Python编程帮助
我正在处理一个Python文件:
class Range:
""" An object that has a non-negative start position and a non-negative length"""
def __init__(self, start, end):
"""
Function: generates a new Range
Returns : a new range
Args : start - start position
end - end position
Start and End must be non-negative """
self.start = 0
self.end = 10000
self.setStart(start)
self.setEnd(end)
def getStart(self):
"""
Function: get the start of the range
Returns : a number or None
Args : start - the int index of the first nucleotide of this range """
return self.start
def setStart(self, s):
"""
Function: set the start of the range
Returns : None
Args : start - a non-negative int or None """
if type(s) !=int:
raise TypeError ("Cannot set Start as this is not an interger")
elif s < 0:
raise ValueError ("Cannot set Start as this is not a non-negative int")
elif s > self.end:
raise ValueError("start cannot be larger than end")
else:
self.start = s
def getEnd(self):
"""
Function: get the end of the range
Returns : a number
Args :
"""
return self.end
def setEnd(self, e):
"""
Function: set the end of the range
Returns : None
Args : end - a non-negative int or None
"""
if type(e) !=int:
raise TypeError ("Cannot set End as this is not an interger")
elif e < 0:
raise ValueError ("Cannot set End as this is not a non-negative int")
elif e < self.start:
raise ValueError ("end has to be larger than start")
else:
self.end = e
def getLength(self):
"""
Function: get the length of the range
Returns : an int. the length of this range
Args:
"""
return self.end - self.start
def overlaps(self, r):
"""
Function: to test if two nucleotide is overlap
Returns : True or False
Args : other - a Range object
"""
start1 = self.getStart()
end1 = start1 + self.getLength()
start2 = r.getStart()
end2 = start2 + self.getLength()
max_start = max(start1,start2)
min_end = min(end1,end2)
return min_end - max_start > 0
if self.getStart() == r.getStart():
return True
else:
return False
class DNAFeature(Range):
"""Represents a feature on a DNA sequence """
def __init__(self, seq_name = None, strand = 0, **kwargs):
"""
Function : represents a rane
Returns :
Args : strand, seqname, **kwargs
"""
Range.__init__(self, **kwargs)
self.setStrand(strand)
self.setSeqName(seq_name)
def getSeqName(self):
"""
Function: Gets object's Sequence Name
Returns : seqname - string
Args :
"""
return self.seq_name
def setSeqName(self, seq_name):
"""
Function: Sets object's Sequence Name
Returns : None
Args : seqname - mRNA accession name
"""
self.seq_name = seq_name
def getStrand(self):
"""
Function: Retrieve the strand affiliation of this
Returns : 1, 0, -1 - strand
Args :
"""
return self.strand
def setStrand(self, strand):
"""
Function: sets which strand the object is on
Returns : None
Args : strand - one of ['+',1,'F','-',-1,'R']
"""
StrandValues = [1, 0, -1]
if not strand in StrandValues:
raise ValueError("only able to setStrand if the values is 1, 0, or -1")
else:
self.strand = strand
def overlaps(self, other, ignore_strand = True):
"""
Function: tests if this overlaps other
Returns : true if the ranges have same Seqname and overlap, false if not
Args : other - another Range object
"""
if ignore_strand == True and self.getSeqName() == other.getSeqName():
return Range.overlaps(self,other)
else:
return False
class GeneModel(DNAFeature):
def __init__(self, transl_start=None, transl_stop=None, display_id = None, **kwargs):
"""
Function : contains a group of DNAFeature objects representing exons
Returns :
Args : **kwargs
"""
DNAFeature.__init__(self, **kwargs)
self.setTranslStart(transl_start)
self.setTranslStop(transl_stop)
self.setDisplayId(display_id)
self.exons = [ ]
def getFeats(self):
"""
Function: gets object's feats list
Returns : list of feature keys
Args : feature_type - the type of strand the object holds
"""
self.exons.sort(cmp=self.start)
return self.exons
def addFeat(self, feat):
"""
Function: adds SeqFeature to feats keys
Returns : None
Args : feat - a single SeqFeature object
"""
if type(feat) == DNAFeature:
self.exons.append(feat)
else:
raise TypeError("Cannot add feature as it is not a type of DNAFeature")
def setTranslStart(self, transl_start):
"""
Function : accepts an non-negative int, sets the start position of the initiating ATG
Returns :
Args : transl_start
"""
if transl_start == None:
self.transl_start = None
return
elif type(transl_start) !=int:
raise TypeError("TranslStart cannot be set since it is not a type of int")
elif transl_start < 0:
raise ValueError("TranslStart cannot be set to a negative int")
else:
self.translStart = transl_start
def getTranslStart(self):
"""
Function: the start position of initiating ATG codon
Return : an int.
Args :
"""
return self.transl_start
def setTranslStop(self, transl_stop):
"""
Function: set the end position of initiating ATG codon
Return : None
Args : a positive int
"""
if transl_stop == None:
self.transl_stop = None
return
elif type(transl_stop) !=int:
raise TypeError("TranslStop cannot be set since it is not a type of int")
elif transl_stop < 0:
raise ValueError("TranslStop cannot be set to a negative int")
else:
self.translStop = transl_stop
def getTranslStop(self):
"""
Function: the end position of initiating ATG codon
Return : an int.
Args :
"""
return self.transl_stop
def setDisplayId(self, display_id):
"""
Function: set the display id
Returns : None
Args : display_id - a string, a preferred name for this
"""
if type(display_id) !=str:
raise TypeError("Cannot set displayId as it is not a type string")
else:
self.display_id = display_id
def getDisplayId(self):
"""
Function: get the display id
Returns : display_id - a string, a preferred name for this, e.g AT1G10555.1
Args :
"""
return self.display_id
然后,我从教授那里拿到了一些代码来测试我的文件:
class TestGeneModelConstructor(unittest.TestCase):
def testGeneModelConstructor(self):
"""GeneModel constructor supports named arguments display_id,transl_start,transl_stop"""
p1.GeneModel(start=0,end=10,seq_name='something',strand=1,display_id='foobar',
transl_start=0,transl_stop=10)
def testGeneModelConstructorDefaults(self):
"""Default values for display_id, transl_start, transl_stop should be None"""
r = p1.GeneModel()
self.assertEquals(r.getDisplayId(),None)
self.assertEquals(r.getTranslStart(),None)
self.assertEquals(r.getTranslStop(),None)
def testGeneModelConstructorWrongTypeDisplayId(self):
"""Raise a TypeError if display_id is not a string."""
self.assertRaises(TypeError,p1.GeneModel,display_id=0)
def testGeneModelConstructorWrongTypeTranslStart(self):
"""Raise a TypeError if transl_start is not an int."""
self.assertRaises(TypeError,p1.GeneModel,transl_start='0')
def testGeneModelConstructorWrongTypeTranslStop(self):
"""Raise a TypeError if transl_stop is not an int."""
self.assertRaises(TypeError,p1.GeneModel,transl_stop='0')
def testGeneModelConstructorWrongValueTranslStart(self):
"""Raise a ValueError if transl_start is int < 0."""
self.assertRaises(ValueError,p1.GeneModel,transl_start=-1)
def testGeneModelConstructorWrongValueTranslStop(self):
"""Raise a ValueError if transl_stop is int < 0."""
self.assertRaises(ValueError,p1.GeneModel,transl_stop=-1)
我运行了它,但出现了这些错误:
ERROR: Default values for display_id, transl_start, transl_stop should be None
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 117, in testGeneModelConstructorDefaults
r = p1.GeneModel()
TypeError: __init__() takes at least 3 arguments (1 given)
======================================================================
ERROR: Raise a ValueError if transl_start is int < 0.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 136, in testGeneModelConstructorWrongValueTranslStart
self.assertRaises(ValueError,p1.GeneModel,transl_start=-1)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 336, in failUnlessRaises
TypeError: __init__() takes at least 3 non-keyword arguments (2 given)
======================================================================
ERROR: Raise a ValueError if transl_stop is int < 0.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 140, in testGeneModelConstructorWrongValueTranslStop
self.assertRaises(ValueError,p1.GeneModel,transl_stop=-1)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 336, in failUnlessRaises
TypeError: __init__() takes at least 3 non-keyword arguments (1 given)
我不太确定哪里出了问题,我尝试修复了几次,但还是没搞明白我的代码哪里有问题。
好吧,我在DNAFeature里把我的代码改成了这样:
class DNAFeature(Range):
"""Represents a feature on a DNA sequence """
def __init__(self, seq_name = None, strand = 0, **kwargs):
"""
Function : represents a rane
Returns :
Args : strand, seqname, **kwargs
"""
Range.__init__(self, 0,10000, **kwargs)
self.setStrand(strand)
self.setSeqName(seq_name)
然后,又出现了3个错误和1个失败,像这样:
ERROR: DNAFeature on different sequence don't overlap
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 164, in testDiffSequenceOverlaps
r1 = p1.DNAFeature(start=0,end=10,strand=1,seq_name="foo")
File "/Users/trungpham/binf_prog/tpham22/project1/p1.py", line 95, in __init__
Range.__init__(self, 0, 10000, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'start'
======================================================================
ERROR: DNAFeatures on the same strand can overlap if ignore_strand is True.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 185, in testDiffStrandsDontOverlap
r1 = p1.DNAFeature(start=0,end=10,strand=1,seq_name="foo")
File "/Users/trungpham/binf_prog/tpham22/project1/p1.py", line 95, in __init__
Range.__init__(self, 0, 10000, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'start'
======================================================================
ERROR: GeneModel constructor supports named arguments display_id,transl_start,transl_stop
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 113, in testGeneModelConstructor
transl_start=0,transl_stop=10)
File "/Users/trungpham/binf_prog/tpham22/project1/p1.py", line 151, in __init__
DNAFeature.__init__(self, **kwargs)
File "/Users/trungpham/binf_prog/tpham22/project1/p1.py", line 95, in __init__
Range.__init__(self, 0, 10000, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'start'
FAIL: Raise a TypeError if seq_name is not a string.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/trungpham/binf_prog/class/test/testProject1.py", line 98, in testDNAFeatureSeqNameConstructorWrongType
self.assertRaises(TypeError,p1.DNAFeature,seq_name=0)
AssertionError: TypeError not raised
3 个回答
1
看起来这些测试是默认所有参数都是按值传递的。你需要给位置参数设置默认值。
1
Smashery说得对。试试运行这段简化的代码:
class GeneModel(object):
def __init__(self, transl_start=None, transl_stop=None, display_id = None, **kwargs):
pass
def testGeneModelConstructor():
g = GeneModel(start=0,end=10,seq_name='something',strand=1,display_id='foobar', transl_start=0,transl_stop=10)
def testGeneModelConstructorDefaults():
r = GeneModel()
testGeneModelConstructor()
testGeneModelConstructorDefaults()
2
这里有几个问题:
首先:
在你的测试函数 testGeneModelConstructorDefaults 中,你写了注释:“display_id、transl_start 和 transl_stop 的默认值应该是 None”。
你遇到的问题是,你只为三个参数中的一个设置了默认值;而这个测试函数假设你已经为所有三个参数都设置了默认值。要解决这个问题,你需要这样定义构造函数:
def __init__(self, transl_start=None, transl_stop=None, display_id = None, **kwargs)
通过使用关键字参数,它会默认使用 None
。如果你没有明确指定这些关键字参数,Python 就会报错(就像现在这样)。
其次:
你还得考虑你的父类构造函数。Range
这个父类需要两个参数:start 和 end。
def __init__(self, start, end):
但是,当 DNAFeature
的构造函数调用 Range
父类时,并没有传入 begin 或 end:
Range.__init__(self, **kwargs)
我认为 现在的错误就在这里(我觉得之前是在 p1.GeneModel()
的调用那里 - 你两个错误信息中可能有不同的错误行)。
要解决这个问题,也要把 start 和 end 的值变成关键字参数。所以,不要这样写:
def __init__(self, start, end):
而是要这样写:
def __init__(self, start=0, end=10000):
然后你可以删除你 range
构造函数中的以下几行代码:
self.start = 0
self.end = 10000
这样至少可以让你解决这个错误 - 你可能还会发现其他错误。