python类的三种方法
<p>一、先看语法,python 类语法中有三种方法,实例方法,静态方法,类方法。</p><p>ps.python中self,cls的区别</p>
<p>普通实例方法,第一个参数需要是self,它表示一个具体的实例本身。<br>如果用了staticmethod,那么就可以无视这个self,而将这个方法当成一个普通的函数使用。<br>而对于classmethod,它的第一个参数不是self,是cls,它表示这个类本身。</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)"> Foo(object):
</span><span style="color: rgba(128, 0, 0, 1)">"""</span><span style="color: rgba(128, 0, 0, 1)">类三种方法语法形式</span><span style="color: rgba(128, 0, 0, 1)">"""</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> instance_method(self):
</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)">是类{}的实例方法,只能被实例对象调用</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">.format(Foo))
@staticmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> static_method():
</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)">是静态方法</span><span style="color: rgba(128, 0, 0, 1)">"</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_method(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)">是类方法</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
foo </span>=<span style="color: rgba(0, 0, 0, 1)"> Foo()
foo.instance_method()
foo.static_method()
foo.class_method()
</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)">----------------</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
Foo.static_method()
Foo.class_method()</span></pre>
</div>
<p>运行结果如下</p>
<div class="cnblogs_code">
<pre>是类<<span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__.Foo</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, 0, 1)">
是静态方法
是类方法</span></pre>
</div>
<p>说明:</p>
<p>实例方法只能被实例对象调用,静态方法(由@staticmethod装饰的方法)、类方法(由@classmethod装饰的方法),可以被类或类的实例对象调用。</p>
<p>实例方法,第一个参数必须要默认传实例对象,一般习惯用self。<br>静态方法,参数没有要求。</p>
<p>类方法,第一个参数必须要默认传类,一般习惯用cls。</p>
<p>二、静态方法、类方法使用区别或者说使用场景</p>
<p>1、类方法用在模拟java定义多个构造函数的情况。</p>
<p> 由于python类中只能有一个初始化方法,不能按照不同的情况初始化类。</p>
<p>参考django https://docs.djangoproject.com/en/1.9/ref/models/instances/ 请看下面的代码。</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)"> Book(object):
</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, title):
self.title </span>=<span style="color: rgba(0, 0, 0, 1)"> title
@classmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> class_method_create(cls, title):
book </span>= cls(title=<span style="color: rgba(0, 0, 0, 1)">title)
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> book
@staticmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> static_method_create(title):
book</span>=<span style="color: rgba(0, 0, 0, 1)"> Book(title)
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> book
book1 </span>= Book(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">use instance_method_create book instance</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
book2 </span>= Book.class_method_create(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">use class_method_create book instance</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
book3 </span>= Book.static_method_create(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">use static_method_create book instance</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)">print</span><span style="color: rgba(0, 0, 0, 1)">(book1.title)
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(book2.title)
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(book3.title)</pre>
</div>
<p>结果:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">use instance_method_create book instance
use class_method_create book instance
use static_method_create book instance
Process finished with exit code 0</span></pre>
</div>
<p>特别说明,静态方法也可以实现上面功能,当静态方法每次都要写上类的名字,不方便。</p>
<p>2、类中静态方法方法调用静态方法和类方法调用静态方法例子。</p>
<p>下面的代码,静态方法调用另一个静态方法,如果改用类方法调用静态方法,可以让cls代替类,</p>
<p>让代码看起来精简一些。也防止类名修改了,不用在类定义中修改原来的类名。</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)"> Foo(object):
X </span>= 1<span style="color: rgba(0, 0, 0, 1)">
Y </span>= 2<span style="color: rgba(0, 0, 0, 1)">
@staticmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span> averag(*<span style="color: rgba(0, 0, 0, 1)">mixes):
</span><span style="color: rgba(0, 0, 255, 1)">return</span> sum(mixes) /<span style="color: rgba(0, 0, 0, 1)"> len(mixes)
@staticmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span> static_method():<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 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)">在静态方法中调用静态方法</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Foo.averag(Foo.X, Foo.Y)
@classmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span> class_method(cls):<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 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)">在类方法中使用静态方法</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cls.averag(cls.X, cls.Y)
foo </span>=<span style="color: rgba(0, 0, 0, 1)"> Foo()
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(foo.static_method())
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(foo.class_method())</pre>
</div>
<p>结果:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">在静态方法中调用静态方法
</span>1<span style="color: rgba(0, 0, 0, 1)">
在类方法中使用静态方法
</span>1</pre>
</div>
<p>3、继承类中的区别 </p>
<p>从下面代码可以看出,如果子类继承父类的方法,子类覆盖了父类的静态方法,<br>子类的实例继承了父类的static_method静态方法,调用该方法,还是调用的父类的方法和类属性。</p>
<p>子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。</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)"> Foo(object):
X </span>= 1<span style="color: rgba(0, 0, 0, 1)">
Y </span>= 14<span style="color: rgba(0, 0, 0, 1)">
@staticmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span> averag(*mixes):<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> "父类中的静态方法"</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> sum(mixes) /<span style="color: rgba(0, 0, 0, 1)"> len(mixes)
@staticmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span> static_method():<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 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)">父类中的静态方法</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Foo.averag(Foo.X, Foo.Y)
@classmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span> class_method(cls):<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 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)">父类中的类方法</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cls.averag(cls.X, cls.Y)
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Son(Foo):
X </span>= 3<span style="color: rgba(0, 0, 0, 1)">
Y </span>= 5<span style="color: rgba(0, 0, 0, 1)">
@staticmethod
</span><span style="color: rgba(0, 0, 255, 1)">def</span> averag(*mixes):<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 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)">子类中重载了父类的静态方法</span><span style="color: rgba(128, 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)">666 </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,mixes
</span><span style="color: rgba(0, 0, 255, 1)">return</span> sum(mixes) / 3<span style="color: rgba(0, 0, 0, 1)">
p </span>=<span style="color: rgba(0, 0, 0, 1)"> Son()
</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)">result of p.averag(1,5)</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">print</span> (p.averag(1,5<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)">result of p.static_method()</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(p.static_method())
</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)">result of p.class_method()</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">print</span>(p.class_method())</pre>
</div>
<p>结果如下:</p>
<div class="cnblogs_code">
<pre>result of p.averag(1,5<span style="color: rgba(0, 0, 0, 1)">)
子类中重载了父类的静态方法
</span>666(1, 5<span style="color: rgba(0, 0, 0, 1)">)
</span>2<span style="color: rgba(0, 0, 0, 1)">
result of p.static_method()
父类中的静态方法
</span>7<span style="color: rgba(0, 0, 0, 1)">
result of p.class_method()
父类中的类方法
子类中重载了父类的静态方法
</span>666(3, 5<span style="color: rgba(0, 0, 0, 1)">)
</span>2<span style="color: rgba(0, 0, 0, 1)">
Process finished with exit code 0</span></pre>
</div><br><br>
来源:https://www.cnblogs.com/corbyliu/p/12067931.html
頁:
[1]