Python文档中@classmethod的参数的作用是什么?

时间:2018-06-25 17:42:05

标签: python python-3.x

我正在尝试了解装饰器,目前正在阅读the documentation

import types

class SelfDocumenting( object ):
    @classmethod
    def getMethods( aClass ):
        return [ (n,v.__doc__) for n,v in aClass.__dict__.items()
                 if type(v) == types.FunctionType ]
    def help( self ):
        """Part of the self-documenting framework"""
        print self.getMethods()

class SomeClass( SelfDocumenting ):
    attr= "Some class Value"
    def __init__( self ):
        """Create a new Instance"""
        self.instVar= "some instance value"
    def __str__( self ):
        """Display an instance"""
        return "%s %s" % ( self.attr, self.instVar )

我不明白为什么getMethods会得到一个称为aClass的参数,但是在定义SomeClass并稍后调用它时(请参见下文),它可以找出在getMethods方法中用aClass替换的内容:

>>> ac= SomeClass()
>>> ac.help()
[('__str__', 'Display an instance'), ('__init__', 'Create a new Instance')]

更新: 多亏了答案,但为将来参考,我的困惑源于一个事实,即self是保留字,而aClass不是。所以我不确定该如何处理。我认为@abarnert的评论澄清了文档中的代码并不真正具有代表性。

3 个答案:

答案 0 :(得分:3)

这与classmethod这个事实并没有真正的关系。

出于相同的原因,我们在调用“普通”实例方法时不需要传递实例,因此实例(在本例中为类)是隐式传递的。

class Foo:
    def instance_method(self):
        print('No need to pass {} explictly'.format(self))

    @classmethod
    def class_method(cls):
        print('No need to pass {} explictly'.format(cls))

obj = Foo()

obj.instance_method()
# No need to pass <__main__.Foo object at 0x0000000002A38DD8> explictly

obj.class_method()
# No need to pass <class '__main__.Foo'> explictly

答案 1 :(得分:3)

Straight from the classmethod documentation

  

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

这与派生类相同:

  

如果派生类调用类方法,则派生类对象作为隐式第一个参数传递。

答案 2 :(得分:1)

根据说明,如以下提到的链接  https://docs.python.org/2/library/functions.html#classmethod

类方法是绑定到类而不是对象的方法。它不需要像静态方法一样创建类实例。

静态方法和类方法之间的区别是:

  • 静态方法对类一无所知,只处理 参数Class方法与该类一起使用,因为其参数为 总是班级本身。

class方法可以同时由类及其对象调用。 来源: https://www.programiz.com/python-programming/methods/built-in/classmethod

您可以在__ builtin __.py

中查看@ClassMethod的描述。
class classmethod(object):
    """
    classmethod(function) -> method

    Convert a function to be a class method.

    A class method receives the class as implicit first argument,
    just like an instance method receives the instance.
    To declare a class method, use this idiom:

      class C:
          @classmethod
          def f(cls, arg1, arg2, ...):
              ...

    It can be called either on the class (e.g. C.f()) or on an instance
    (e.g. C().f()).  The instance is ignored except for its class.
    If a class method is called for a derived class, the derived class
    object is passed as the implied first argument.

    Class methods are different than C++ or Java static methods.
    If you want those, see the staticmethod builtin.
    """
    def __getattribute__(self, name): # real signature unknown; restored from __doc__
        """ x.__getattribute__('name') <==> x.name """
        pass

    def __get__(self, obj, type=None): # real signature unknown; restored from __doc__
        """ descr.__get__(obj[, type]) -> value """
        pass

    def __init__(self, function): # real signature unknown; restored from __doc__
        pass

    @staticmethod # known case of __new__
    def __new__(S, *more): # real signature unknown; restored from __doc__
        """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
        pass

    __func__ = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default