Методы против функций и других типов вызываемых объектов ...
(Для решения проблемы в комментариях в посте Неизвестного.)
Во-первых, следует отметить, что, помимо пользовательских методов, есть встроенные методы, а встроенный метод, как говорит документ в http://docs.python.org/reference/datamodel.html, «действительно другой маскировка встроенной функции "(которая является оболочкой для функции C).
Что касается пользовательских методов, как цитирует цитата Неизвестного:
Пользовательский объект метода объединяет
класс, экземпляр класса (или None)
и любой вызываемый объект (обычно
пользовательская функция).
Но это не значит, что «все, что определяет __call__
и прикрепляется к объекту, является методом». Метод является вызываемым, но вызываемый не обязательно является методом. Пользовательские методы являются обертками вокруг того, что говорится в цитате.
Надеюсь, этот вывод (из Python 2.5.2, который мне пригодится) покажет различие:
IDLE 1.2.2
>>> class A(object):
x = 7
>>> A # show the class object
<class '__main__.A'>
>>> a = A()
>>> a # show the instance
<__main__.A object at 0x021AFBF0>
>>> def test_func(self):
print self.x
>>> type(test_func) # what type is it?
<type 'function'>
>>> dir(test_func) # what does it have?
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__module__', '__name__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict',
'func_doc', 'func_globals', 'func_name']
>>> # But now let's put test_func on the class...
>>> A.test = test_func
>>> type(A.test) # What type does this show?
<type 'instancemethod'>
>>> dir(A.test) # And what does it have?
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__get__',
'__getattribute__', '__hash__', '__init__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__str__', 'im_class',
'im_func', 'im_self']
>>> # See, we just got a wrapper, and the function is in 'im_func'...
>>> getattr(A.test, 'im_func')
<function test_func at 0x0219F4B0>
>>> # Now to show bound vs. unbound methods...
>>> getattr(a.test, 'im_self') # Accessing it via the instance
<__main__.A object at 0x021AFBF0>
>>> # The instance is itself 'im_self'
>>> a.test()
7
>>> getattr(A.test, 'im_self') # Accessing it via the class returns None...
>>> print getattr(A.test, 'im_self')
None
>>> # It's unbound when accessed that way, so there's no instance in there
>>> # Which is why the following fails...
>>> A.test()
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
A.test()
TypeError: unbound method test_func() must be called with A instance as
first argument (got nothing instead)
>>>
И - редактирование для добавления следующего дополнительного вывода, что тоже актуально ...
>>> class B(object):
pass
>>> b = B()
>>> b.test = test_func # Putting the function on the instance, not class
>>> type(b.test)
<type 'function'>
>>>
Я не буду добавлять больше вывода, но вы также можете сделать класс атрибутом другого класса или экземпляра, и, хотя классы могут вызываться, вы не получите метод. Методы реализованы с использованием дескрипторов, не относящихся к данным, поэтому ищите дескрипторы, если вам нужна дополнительная информация о том, как они работают.