对于Python中的类方法,"self"实际上是强制性的吗



我在Python 3.6.5中看到了一个代码片段,可以用下面的这个简化示例复制,我不明白这是否令人担忧。老实说,我很惊讶它能起作用。。。

class Foo:
def bar(numb):
return numb
A1 = bar(1)

print(Foo)
print(Foo.A1)
print(Foo.bar(17))

在我看过的所有python指南中,self作为我们所知道和喜爱的所有目的的第一个论据出现。如果不是,则使用静态装饰器对方法进行装饰,一切都很好。然而,这个案例确实有效。如果我在bar上使用静态装饰器,那么在设置A1:时会得到一个TypeError

Traceback (most recent call last):
File "/home/user/dir/understanding_classes.py", line 1, in <module>
class Foo:
File "/home/user/dir/understanding_classes.py", line 7, in Foo
A1 = bar(1)
TypeError: 'staticmethod' object is not callable

这是可以保留在代码中的东西吗?还是潜在的问题?我希望这个问题不要太宽泛,但这是如何以及为什么起作用的?

方法的第一个参数将设置为接收器。按照惯例,我们称之为self,但self不是关键字;任何有效的参数名称都同样有效。

有两种不同的方法可以调用这里相关的方法。假设我们有一个简单的Person类,其中包含namesay_hi方法

class Person:
def __init__(self, name):
self.name = name
def say_hi(self):
print(f'Hi my name is {self.name}')

p = Person('J.K.')

如果我们在p上调用该方法,我们将使用self=p调用say_hi

p.say_hi() # self=p, prints 'Hi my name is J.K.'

您在示例中所做的是通过类调用方法,并显式传递第一个参数。这里的等价调用是

Person.say_hi(p) # explicit self=p, also prints 'Hi my name is J.K.'

在您的示例中,您使用一个非静态方法,然后通过类调用它,然后显式传递第一个参数。它确实有效,但没有多大意义,因为你应该能够通过说来调用非静态方法

f = Foo()
f.bar() # numb = f, works, but numb isn't a number it's a Foo

如果你想把一个函数放在一个没有接收器的类中,那就是你想使用@staticmethod(或者更常见的@classmethod(的时候

class Person:
def __init__(self, name):
self.name = name
def say_hi(self):
print(f'Hi my name is {self.name}')
@staticmethod
def say_hello():
print('hello')

p = Person('J.K.')
Person.say_hello()
p.say_hello()

最新更新