概念区别
<font style="color:#F5222D;">self:</font>
类的方法的第一个参数,表示一个具体的实例本身。如果类的方法用了修饰符“staticmethod”,则可以无视这个self,这个方法就当成一个普通的函数使用<font style="color:#F5222D;">cls:</font>
若类方法用修饰符“classmethod”修饰,则cls作为类方法的第一个参数,表示这个类本身<font style="color:#F5222D;">staticmethod</font>
和<font style="color:#F5222D;">classmethod</font>
- 一般来说,需要将类实例化后,才能调用类的方法。但是,如果类的方法被
<font style="color:rgb(77, 77, 77);">staticmethod</font>
和<font style="color:rgb(77, 77, 77);">classmethod</font>
修饰,则可以不用实例化,可以直接用“类名.方法名()”的方式调用 - 可以把某些属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁
class Person:
a = 'a'
@staticmethod
def people1(name):
print("hello ", name)
def people2(self, name):
print("hello ", name)
@classmethod
def people3(cls, name):
print("hello ", name)
定义一个类Person
,类Person中有三个函数,people1
为静态函数,用<font style="color:#F759AB;">@staticmethod</font>
装饰,people<font style="color:rgb(77, 77, 77);">2</font>
为一般的类方法,people<font style="color:rgb(77, 77, 77);">3</font>
为类函数,用<font style="color:#F759AB;">@classmethod</font>
修饰。
- 对于类方法
people1
,既可以作为类的<font style="color:rgb(77, 77, 77);">方法</font>
使用,也可以作为类的<font style="color:rgb(77, 77, 77);">实例的方法</font>
使用
Per = Person()
Per.people1("world") # 输出hello world
Person.people1("world") # 输出hello world
- 对于类方法
people2
,它是正常的函数,是类的实例的函数,只能通过<font style="color:#F759AB;">Per</font>
调用
Per.people2('world') # 输出: hello world
Person.people2('world') # 报错: unbound method people2() must be called with A instance as first argument (got str instance instead)
- 对于类方法
people3
,它是类函数,<font style="color:rgb(77, 77, 77);">cls</font>
作为第一个参数用来表示类本身。在类方法中用到,类方法是只与类本身有关而与实例无关的方法
Per.foo1("world") # 输出: hello world
Per.foo1("world") # 输出: hello world
- 虽然
<font style="color:rgb(77, 77, 77);">staticmethod</font>
与<font style="color:rgb(77, 77, 77);">classmethod</font>
的使用方法和输出结果相同,但这两种方法还是有区别
1. <font style="color:rgb(85, 86, 102);background-color:rgb(238, 240, 244);">classmethod</font>
修饰的类方法,第一个参数必须是<font style="color:rgb(85, 86, 102);background-color:rgb(238, 240, 244);">cls</font>
,而<font style="color:rgb(85, 86, 102);background-color:rgb(238, 240, 244);">staticmethod</font>
则既不需要<font style="color:rgb(85, 86, 102);background-color:rgb(238, 240, 244);">self</font>
也不需要<font style="color:rgb(85, 86, 102);background-color:rgb(238, 240, 244);">cls</font>
2. <font style="color:rgb(85, 86, 102);background-color:rgb(238, 240, 244);">classmethod</font>
中可以通过<font style="color:rgb(85, 86, 102);background-color:rgb(238, 240, 244);">cls</font>
调用类的方法;而<font style="color:rgb(85, 86, 102);background-color:rgb(238, 240, 244);">staticmethod</font>
则无法调用类的其他方法。但是二者都可以通过<font style="color:#F759AB;background-color:rgb(238, 240, 244);">"类名.属性名"</font>
的方式访问类的属性 - 在classmethod中可以调用类中定义的其他方法、类的属性,但staticmethod只能通过
<font style="color:rgb(77, 77, 77);">Person.a</font>
调用类的属性,但无法通过在该函数内部调用<font style="color:rgb(77, 77, 77);">A.Person2()</font>
。
class Person:
a = 'a'
@staticmethod
def people1(name):
print("hello ", name)
def people2(self, name):
print("hello ", name)
print(Person.a)
print(Person.people2("xx")) #报错:unbound method people2() must be called with A instance as first argument (got str instance instead)
@classmethod
def people3(cls, name):
print("hello ", name)
print(Person.a)
print(cls.people2("xx"))