概念区别
<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 worldPerson.people1("world") # 输出hello world
- 对于类方法
people2,它是正常的函数,是类的实例的函数,只能通过<font style="color:#F759AB;">Per</font>调用
Per.people2('world') # 输出: hello worldPerson.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 worldPer.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"))