【问题标题】:Using class methods without `@classmethod`使用没有 `@classmethod` 的类方法
【发布时间】:2017-12-24 10:53:12
【问题描述】:

考虑:

class cla(object):
    def __init__(self,val):
        self.val = val

    def met(self):
        return self.val + 1

然后cla.met(cla(1)) 返回2

由于我不需要cla 类的实例来使用方法met,这是否意味着它是一个类方法,即使我没有使用装饰器@classmethod

我阅读了https://julien.danjou.info/blog/2013/guide-python-static-class-abstract-methods 以更好地理解类方法是什么,但不知何故,在我看来@classmethod 的预期含义已经存在于类的正常方法中——实际上我对那里的例子,因为他们甚至不编译。

【问题讨论】:

标签: python class methods semantics


【解决方案1】:

cla.met(cla(1)) 只是表达cla(1).met() 的一种复杂方式。答案是否定的:met 不是类方法。

类方法是

class cla():
   @classmethod
   def met(cls, val):
       return val + 1

这将被称为cla.met(1)

希望这可以澄清差异。

【讨论】:

    【解决方案2】:

    如果你有 cla 类的实例:

    instance = cla(1)
    

    那么下面两个调用是等价的:

    instance.met()
    cla.met(instance)
    

    请注意,第二个仅在您将带有val 属性的参数传递给它时才有效(因此您实际上确实需要类似于cla 类的实例),而第一个隐含调用类上定义的函数并将自身作为参数传递。见docs on method objects。以下几行有助于阐明方法对象的内部结构:

    >>> f = cla.met
    >>> m = instance.met
    >>> type(f)
    <class 'function'>
    >>> type(m)
    <class 'method'>
    >>> m.__self__ == instance
    True
    >>> m.__func__ == f
    True
    

    所以

    >>> f(instance)
    2
    

    相同
    >>> m.__func__(m.__self__)
    2
    

    这就是instance.met()(又名m()又名m.__call__())在幕后所做的。

    【讨论】:

      猜你喜欢
      • 2022-11-18
      • 2021-07-02
      • 2018-02-05
      • 2012-12-15
      • 2016-03-17
      • 2013-02-23
      • 1970-01-01
      • 2017-04-17
      • 1970-01-01
      相关资源
      最近更新 更多