python 中的 "static method" 是什么

What is "static method" in python

我是 python 的新手,无法理解 python(例如 __new__())中的静态方法是什么以及它的作用。谁能解释一下?百万感谢

你已经读过了吗?

https://en.wikipedia.org/wiki/Method_(computer_programming)

尤其是这个?

https://en.wikipedia.org/wiki/Method_(computer_programming)#Static_methods

说明

在 OOP 中,您定义 classes,稍后您将在 实例化。 class 只不过是一个蓝图:从 class 实例化对象后,您的对象将完全遵循 class 的蓝图。这意味着:如果您在 class 中定义了一个名为“abc”的字段,您稍后将在您的对象中拥有一个字段“abc”。如果您在 class 中定义方法“foo()”,稍后您将在对象.[=34 上调用方法“foo()” =]

请注意这个“在你的对象上”是必不可少的:你总是实例化一个class然后然后你可以调用方法。这是“正常”方式。

一个静态方法不同。虽然普通方法总是需要有一个实例(然后您可以在其中调用此方法),但静态方法 而不是 。静态方法独立于您的实例而存在(这就是它被命名为“静态”的原因)。因此,静态方法与您的 class 定义本身相关联,因此始终存在,因此只能在您的 class 本身中调用。它完全独立于所有实例。

这是一个静态方法。

Python的实现有点……嗯……简单。在细节上与上述描述存在偏差。但这没有任何区别:为了符合 OOP 概念,您始终应该使用与上述完全相同的方法。

例子

举个例子:

class FooBar:

  def someMethod(self):
    print("abc")

这是一个常规(实例)方法。你这样使用它:

myObj = FooBar()
myObj.someMethod()

如果你有...

myObjB = FooBar()
myObjB.someMethod()

...您有一个额外的实例,因此在第二个实例上调用 someMethod() 将调用第二个 someMethod() 方法 - 在第二个对象中定义。这是因为您在使用前实例化对象,因此所有实例都遵循定义的蓝图 FooBar。因此所有实例都会收到某种形式的 someMethod().

副本

(实际上 Python 会在内部使用优化,所以实际上只有一段代码实现了你的 someMethod() 在内存中,但现在暂时忘记这个。对程序员来说它 出现,因为 class 的每个实例都会有一个方法 someMethod() 的副本。而 这就是 抽象级别这与我们相关,因为这是我们工作的“表面”。在编程或脚本语言的实施中,事情可能有点不同,但这不是很相关。)

我们来看一个静态方法:

class FooBar:

  @staticmethod
  def someStaticMethod():
    print("abc")

这样的静态方法可以这样调用:

FooBar.someStaticMethod()

如您所见:没有实例。您可以在 class 本身的上下文中直接调用此方法。虽然常规方法适用于特定实例本身 - 它们通常会修改此实例本身内的数据 - class 方法不会。它可以修改静态 (!) 数据,但通常不会。

将静态方法视为一种特殊情况。很少需要它。如果您编写代码,您通常想要的是 而不是 来实现静态方法。只有在非常特殊的情况下,实现静态方法才有意义。

self参数

请注意,标准“实例”方法始终必须将 self 作为第一个参数。这是 python 具体的。在现实世界中 Python 将(当然!)只在内存中存储您的方法一次,即使您实例化 class 的数千个对象也是如此。将此视为优化。如果您随后在数千个实例中的一个实例上调用您的方法,则始终会调用同一段代码。但是为了区分该方法的代码应该在您的实例上工作的特定对象,将作为第一个参数传递给这个内部存储的代码段。这是 self 参数。它是某种隐式参数,常规(实例)方法总是需要它。 (不是:静态方法 - 您 不需要 需要一个实例来调用它们)。

因为这个参数是隐含的并且大多数编程语言总是需要它向程序员隐藏它(并在内部以正确的方式处理它 - 在引擎盖下)。无论如何,暴露这个特殊的论点并没有多大意义。

很遗憾Python不遵循这个原则。 Python 不隐藏隐式要求的参数。 (Python 对 OOP 概念的结合有点……简单。)因此,您几乎在方法中随处可见 self。在你的脑海里你可以忽略它,但如果你定义了你自己的 classes,你需要明确地写它。 (为了以良好的方式构建程序,您应该这样做。)

静态方法__new__()

Python比较特别。虽然常规编程语言遵循如何创建特定 classes 实例的严格且不变的概念,但 Python 在这里有点不同。这种行为是可以改变的。此行为在 __new__() 中实现。所以如果你这样做......

myObj = FooBar()

... Python 隐式调用 FooBar.__new__() 进而调用名为 __init__() 的 constructor-like (实例)方法,您可以(!)在 class(作为实例方法)和 then returns 完全初始化的实例。在这个例子中,这个实例就是存储在 myObj 中的内容。

如果需要,您可以修改此行为。但这需要一个非常非常非常特别不寻常的用例。在你与 Python 的整个工作中,你可能永远不会与 __new__() 本身有任何关系。我的建议:如果您是 Python 的新手,请忽略它。