问题描述
我对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,请忽略它。