2014-02-19 6 views
0

Чтение стандартной библиотеки Python. Попытка понять класс.Python - classmethod()

class C: 
    @classmethod 
    def f(x,y): 
     print('words') 

Когда я типа:

print(classmethod(C)) 

возвращает:

<classmethod object at 0x00FAD930> 

Как бы увидеть, что возвращает Метод класса вместо генератора Метод класса?

+0

Вы не имеете генератор Метод класса. У вас есть объект дескриптора класса. –

+0

Вы пытались: 'C.f (1,2)'? – Bakuriu

+0

Это Python 3. – Phoenix

ответ

3

Вы производите объект classmethod дескриптора:

print(classmethod(C)) 

возвращает класс C обернутый в новом classmethod объекта. Это не генератор, это то, что Python фактически хранит в вашем классе, когда вы украшаете его с помощью этого метода.

Помните, что строка @decorator_expression над функцией или классом является просто синтаксическим сахаром для вызова дополнительной функции, заменяющей этот объект; @classmethod выше def f(...) означает, что Python заменит f на f = classmethod(f).

Вы можете видеть объект того же типа, если смотреть на значение C.__dict__['f']; это тот же тип объекта:

>>> class C: 
...  @classmethod 
...  def f(x,y): 
...   print('words') 
... 
>>> C.__dict__['f'] 
<classmethod object at 0x107d00810> 
>>> C.__dict__['f'].__get__(None, C) 
<bound method type.f of <class '__main__.C'>> 
>>> C.f 
<bound method type.f of <class '__main__.C'>> 

Это __get__ метод на объект дескриптора, который вызывается, когда вы пытаетесь получить доступ к атрибуту C.f.

Функции сами по себе являются дескрипторами; a classmethod обходит метод функции .__get__, чтобы обеспечить привязку к классу вместо обычного привязки к экземпляру.

См. descriptor HOWTO, чтобы понять, что такое дескриптор, и как работает объект classmethod.

Чтобы видеть то, что сам метод возвращает, просто вызовите его на классе или на экземпляре:

>>> class C: 
...  @classmethod 
...  def f(*args, **kw): 
...   return args, kw 
...  def regular(*args, **kw): 
...   return args, kw 
... 
>>> C.f() 
((<class '__main__.C'>,), {}) 
>>> C().f() 
((<class '__main__.C'>,), {}) 
>>> C.regular() 
((), {}) 
>>> C().regular() 
((<__main__.C object at 0x1085b0790>,), {}) 

Вместо обычного объекта self например, метод вместо передается ссылка на класс. Для вызова C.f() (непосредственно в классе) и C().f() (на примере C) первым аргументом f() является C.

Сравните это с методом C.regular(); это обычный метод и при вызове непосредственно с классом с C.regular() аргументы не были переданы, когда вызывается экземпляр с C().regular() первым аргументом, экземпляр был передан. Это то, что вы обычно используете в методе self подпись.

Для методов класса первый аргумент обычно называется cls при объявлении вашего метода.

0

Изменить на:

class C: 
    @classmethod 
    def f(cls, x, y): 
     return 'words' 

В отличие от традиционных методов класса, где первый аргумент является self ссылкой, метод класса получает class в качестве неявного первого аргумента, так же, как метод экземпляра получает экземпляр.

Кроме того, вам необходимо вернуть значение для его печати.

2

Если вы хотите, чтобы вызвать classmethodf вы создали на C, вы должны сделать:

C.f(...) 

classmethod функция декоратор, он будет обернуть все, что вы передаете ему и вернуть classmethod object:

>>> classmethod(1) 
<classmethod object at 0x02FA6370> 

Обратите внимание, что первым к classmethod является сам класс, названный cls по соглашению:

class C: 
    @classmethod 
    def f(cls, x, y): 
     print("words") 

Это дает:

>>> C.f(1, 2) 
words 

return В качестве альтернативы значение и print его вне функции:

class C: 
    @classmethod 
    def f(cls, x, y): 
     return "words" 

>>> print(C.f(1, 2)) 
words 
0

classmethod полезно при совместном использовании значения во всех различных объектов создается.

class Classtest: 
    a =10 
    @classmethod 
    def hi(cls, x): 
     cls.a= cls.a+x 
     print cls.a 

h = Classtest() 
h.hi(10) 

b = Classtest() 
b.hi(30) 

c = Classtest() 
c.hi(40) 

>>> ================================ RESTART  ================================ 
>>> 
20 
50 
90 

Здесь значение переменной а является общим для всех различных объектов, которые создаются и не ограничивается только к одному экземпляру

Смежные вопросы