23

我以为我开始掌握编程的“Python 方式”。类的方法接受 self 作为第一个参数,以引用该方法在其上下文中被调用的类的实例。@classmethod 装饰器指的是一个方法,其功能与该类相关联,但不引用具体实例。

那么,如果该方法是在没有实例引用的情况下被调用的,@classmethod 的第一个参数(规范的“self”)指的是什么?

4

4 回答 4

38

类本身

类方法接收类作为隐式第一个参数,就像实例方法接收实例一样。

class C:
    @classmethod
    def f(cls):
        print(cls.__name__, type(cls))

>>> C.f()
C <class 'type'>

顺便说一句,这是cls规范的

于 2009-02-10T17:22:58.210 回答
16

类方法的第一个参数按约定命名cls,指的是调用它的方法所在的类对象。

>>> class A(object):
...     @classmethod
...     def m(cls):
...         print cls is A
...         print issubclass(cls, A)

>>> class B(A): pass
>>> a = A()
>>> a.m()
True
True
>>> b = B()
>>> b.m()
False 
True
于 2009-02-10T17:28:00.040 回答
0

类对象作为第一个参数传递。例如:

class Foo(object):
    @classmethod
    def bar(self):
        return self()

将返回 Foo 类的实例。

编辑

请注意,最后一行是 self() 而不是 self。self 将返回类本身,而 self() 返回一个实例。

于 2009-02-10T17:23:17.647 回答
0

Django 在这里用一个类方法做了一些奇怪的事情:

class BaseFormSet(StrAndUnicode):
    """
    A collection of instances of the same Form class.
    """
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList):
        ...
        self.prefix = prefix or self.get_default_prefix()
        ...

即使 get_default_prefix 以这种方式声明(在同一类中):

    @classmethod
    def get_default_prefix(cls):
        return 'form'
于 2013-03-13T18:22:16.403 回答