什么是python中的“静态方法”

Gre*_*ade 1 python static-methods

我对python很陌生,无法理解python中的静态方法是什么(例如__new__())以及它有什么作用。谁能解释一下?太感谢了

Reg*_*May 5

你已经读过这个了吗?

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

特别是这个?

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

解释

在面向对象的定义,你以后实例化。一个类只不过是一个蓝图:一旦你从一个类中实例化对象,你的对象将完全遵循你的类的蓝图。这意味着:如果您在类中定义了一个名为“abc”的字段,那么稍后您的对象中就会有一个字段“abc”。如果您在类中定义了一个方法“foo()”,那么稍后您将在您的对象上调用一个方法“foo()” 。

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

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

那是一个静态方法。

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

例子

给你举个例子:

class FooBar:

  def someMethod(self):
    print("abc")
Run Code Online (Sandbox Code Playgroud)

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

myObj = FooBar()
myObj.someMethod()
Run Code Online (Sandbox Code Playgroud)

如果你有 ...

myObjB = FooBar()
myObjB.someMethod()
Run Code Online (Sandbox Code Playgroud)

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

(实际上 Python 会在内部使用优化,所以实际上只有一段代码someMethod()在内存中实现你的,但暂时忘记这一点。对于程序员来说,似乎类的每个实例都会有一个方法的副本someMethod()。而这就是抽象的水平是相关的我们,因为这是“表面”我们的深层工作的程序或脚本语言的东西执行中可能会有点不同,但这个不是很重要。)

我们来看一个静态方法:

class FooBar:

  @staticmethod
  def someStaticMethod():
    print("abc")
Run Code Online (Sandbox Code Playgroud)

可以像这样调用此类静态方法:

FooBar.someStaticMethod()
Run Code Online (Sandbox Code Playgroud)

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

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

self参数

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

由于这个参数是隐含的,并且总是需要大多数编程语言隐藏给程序员(并在内部处理 - 在幕后 - 以正确的方式)。无论如何,公开这个特殊的论点并没有多大意义。

不幸的是,Python 没有遵循这个原则。Python 不会隐藏这个隐式需要的参数。(Python 对 OOP 概念的结合有点……简单。)因此,您self几乎可以在方法中看到任何地方。在您看来,您可以忽略它,但如果您定义自己的类,则需要明确地编写它。(为了以良好的方式构建程序,您应该这样做。)

静态方法 __new__()

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

myObj = FooBar()
Run Code Online (Sandbox Code Playgroud)

... Python 隐式调用FooBar.__new__()它反过来调用一个类似构造函数的(实例)方法__init__(),你可以(!)在你的类中定义它(作为实例方法),然后返回完全初始化的实例。这个实例就是myObj在这个例子中存储的东西。

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