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

问题描述

我对python还是很陌生,无法理解python中的静态方法是什么(例如__new__())及其作用。有人可以解释吗?谢谢一百万

解决方法

您已经阅读了吗?

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,请忽略它。