概念区别

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