Python中的@staticmethod有什么意义?

我已经开发了这个简短的测试/示例代码,以更好地理解静态方法在Python中的工作方式。

class TestClass:
    def __init__(self, size):
        self.size = size

    def instance(self):
        print("regular instance method - with 'self'")

    @staticmethod
    def static():
        print("static instance method - with @staticmethod")

    def static_class():
        print("static class method")


a = TestClass(1000)

a.instance()
a.static()
TestClass.static_class()

此代码正常工作,它不会返回任何错误。 我的问题是:

  • 我是否正确理解“自我”可以理解为“这种方法将从实例中调用”之类的东西?

  • 再次,@staticmethod背后的逻辑是什么 - 它是否创建可以从实例调用的静态方法? 这不是什么静态方法?

  • 为什么第二种方法比第三种方法更受青睐? (我认为自从装饰器存在以后,就有了一点意义。)第三种选择似乎更简单,更直接。


  • 这是一篇关于静态方法的文章。 综上所述:

  • 实例方法:要求实例作为第一个参数
  • 类方法:要求类作为第一个参数
  • 静态方法:既不要求作为第一个参数
  • 关于你的问题:

  • 是。 虽然变量名称self是一个约定,但它与该实例有关。
  • 可以使用静态方法在相同的类下对相似的实用程序方法进行分组。
  • 对于类中的方法,您需要将self添加为第一个参数或使用@staticmethod装饰它的方法。 没有参数的“非装饰方法”会引发错误。
  • 当用参数调用这些函数时,看看它们是如何工作的可能会更清楚。 一个修改的例子:

    class TestClass:
    
        weight = 200                             # class attr 
    
        def __init__(self, size):
            self.size = size                     # instance attr
    
        def instance_mthd(self, val):
            print("Instance method, with 'self':", self.size*val)
    
        @classmethod
        def class_mthd(cls, val):
            print("Class method, with `cls`:", cls.weight*val)
    
        @staticmethod
        def static_mthd(val):
            print("Static method, with neither args:", val)
    
    a = TestClass(1000)
    
    a.instance_mthd(2)
    # Instance method, with 'self': 2000
    
    TestClass.class_mthd(2)
    # Class method, with `cls`: 400
    
    a.static_mthd(2)
    # Static method, with neither args: 2
    

    总的来说,你可以从访问角度考虑每种方法:

  • 如果您需要访问实例或实例组件(例如实例属性),那么在传递self作为第一个参数时使用实例方法。
  • 同样,如果您需要访问某个类,请使用类方法。
  • 如果既不访问实例也不访问类是重要的,您可以使用静态方法。
  • 注意在上面的例子中,每个方法类型都传递了相同的参数,但是通过selfcls分别访问实例和类属性是不同的。

    请注意,有一种方法可以通过使用self.__class__来访问实例方法中的类组件,从而避免需要类方法:

        ...
    
        def instance_mthd2(self, val):
            print("Instance method, with class access via `self`:", self.__class__.weight*val)
        ...
    
    a.instance_mthd2(2)
    # Instance method, with class access via `self`: 400
    

    REF:我建议观看Raymond Hettinger谈论Python的类开发工具包,这个工具包通过例子清楚地阐明了每种方法的目的。


    方法作用于它们被调用的实例。 该实例作为第一个参数传递,通常称为self

    类方法是相似的,但对整体类对象而不是其中一个实例起作用。 它们作为构造函数和工厂函数很方便,或者用于配置设置以及一次性影响类或其所有实例的其他情况,而不是单个实例。

    第三种选择,静态方法,是奇怪的人。 他们不通过实例或班级。 它们适用于程序类结构中的嵌套效用函数,以用于组织目的,但是以一种清楚地表明您(代码审阅者,“linting”和程序检查工具等)表明您有意不依赖于实例或类的方式值。 这样,你就不会得到关于那个未使用的self “变量声明但从未使用过”的警告。

    从调用者的角度来看,静态方法看起来像其他任何方法调用。 如果你没有@staticmethod可用,你可以使用一个普通的实例或类方法(尽管存在过量的“变量未使用!!”linter警告)的风险。 因此与类方法不同,静态方法是Python的完全可选部分。 他们没有添加任何功能的语言; 相反,他们提供了一种让开发者的意图更清晰的方法。


    以下是你的问题的答案:

    问题1:

    我是否正确理解“自我”可以理解为“这种方法将从实例中调用”之类的东西?

    不,这不完全是Trueself意味着函数的第一个参数应该是类的实例。 例如:

    def my_class_function(self)
    

    可以称为:

    self.my_class_function()
    OR,
    my_class_function(self)
    

    另外,使用self作为对象的引用并不是必须的。 你可以使用任何东西(只要它是有效的变量),但使用self是随处可见的标准。

    问题2:

    再次,@staticmethod背后的逻辑是什么 - 它是否创建可以从实例调用的静态方法? 这不是什么静态方法?

    @staticmethod变量与函数一起使用,你不需要在函数中引用类的对象,也就是说,你不需要使用self来访问任何类的属性或函数。

    问题3:

    为什么第二种方法比第三种方法更受青睐? (我认为自从装饰器存在以后,就有了一点意义。)第三种选择似乎更简单,更直接。

    使用第二种方法(即使用@staticmetod ,与第三种方法(不使用装饰器)不同,可以使用类的对象从类外部调用函数,因为函数的范围在类中。

    链接地址: http://www.djcxy.com/p/54147.html

    上一篇: What's the point of @staticmethod in Python?

    下一篇: Why use staticmethod instead of no decorator at all