我正在阅读PEP 8(样式指南),我注意到它建议使用self作为实例方法中的第一个参数,但cls作为类方法中的第一个参数。
我已经使用并编写了一些类,但我从未遇到过类方法(嗯,一种将cls作为参数传递的方法)。有哪些例子?
创建实例方法时,第一个参数总是self
. 您可以将其命名为任何您想要的名称,但含义始终相同,并且您应该使用self
它,因为它是命名约定。
self
(通常)在调用实例方法时被隐藏传递;它表示调用该方法的实例。
这是一个名为的类的示例,该类Inst
具有一个名为的实例方法introduce()
:
class Inst:
def __init__(self, name):
self.name = name
def introduce(self):
print("Hello, I am %s, and my name is " %(self, self.name))
现在要调用这个方法,我们首先需要创建我们的类的一个实例。一旦我们有了一个实例,我们就可以调用introduce()
它,该实例将自动传递为self
:
myinst = Inst("Test Instance")
otherinst = Inst("An other instance")
myinst.introduce()
# outputs: Hello, I am <Inst object at x>, and my name is Test Instance
otherinst.introduce()
# outputs: Hello, I am <Inst object at y>, and my name is An other instance
如您所见,我们没有传递参数self
。它通过句点运算符隐藏传递。我们正在调用Inst
类的实例方法introduce
,参数为myinst
or otherinst
。这意味着我们可以调用Inst.introduce(myinst)
并获得完全相同的结果。
类方法的概念与实例方法非常相似,唯一的区别是我们现在将类本身作为第一个参数传递,而不是将实例作为第一个参数隐藏传递。
class Cls:
@classmethod
def introduce(cls):
print("Hello, I am %s!" %cls)
由于我们只将一个类传递给该方法,因此不涉及任何实例。
这意味着我们根本不需要实例,我们调用类方法就好像它是一个静态函数:
Cls.introduce() # same as Cls.introduce(Cls)
# outputs: Hello, I am <class 'Cls'>
请注意,再次Cls
隐藏传递,因此我们也可以说Cls.introduce(Inst)
并获取输出"Hello, I am <class 'Inst'>
。
当我们从以下位置继承一个类时,这特别有用Cls
:
class SubCls(Cls):
pass
SubCls.introduce()
# outputs: Hello, I am <class 'SubCls'>
简单地说,实例方法是在类内部定义的函数。它因类的不同实例而异。例子:
class Dog:
def __init__(self, sound):
self.sound = sound
def bark(self):
return f"The dog makes the sound: {self.sound}"
与 bark() 方法不同,类方法是应用于类的所有实例的方法。