What's the point of @staticmethod in Python?
为了更好地理解静态方法在Python中的工作方式,我开发了这个简短的测试/示例代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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() |
此代码工作正常,不会返回任何错误。我的问题是:
我是否正确地理解"self"可以理解为"这个方法将从实例中调用"?
再说一遍,@staticmethod背后的逻辑是什么-是创建可以从实例调用的静态方法吗?这不正是静态方法的意义吗?
为什么第二种方法比第三种方法更受欢迎?(我假设由于存在装饰器,所以有一点需要说明。)第三个选项似乎更简单、更直接。
这是一篇关于静态方法的文章。综上所述:
- 实例方法:需要实例作为第一个参数
- 类方法:要求类作为第一个参数
- 静态方法:不需要作为第一个参数
关于你的问题:
当用参数调用时,可以更清楚地看到这些是如何工作的。修改后的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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 作为第一个参数传递。 - 同样,如果需要访问类,请使用类方法。
- 如果对实例和类的访问都不重要,则可以使用静态方法。
注意,在上面的示例中,每个方法类型都传递相同的参数,但是通过
注意,有一种方法可以使用
1 2 3 4 5 6 7 8 | ... 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 |
参考:我建议看RaymondHettinger的Talkpython的类开发工具包,它用示例清楚地阐明了每种方法类型的用途。
方法作用于调用它们的实例。实例作为第一个参数传递,通常称为
类方法类似,但作用于整个类对象,而不是其中一个实例。它们作为构造函数和工厂函数,或者配置设置和其他同时影响类或其所有实例的情况,而不是单个实例,都非常方便。
第三个选项,静态方法,是奇数。它们既不传递实例也不传递类。它们有利于在程序的类结构中为组织目的嵌套实用程序功能,但在某种方式上(对代码审阅者、"linting"和程序检查工具等)明确表示您有意不依赖实例或类值。这样,就不会得到关于未使用的
从调用者的角度来看,静态方法与任何其他方法调用类似。如果您没有可用的
以下是您问题的答案:
问题1:
Do I understand correctly that"self" can be understood as something like"this method will be called from an instance"?
不,那不完全是
1 | def my_class_function(self) |
可以称为:
1 2 3 | self.my_class_function() OR, my_class_function(self) |
此外,不必使用
问题2:
Then again, what's the logic behind @staticmethod - is it to create static methods which can be called from an instance? Isn't that exactly not what static methods are about?
问题3:
Why would the second approach be favored over the third one? (I assume that since the decorator exists, there is a point to this.) The 3rd option seems to be the simpler and more straightforward.
使用第二种方法,即使用