设为首页 收藏本站
查看: 847|回复: 0

[经验分享] Python 中的方法、静态方法(static method)和类方法(class method)

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-6-23 08:57:52 | 显示全部楼层 |阅读模式
英文原文: https://julien.danjou.info/blog/ ... ss-abstract-methods
翻译出处: http://python.jobbole.com/81595/


一、How methods work in Python
方法就是一个函数、以类的属性被存储。可以通过如下的形式进行声明和访问:
1
2
3
4
5
6
7
8
9
In [1]: class Pizza(object):
   ...:     def __init__(self,size):
   ...:         self.size = size
   ...:     def get_size(self):
   ...:         return self.size
   ...:     

In [2]: Pizza.get_size
Out[2]: <unbound method Pizza.get_size>



以上的执行结果告诉我们,类Pizza 的属性get_size 是一个未绑定的方法。是什么意思呢? 将在下面的尝试得到答案。
1
2
3
4
5
6
7
In [3]: Pizza.get_size()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-65dcef60aa06> in <module>()
----> 1 Pizza.get_size()

TypeError: unbound method get_size() must be called with Pizza instance as first argument (got nothing instead)



上面的结果告诉我们,想要调用类Pizza的属性get_size,需要一个Pizza 的实例。而从get_size 的方法中也可以看出,第一个参数为一个Pizza的实例
1
2
In [4]: Pizza.get_size(Pizza(42))
Out[4]: 42



OK,以上我们可以真正的去使用类Pizza 的属性get_size 了。 而现实生活中,我们通常这样使用:
1
2
3
4
In [5]: pizza = Pizza(42)      # 声明一个Pizza 的实例

In [6]: pizza.get_size()       # 通过声明的实例pizza 调用 get_size 方法
Out[6]: 42




二、Static methods
什么时静态方法? 我感觉还是英文原汁原味的更地道
Static methods are a special case of methods. Sometimes, you'll write code that belongs to a class, but that doesn't use the object itself at all.
静态方法是一类特殊的方法。有时,你想写一些属于类的代码,但又不会去使用和这个类任何相关的东西。
Example:
1
2
3
4
5
6
In [1]: class Pizza(object):
   ...:     @staticmethod
   ...:     def mix_ingredients(x,y):
   ...:         return x + y
   ...:     def cook(self):
   ...:         return self.mix_ingredients(self.cheese,self.vegetables)



在以上的例子中,书写一个非静态的方法同样也可以工作。但是需要对函数mix_ingredients 传递一个self 参数,但这个参数时完全使用不到的。在这里使用到了装饰器 @staticmethod 。它给我们带来了
如下的几点好处:

Python 可以直接使用静态方法,而避免了去实例化一个对象。实例化对象需要消耗资源的,静态方法避免了这一切。
可读性更好了,看到@staticmethod 后,我们就可以知道此方法是对立的,不需要依赖类的实例。
1
2
3
4
5
6
7
8
9
10
In [3]: Pizza().cook is Pizza().cook
Out[3]: False

In [4]: Pizza().mix_ingredients is Pizza.mix_ingredients
Out[4]: True

In [5]: Pizza().mix_ingredients is Pizza().mix_ingredients
Out[5]: True

In [6]:



从上面的执行结果也可以看出,静态方法即可以被类调用,同样类的实例也可以调用,只是这样会耗用更多的资源而已(看起来不专业。哈哈)

三、Class methods
what are class methods? Class methods are methods that are not bound to an object, but to… a class!
什么时类方法,类方法不是绑定到类的实例上去的,而是绑定到类上去的.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
In [1]: class Pizza(object):
   ...:     radius = 42
   ...:     @classmethod
   ...:     def get_radius(cls):
   ...:         return cls.radius
   ...:     

In [2]: Pizza.get_radius
Out[2]: <bound method type.get_radius of <class '__main__.Pizza'>>

In [3]: Pizza().get_radius
Out[3]: <bound method type.get_radius of <class '__main__.Pizza'>>

In [4]: Pizza.get_radius()
Out[4]: 42



无论什么情况下,get_radius 都是绑定到 类 Pizza 上的。

那这个类方法,到底有什么用呢? 我们在什么时候才会去用它呢? 我想这才是我想去关心的。

(1)、工厂方法:它用于创建类的实例,例如一些预处理。如果使用@staticmethod代替,那我们不得不硬编码Pizza类名在函数中,这使得任何继承Pizza的类都不能使用我们这个工厂方法给它自己用。
1
2
3
4
5
6
7
class Pizza(object):
    def __init__(self, ingredients):
        self.ingredients = ingredients
  
    @classmethod
    def from_fridge(cls, fridge):
        return cls(fridge.get_cheese() + fridge.get_vegetables())



(2)、调用静态类:如果你把一个静态方法拆分成多个静态方法,除非你使用类方法,否则你还是得硬编码类名。使用这种方式声明方法,Pizza类名明永远都不会在被直接引用,继承和方法覆盖都可以完美的工作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Pizza(object):
    def __init__(self, radius, height):
        self.radius = radius
        self.height = height
  
    @staticmethod
    def compute_area(radius):
         return math.pi * (radius ** 2)
  
    @classmethod
    def compute_volume(cls, height, radius):
         return height * cls.compute_area(radius)
  
    def get_volume(self):
        return self.compute_volume(self.height, self.radius)



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-79645-1-1.html 上篇帖子: Python变量、运算符与表达式 下篇帖子: 为python添加tab自动补全功能 method
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表