python @classmethod
将函数转换为类函数的装饰器
用法:
class C:
@classmethod
def f(cls, arg1, arg2, ...):#类方法
pass
def f1(self,arg1,arg2, ...):#实例方法
pass
...
类方法与实例方法的本质区别:(敲黑板!!!)
类方法第一个参数传入类的内存地址,便于访问类的命名空间!
实例方法第一个参数传入实例的内存地址,便于访问实例的命名空间!
深入理解Python的很多东西需要联系命名空间。
类方法,为了使用类的属性与方法而创立,服务于类,服务于所有实例
实例方法,为了使用实例的属性(_init _()初始化的属性)与方法而创立,服务于具体实例
静态方法,不使用类与实例的内容而创立,佛系方法,仅存在于类的命名空间!
python类方法的特性
1、与静态方法一样,可以通过类名调用类方法。
2、与静态方法一样,类成员方法无法访问对象实体变量,可以访问类的静态变量。
3、类方法需要传入代表本类的cls参数。
ps:类属性的定义方法是直接在类中定义一个属性,这样定义的属性就是类属性。
(类属性与方法区别与实例的属性与方法设计目的不同:服务共有与私有 )
可以通过类对象来修改类属性,但是不可以通过实例对象来修改类属性。用实例对象来修改类属性时不会报错,因为这时候其实是给类的实例对象定义了一个与类属性同名的实例属性。
类方法一般和类属性配合使用,当方法中需要使用类对象(如访问私有类属性等)时,定义类方法。
实例测试
class C:
__private_property = 'C_private'
property1 = 'c_property1'
def __init__(self,arg0):
self.arg0 = arg0
@classmethod
def cls_f1(cls, arg1):#cls用来存储类地址
print(cls)
print(arg1)
print(cls.property1)#调用类属性
print(cls.__private_property)#调用类私有属性
cls.cls_f2('cls.f1 调用 cls.f2()')
@classmethod
def cls_f2(cls,arg2):
print(cls)
print(arg2)
def f1(self,arg2):#self用来存储实例地址
print(self)
print(arg2)
print(self.property1)#访问实例属性,如果没有去类命名空间找
print(self.arg0)
print(self.__private_property)#也不报错,类私有只是君子约定
a = C('a实例')
b = C('b实例')
print(a.property1)#到类中找相应类属性
a.property1='a.property1我是实例属性'#创建与类的同名的实例属性
print(a.property1)#访问实例属性
print(b.property1)#访问的类属性
a.cls_f1('a.cls_f1()')
print('#'*40)
C.property1 = 'property_new'
print(C.property1)
print(b.property1)
print(a.property1)
a.cls_f1('a.cls_f1()')
a.cls_f2('a.cls_f2()')
b.f1('b.f1')#print(self.property1)找不到b实例的property1就会到类中找
输出:
c_property1
a.property1我是实例属性
c_property1
<class '__main__.C'>
a.cls_f1()
c_property1
C_private
<class '__main__.C'>
cls.f1 调用 cls.f2()
########################################
property_new
property_new
a.property1我是实例属性
<class '__main__.C'>
a.cls_f1()
property_new
C_private
<class '__main__.C'>
cls.f1 调用 cls.f2()
<class '__main__.C'>
a.cls_f2()
<__main__.C object at 0x03337F70>
b.f1
property_new
b实例
C_private