你已经读过这个了吗?
https://en.wikipedia.org/wiki/Method_(computer_programming)
特别是这个?
https://en.wikipedia.org/wiki/Method_(computer_programming)#Static_methods
说明
在 OOP 中,您可以定义 类,然后在 实例化。一个类只不过是一个蓝图:一旦你从一个类实例化对象,你的对象将完全遵循你的类的蓝图。这意味着:如果您在类中定义了一个名为“abc”的字段,您稍后将在您的对象中拥有一个字段“abc”。如果您在您的类中定义了一个方法“foo()”,那么稍后您将在对象上调用一个方法“foo()”。
请注意,这个“在您的对象上”是必不可少的:您总是实例化一个类,然后您可以调用该方法。这是“正常”的方式。
静态方法是不同的。虽然普通方法总是需要有一个实例(然后您可以在其中调用此方法),但静态方法却不。静态方法独立于您的实例存在(这就是它被命名为“静态”的原因)。因此,静态方法与您的类定义本身相关联,因此始终存在,因此只能在您的类本身中调用。它完全独立于所有实例。
这是一个静态方法。
Python 的实现有点……嗯……简单。详细而言,与上述描述存在偏差。但这并没有什么区别:为了与 OOP 概念保持一致,您始终应该使用与上述完全相同的方法。
示例
举个例子:
class FooBar:
def someMethod(self):
print("abc")
这是一个常规(实例)方法。你可以这样使用它:
myObj = FooBar()
myObj.someMethod()
如果你有...
myObjB = FooBar()
myObjB.someMethod()
...您有一个额外的实例,因此在第二个实例上调用 someMethod() 将调用第二个 someMethod() 方法 - 在第二个对象中定义。这是因为您在使用之前实例化对象,因此所有实例都遵循定义的蓝图 FooBar。因此,所有实例都会收到某种someMethod() 的副本。
(实际上,Python 将在内部使用优化,因此实际上只有一段代码在内存中实现了您的someMethod(),但现在忘记这一点。对于程序员来说,它显示为一个类的每个实例都会有一个方法 someMethod() 的副本。这就是与我们相关的抽象级别,因为这是我们工作的“表面”。在实现的深处编程或脚本语言的事情可能有点不同,但这不是很相关。)
我们来看一个静态方法:
class FooBar:
@staticmethod
def someStaticMethod():
print("abc")
这样的静态方法可以这样调用:
FooBar.someStaticMethod()
如您所见:没有实例。您直接在类本身的上下文中调用此方法。虽然常规方法适用于特定实例本身 - 它们通常修改此实例本身内的数据 - 类方法却没有。它可以修改静态 (!) 数据,但通常它不会。
将静态方法视为一种特殊情况。很少需要它。如果您编写代码,您通常想要的是 not 来实现静态方法。只有在非常特殊的情况下,实现静态方法才有意义。
self 参数
请注意,标准“实例”方法始终必须将self 作为第一个参数。这是特定于 python 的。在现实世界中,Python 将(当然!)只在内存中存储一次您的方法,即使您实例化了您的类的数千个对象。考虑这是一种优化。如果您随后在数千个实例中的一个上调用您的方法,则始终会调用同一段代码。但是为了区分方法的代码应该在您的实例上工作的特定对象,它会作为第一个参数传递给这段内部存储的代码。这是self 参数。它是某种隐式参数,并且对于常规(实例)方法总是需要的。 (不是:静态方法 - 你不需要需要一个实例来调用它们)。
由于这个参数是隐式的,并且大多数编程语言总是需要隐藏它给程序员(并在内部处理这个 - 在引擎盖下 - 以正确的方式)。无论如何,暴露这个特殊的论点并没有多大意义。
不幸的是,Python 没有遵循这个原则。 Python 不会隐藏这个隐式需要的参数。 (Python 对 OOP 概念的结合有点……简单。)因此,您几乎可以在方法中的任何地方看到 self。在您的脑海中您可以忽略它,但如果您定义自己的类,则需要明确编写它。 (为了以良好的方式构建程序,您应该这样做。)
静态方法__new__()
Python 非常特别。虽然常规编程语言遵循如何创建特定类的实例的严格且不可变的概念,但 Python 在这里有点不同。这种行为是可以改变的。此行为在__new__() 中实现。所以如果你这样做......
myObj = FooBar()
... Python 隐式调用FooBar.__new__(),后者又调用一个名为__init__() 的类构造函数(实例)方法,您可以(!)在类中定义(作为实例方法)和then 返回完全初始化的实例。在这个例子中,这个实例就是她存储在myObj 中的内容。
您可以根据需要修改此行为。但这需要一个非常非常非常特别不寻常的用例。在您使用 Python 的整个工作中,您可能永远不会与 __new__() 本身有任何关系。我的建议:如果您对 Python 不熟悉,请忽略它。