丁逸 發表於 2019-9-4 18:52:00

Python中@staticmethod和@classmethod的作用和区别

<p><span style="font-size: 14px">Python有3种方法,静态方法(staticmethod),类方法(classmethod)和实例方法。下面用代码举例。</span></p>
<p>对于一般的函数foo(x),它跟类和类的实例没有任何关系,直接调用foo(x)即可。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> foo(x):
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">running foo(%s)</span><span style="color: rgba(128, 0, 0, 1)">"</span> %<span style="color: rgba(0, 0, 0, 1)"> x)

foo(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test</span><span style="color: rgba(128, 0, 0, 1)">"</span>)</pre>
</div>
<p><span style="line-height: 1.5">在类A里面的实例方法foo(self, x),<strong>第一个参数是self</strong>,我们需要有一个A的实例,才可以调用这个函数。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> A:
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> foo(self, x):
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">running foo(%s, %s)</span><span style="color: rgba(128, 0, 0, 1)">"</span> %<span style="color: rgba(0, 0, 0, 1)"> (self, x))

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> A.foo(x) 这样会报错</span>
a =<span style="color: rgba(0, 0, 0, 1)"> A()
a.foo(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test</span><span style="color: rgba(128, 0, 0, 1)">"</span>)</pre>
</div>
<p><span style="line-height: 1.5">当我们需要和类直接进行交互,而不需要和实例进行交互时,类方法是最好的选择。类方法与实例方法类似,但是传递的不是类的实例,而是类本身,</span><strong style="line-height: 1.5">第一个参数是cls</strong><span style="line-height: 1.5">。<strong>我们可以用类的实例调用类方法,也可以直接用类名来调用。</strong></span><span style="color: rgba(0, 128, 0, 1)"><br></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> A:
    class_attr </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">attr</span><span style="color: rgba(128, 0, 0, 1)">"</span>
   
    <span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">(self):
      </span><span style="color: rgba(0, 0, 255, 1)">pass</span><span style="color: rgba(0, 0, 0, 1)">
      
    @classmethod
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> class_foo(cls):
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">running class_foo(%s)</span><span style="color: rgba(128, 0, 0, 1)">"</span> %<span style="color: rgba(0, 0, 0, 1)"> (cls.class_attr))

a </span>=<span style="color: rgba(0, 0, 0, 1)"> A()
a.class_foo()
A.class_foo()</span></pre>
</div>
<p><span style="line-height: 1.5">静态方法类似普通方法,参数里面不用self。这些方法和类相关,但是又不需要类和实例中的任何信息、属性等等。如果把这些方法写到类外面,这样就把和类相关的代码分散到类外,使得之后对于代码的理解和维护都是巨大的障碍。而静态方法就是用来解决这一类问题的。</span></p>
<p><span style="line-height: 1.5">比如我们检查是否开启了日志功能,这个和类相关,但是跟类的属性和实例都没有关系。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
log_enabled =<span style="color: rgba(0, 0, 0, 1)"> True

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> A:
    class_attr </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">attr</span><span style="color: rgba(128, 0, 0, 1)">"</span>
   
    <span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">(self):
      </span><span style="color: rgba(0, 0, 255, 1)">pass</span><span style="color: rgba(0, 0, 0, 1)">
      
    @staticmethod
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> static_foo():
      </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> log_enabled:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">log is enabled</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
            </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">log is disabled</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      

A.static_foo()</span></pre>
</div>
<p>&nbsp;</p>
<p><span style="line-height: 1.5">参考文章:</span></p>
<p><span style="line-height: 1.5">https://www.jianshu.com/p/ce117e8b1c61</span></p>
<p><span style="line-height: 1.5">https://blog.csdn.net/ljt735029684/article/details/80714274</span></p>
<p><span style="line-height: 1.5">https://github.com/jackfrued/interview_python</span></p><br><br>
来源:https://www.cnblogs.com/dogecheng/p/11441088.html
頁: [1]
查看完整版本: Python中@staticmethod和@classmethod的作用和区别