>>> class S(object):
... def __init__(self):
... self.x = 1
... def x(self):
... return self.x
...
>>> s = S()
>>> s.x
1
>>> s.x()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
Why, in this example, is s.x a method, but also an integer? It seems to me that self.x = 1 should replace the def x(self): declaration of the attribute x during instantiation. Why is it that I can get and call, resulting in an integer and a method, respectively, the same attribute? My guess is that the variable look-up pattern in new-style classes is duck typed, so as to return the most relevant result to the caller. I would love to hear the whole story.
It looks like you’re having a misunderstanding of the error you’re seeing. When your
sobject is instantiated, its constructor replaces the methodxby an integer, so in thesobject,xis an integer, not a function. Trying to call it as a method results in an exception being thrown.Python is duck-typed in the sense that method calls are resolved at runtime – the compiler has no problem with
s.x()becausexmight have been created as a method dynamically. However, when the interpreter actually callsxas a method, it noticesxis an integer and can’t be called, hence theTypeError.