'int'对象不可调用

时间:2010-04-23 22:29:36

标签: python

我正在尝试定义一个简单的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

代码如下:

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()

我认为这是因为我有numerator(self)numerator(self, n)但现在我知道Python没有方法重载(函数重载)所以我重命名为get_numerator但这不是问题。

它可能是什么?

3 个答案:

答案 0 :(得分:19)

您使用numerator作为方法名称(def numerator(...))和成员变量名称(self.numerator = n)。使用set_numeratorset_denominator作为方法名称,它将起作用。

顺便说一句,Python 2.6有一个内置的fraction class

答案 1 :(得分:9)

您不能重载名称numerator以引用成员变量和方法。当您设置self.numerator = n时,您将覆盖对方法的引用,因此当您调用f.numerator(2)时,它会尝试对成员变量执行方法调用,这是int ,Python并不允许你这样做。这就像说x = 2; x(4) - 它没有任何意义。

您应该将setter方法重命名为set_numeratorset_denominator,以消除此命名冲突。

答案 2 :(得分:7)

  • 您正在使用numerator作为方法名称和实例属性的名称。由于方法存储在类中,因此当您查找该属性时,您将获得数字,而不是方法。 (Python会在查看类之前在实例上查找属性。)

    也就是说,在您说f.numerator(2)的行上,它会查找f.numerator并发现它是0,然后尝试调用0,显然不应该工作。

  • 如果您对此代码有任何实际意义,可以使用stdlib fractions模块:http://docs.python.org/library/fractions.html

    • 这是Python 2.6中的新功能。如果我需要表示分数但使用的是早期版本的Python,我可能会使用sympyRational类型。
  • denominator更实用的默认值可能是1。 (那样Fraction(5)将是五,而不是一些未定义的操作倾向于无穷大。)

  • 而不是prints方法,更典型的是定义__str__并打印您的对象。

  • 您的方法只是获取并设置属性。在Python中,我们通常不使用getter和setter - 我们只是让用户设置我们的属性。

    • 您来自Java背景,其中一个基本规则始终是使用getter和setter方法,而不是让用户访问属性。此规则的基本原理是,如果在将来某个日期,您需要做的不仅仅是获取和设置(您需要处理数据),则需要更改API。因为在Python中我们有属性,所以我们不需要在该实例中进行API更改,因此我们可以安全地避免使用setplate和setter以及getter。
  • 继承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