我已经开发了这个简短的测试/示例代码,以便更好地理解静态方法在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()
此代码正常运行,不会返回任何错误。我的问题是:
我是否正确理解" self"可以理解为"这个方法将从一个实例调用"?
那么,@ staticmethod背后的逻辑是什么?是否可以创建可以从实例调用的静态方法?是不是不是什么静态方法?
为什么第二种方法比第三种方法更受青睐? (我假设因为装饰器存在,所以有一点。)第三种选择似乎更简单,更直接。
答案 0 :(得分:4)
以下是static methods上的帖子。总结:
关于你的问题:
soundio-sys
是约定,但它与实例有关。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
和self
而不同。
注意,有一种方法可以使用cls
从实例方法访问类组件,从而避免了对类方法的需求:
self.__class__
REF:我建议观看Raymond Hettinger的talk Python的类开发工具包,它通过示例清楚地阐明了每种方法类型的用途。
答案 1 :(得分:1)
以下是您问题的答案:
问题1:
我是否正确理解“自我”可以理解为“此方法将从实例中调用”?
没有。这不完全是True
。 self
表示函数的第一个参数应该是类的实例。例如:
def my_class_function(self)
可以称为:
self.my_class_function()
OR,
my_class_function(self)
此外,使用self
作为类对象的引用并不是必需的。你可以使用任何东西(只要它是有效变量),但使用self
是随处可见的标准。
问题2:
然后,@ staticmethod背后的逻辑是什么 - 创建可以从实例调用的静态方法?那不就是静态方法到底是什么意思吗?
@staticmethod
变量与函数一起使用,在这些函数中,您不需要对函数中的类对象进行任何引用,即您没有使用self
来访问任何类的属性或函数
问题3:
为什么第二种方法比第三种方法更受青睐? (我假设因为装饰器存在,所以有一点。)第三种选择似乎更简单,更直接。
使用第二种方法,即使用@staticmetod
,您可以使用类的对象从类外部调用函数,这与第三种方法不同(不使用装饰器),因为函数的范围在类中。
答案 2 :(得分:1)
方法对它们被调用的实例起作用。该实例作为第一个参数传递,通常称为self
。
类方法类似,但是对整个类对象而不是其中一个实例起作用。它们可以作为构造函数和工厂函数,或者用于配置设置以及同时影响类或其所有实例的其他情况,而不是单个实例。
第三个选项,静态方法,是奇怪的人。它们不传递实例或类。它们适用于在程序的类结构中嵌套实用程序功能以用于组织目的,但是以明确的方式(对代码审阅者,“linting”和程序检查工具等)表明您有意不依赖于实例或类值。这样,你就不会得到关于那个未使用的self
的“变量声明但从未使用过”的警告。
从调用者的角度来看,静态方法看起来像任何其他方法调用。如果你没有@staticmethod
可用,你可以使用普通的实例或类方法(尽管存在过多的风险“未使用的变量!!”linter warnings)。因此,与类方法不同,静态方法是Python的完全可选部分。他们没有为语言添加任何功能;相反,它们提供了一种方法,使开发人员的意图更加清晰。