Python的静态方法和类成员方法可以被类或实例访问。两者的概念不好说清楚,但还是有区别的:
1)静态方法不需要传入self参数,类成员方法需要传入代表类的cls参数;
2)从第一条开始,静态方法不能访问实例变量,类成员方法也不能访问实例变量,但是可以访问类变量;
3)静态方法有点像函数工具库,而类成员方法更接近Java面向对象概念中的静态方法。
实现静态方法和类方法的两种方式
一、在Python 2.3及之前,用staticmethod和classmethod类型对象包装实现
例子如下(注意print里的说明):
class MyClass:
val1 = 'Value 1'
def __init__(self):
self.val2 = 'Value 2'
def staticmd():
print '静态方法,无法访问val1和val2'
smd = staticmethod(staticmd)
def classmd(cls):
print '类方法,类:' + str(cls) + ',val1:' + cls.val1 + ',无法访问val2的值'
cmd = classmethod(classmd)
执行:
>>> mc = MyClass()
>>> mc.smd()
>>> mc.cmd()
>>> MyClass.smd()
>>> MyClass.cmd()
二、在Python 2.4及之后,用装饰器(decorators)实现
装饰器使用@操作符,例子如下:
class MyClass:
val1 = 'Value 1'
def __init__(self):
self.val2 = 'Value 2'
@staticmethod
def staticmd():
print '静态方法,无法访问val1和val2'
@classmethod
def classmd(cls):
print '类方法,类:' + str(cls) + ',val1:' + cls.val1 + ',无法访问val2的值'
以上两种方式无论使用哪一种,执行情况都是一样的。以方法2的执行结果为例,分析如下:
执行:
>>> mc = MyClass() # 实例化
>>> mc.staticmd() # 实例调用静态方法,无法访问实例变量val1和val2
>>>
静态方法,无法访问val1和val2
>>> mc.classmd() # 实例调用类方法,注意,这里访问的是类MyClass的变量val1的值,不是实例化后mc的实例变量val1,
这里容易混淆,往下看就会明白。val2一直是实例变量,所以无法访问
>>>
类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值
>>> MyClass.staticmd() # 类直接调用静态方法,结果同上面的实例调用,无论是类变量还是实例变量都无法访问
>>>
静态方法,无法访问val1和val2
>>> MyClass.classmd() # 类直接调用类方法,结果同上面的实例调用
>>>
类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值
>>> mc.val1 = 'Value changed' # 改变实例变量val1的值
>>> mc.classmd() # 实例调用类方法,注意到cls.val1的值没变,所以,这时的cls.val1是类变量val1,而非实例变量val1
>>>
类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值
>>> MyClass.classmd() # 类直接调用类方法,结果同上面的实例调用
>>>
类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值
>>> MyClass.val1 = 'Class Value changed' # 改变类变量val1的值
>>> mc.classmd() # 实例调用类方法,注意到cls.val1的值变了,所以,进一步证明了这时的cls.val1是类变量val1,
而非实例变量val1
>>>
类方法,类:__main__.MyClass,val1:Class Value changed,无法访问val2的值
>>> MyClass.classmd() # 类直接调用类方法,结果同上面的实例调用
>>>
类方法,类:__main__.MyClass,val1:Class Value changed,无法访问val2的值
结论
如果上面的执行过程过于复杂,只要记住以下两点即可:
1、静态成员方法:不能访问类属性、实例属性,相当于一个独立的方法。可以理解为与类无关,只是给类加了一个作用域。比如:一个类有三种加密算法,可以考虑静态方法;
2、类成员方法:可以访问类属性,但不能访问实例属性。这里需要注意的是python是一种动态语言。与C++不同的是,实例可以动态添加属性,即实例属性和类属性不一定相同。
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Python中的彩色饼图! (一)10/13
- ♥ 如何在python3中编写自动关机?10/03
- ♥ 如何理解整数对象存储在 Python 中的位置?12/15
- ♥ 如何卸载python08/29
- ♥ python列表读取方法09/18
- ♥ Python schedule 任务调度及其用法11/13
内容反馈