我正在尝试定义一个简单的Fraction类
我收到这个错误:
python fraction.py
Traceback (most recent call last):
File "fraction.py", line 20, in <module>
f.numerator(2)
TypeError: 'int' object is not callable
Run Code Online (Sandbox Code Playgroud)
代码如下:
class Fraction(object):
def __init__( self, n=0, d=0 ):
self.numerator = n
self.denominator = d
def get_numerator(self):
return self.numerator
def get_denominator(self):
return self.denominator
def numerator(self, n):
self.numerator = n
def denominator( self, d ):
self.denominator = d
def prints( self ):
print "%d/%d" %(self.numerator, self.denominator)
if __name__ == "__main__":
f = Fraction()
f.numerator(2)
f.denominator(5)
f.prints()
Run Code Online (Sandbox Code Playgroud)
我认为这是因为我有numerator(self),numerator(self, n)但现在我知道Python没有方法重载(函数重载)所以我重命名get_numerator但不是问题.
会是什么呢?
您不能重载名称numerator以引用成员变量和方法.当你设置时self.numerator = n,你将覆盖对方法的引用,所以当你调用时f.numerator(2),它试图对成员变量进行方法调用,这是一个int,并且Python不允许你这样做.这就像说x = 2; x(4)- 它没有任何意义.
您应该将setter方法重命名为set_numerator并set_denominator删除此命名冲突.
您将numerator同时用作方法名称和实例属性的名称.由于方法存储在类中,因此当您查找该属性时,您将获得数字,而不是方法.(Python会在查看类之前在实例上查找属性.)
也就是说,在你说的那一行f.numerator(2),它查找f.numerator并发现它是0,然后试图调用它0,这显然不应该工作.
如果您对此代码有任何实际用途,可以使用stdlib fractions模块:http://docs.python.org/library/fractions.html
Rational类型.对于一个更实际的默认值denominator可能1.(这种方式Fraction(5)将是五个,而不是一些未定义的操作倾向于无穷大.)
而不是一种prints方法,更典型的是定义__str__和打印您的对象.
您的方法只是获取和设置属性.在Python中,我们通常不使用getter和setter - 我们只是让用户设置我们的属性.
继承numbers.Rational(Python 2.6及更高版本)会让你的类自动完成预期的数字.你将不得不实现它所需要的一切,但它会自动完成更多的工作.查看http://docs.python.org/library/numbers.html了解更多信息.
扰流警报:
class Fraction(object):
"""Don't forget the docstring....."""
def __init__(self, numerator=0, denominator=1):
self.numerator = numerator
self.denominator = denominator
def __str__(self):
return "%d / %d" % (self.numerator, self.denominator)
# I probably want to implement a lot of arithmetic and stuff!
if __name__ == "__main__":
f = Fraction(2, 5)
# If I wanted to change the numerator or denominator at this point,
# I'd just do `f.numerator = 4` or whatever.
print f
Run Code Online (Sandbox Code Playgroud)