【问题标题】:Is it neccessary to decorate a classmethod at it's definition?是否有必要在定义处装饰类方法?
【发布时间】:2021-11-20 13:09:09
【问题描述】:

Python 的 OOP 概念中有三种方法——实例方法、类方法和静态方法。

class MyClass:
    def instancemethod(self):
        return 'instance method called'

    @classmethod
    def classmethod(cls):
        return 'class method called'

    @staticmethod
    def staticmethod():
        return 'static method called'

很明显了解所有三种方法。现在我在一个类中创建一个新方法:

class Test():
    def ppr():
        print('what method is ppr?')

它不是实例方法。

inst = Test()
inst.ppr()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ppr() takes 0 positional arguments but 1 was given

所以它是一个类方法?

Test.ppr()
what method is ppr?

没有@classmethod 关键字来装饰ppr 函数。

【问题讨论】:

    标签: python methods decorator class-method


    【解决方案1】:

    让我们测试一下:

    class MyClass:
        def instancemethod(self):
            return 'instance method called'
    
        @classmethod
        def classmethod(cls):
            return 'class method called'
    
        @staticmethod
        def staticmethod():
            return 'static method called'
    
    class Test():
        def ppr():
            print('what method is ppr?')
    
    print(type(MyClass.instancemethod)) # -> function
    print(type(MyClass.classmethod))    # -> method
    print(type(MyClass.staticmethod))   # -> function 
    
    print(type(Test.ppr))               # -> function 
    

    Test.ppr 作为一个函数返回,它可以在不创建实例的情况下运行——它是一个@staticmethod

    如果它是 @classmethod,它会以类型 method 的形式返回。

    q.e.d.


    我的 IDE 向我显示警告:“方法 ppr 没有参数。”这暗示您可能应该添加selfcls 以及相应的@classmethod

    回答您的问题 - 似乎不需要(目前) - 但谨慎的做法是声明它们@staticmethod 以明确您的意图。

    【讨论】:

    • 这是一个很好的答案,但 IMO 这个问题在 python 引用方法的方式上并没有真正的意义。例如,type(MyClass.instancemethod) 将是 function,但 type(MyClass().instancemethod) 将是 method。就像type(Test.ppr) 是一个functiontype(Test().ppr) 是一个方法。
    • @Axe 公平评论。但我正在比较类的类型结果而不是其实例的类型结果 - 并从正确声明的类的输出中得出结论,而不是错误地完成。我的方法可能只是部分正确 - 但我无法在文档中找到与这方面有关的任何内容,所以我自己又去搞定它;)
    • @PatickArtner 这很公平。我更多地只是批评这个问题。 :D
    【解决方案2】:

    对于普通的静态方法,可以通过类或实例调用。

    #called by class 
    MyClass.staticmethod()
    'static method called'
    #called by instance
    MyClass().staticmethod()
    'static method called'
    

    Test 类中的方法是非标准的static method

    Test.ppr()
    what method is ppr?
    Test().ppr()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: ppr() takes 0 positional arguments but 1 was given
    

    【讨论】:

      猜你喜欢
      • 2011-04-13
      • 2021-04-24
      • 2015-12-06
      • 2014-01-14
      • 2018-10-03
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2020-01-11
      相关资源
      最近更新 更多