写点什么

Python 中的 @staticmethod 和 @classmethod 的区别

用户头像
BigYoung
关注
发布于: 2020 年 07 月 10 日
Python中的@staticmethod和@classmethod的区别

一直搞不明白,类方法和静态方法的区别,特意研究了一下,跟大家分享一下。

为了方便大家了解两者的差别,以下的示例代码将有助于发现其中的差别:

class A(object):def foo(self, x):print "executing foo(%s, %s)" % (self, x)@classmethoddef class_foo(cls, x):print "executing class_foo(%s, %s)" % (cls, x)@staticmethoddef static_foo(x):print "executing static_foo(%s)" % xa = A()
复制代码

以下是对象实例调用方法的常用方法,对象实例 a 作为第一个参数隐式传递。

a.foo(1)# executing foo(<__main__.A object at 0xb7dbef0c>,1)
复制代码

使用 classmethods 时,对象实例的类作为第一个参数而不是隐式传递 self。

a.class_foo(1)# executing class_foo(<class '__main__.A'>,1)
复制代码

您也可以 class_foo 使用该类进行调用。

实际上,如果您将某些东西定义为类方法,则可能是因为您打算从类而不是从类实例调用它。

A.foo(1)本来会引发 TypeError,但 A.class_foo(1)效果很好:

A.class_foo(1)# executing class_foo(<class '__main__.A'>,1)
复制代码

人们发现类方法的一种用途是创建可继承的替代构造函数。

使用 staticmethods 时,self(对象实例)和 cls(类)都不会隐式传递为第一个参数。它们的行为类似于普通函数,只是您可以从实例或类中调用它们:

a.static_foo(1)# executing static_foo(1)A.static_foo('hi')# executing static_foo(hi)
复制代码

特别注意此句:

静态方法用于对与类之间具有某种逻辑联系的函数分组。

foo 只是一个函数,但是当您调用 a.foo 它时,不仅获得该函数,还会获得该函数的“部分应用”版本,该对象实例 a 绑定为该函数的第一个参数。foo 期望有 2 个参数,而 a.foo 只期望有 1 个参数。

a 势必到 foo。这就是下面的术语“绑定”的含义:

print(a.foo)# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
复制代码

与 a.classfoo,a 不绑定 classfoo,而是与类 A 绑定 class_foo。

print(a.class_foo)# <bound method type.class_foo of <class '__main__.A'>>
复制代码

在这里,使用静态方法,即使它是一种方法,也 a.staticfoo 只是返回一个没有绑定参数的良好的'ole 函数。staticfoo 期望有 1 个参数,也 a.static_foo 期望有 1 个参数。

print(a.static_foo)# <function static_foo at 0xb7d479cc>
复制代码

当然,当您 static_foo 使用类进行调用时,也会发生同样的事情 A。

print(A.static_foo)# <function static_foo at 0xb7d479cc>
复制代码


总结一下彼此的调用区别:


本文首发于 BigYoung 小站:http://www.bigyoung.cn

发布于: 2020 年 07 月 10 日阅读数: 69
用户头像

BigYoung

关注

Python工程师/书虫/极客/ 2020.04.22 加入

伸手摘星,即使徒劳无功,也不至于满手泥污。 欢迎大家访问我的BigYoung小站(bigyoung.cn)

评论

发布
暂无评论
Python中的@staticmethod和@classmethod的区别