一 类方法classmethod
在python中,classmethod是内置的装饰器之一,它的作用如下
- 声明一个方法是类方法,可以不用创建实例对象就调用类方法,调用方式:类名.方法名,其中方法的参数self变成cls,cls的作用同self一样。
无classmethod声明
#无classmethod
class my_class():
def __init__(self):
pass
def func1(self):
print("this is func1")
def func2(self):
print("this is func2")
#不创建实例对象,直接调用方法
my_class.func1()
my_class.func2()
>>>
Traceback (most recent call last):
File "C:/Users/admin/python-learning/python学习文件/python基础/CSDN.py", line 21, in <module>
my_class.func1()
TypeError: func1() missing 1 required positional argument: 'self'
可以看到,在没有用装饰器classmethod的时候,不创建实例化对象就调用类方法是会报错的。
有classmethod装饰器
#有classmethod
class my_class():
def __init__(self):
pass
@classmethod
def func1(cls):
print("this is func1")
def func2(self):
print("this is func2")
#func1有classmethod装饰,func2没有
my_class.func1()
my_class.func2()
>>>
Traceback (most recent call last):
File "C:/Users/admin/python-learning/python学习文件/python基础/CSDN.py", line 23, in <module>
my_class.func2()
TypeError: func2() missing 1 required positional argument: 'self'
this is func1
上面的func1使用了classmethod进行装饰,就可以不用创建实例对象直接进行类名.类方法调用;而func2没有使用classmethod进行声明,所以仍然会报错。
二 静态方法staticmethod
同样的,staticmethod也是python内置的装饰器之一,它的作用如下
- 声明一个方法是一个静态方法,可以不用创建实例对象就调用类方法,调用式:类名.方法名,其中方法的参数self可以去掉。
#classmethod, staticmethod
class my_class():
def __init__(self):
pass
@classmethod
def func1(cls):
print("this is func1")
@staticmethod
def func2():
print("this is func2")
def func3(self):
print("this is func3")
#func1有classmethod装饰,func2有staticmethod,func3没有进行任何装饰
my_class.func1()
my_class.func2()
my_class.func3()
this is func1
this is func2
Traceback (most recent call last):
File "C:/Users/admin/python-learning/python学习文件/python基础/CSDN.py", line 28, in <module>
my_class.func3()
TypeError: func3() missing 1 required positional argument: 'self'
上面对func1用了classmethod进行声明是一个类方法,func2用staticmethod声明是一个静态方法,它们都可以用 类名.方法名 进行直接调用,而不用创建实例对象;但是func3没有进行任何装饰,就不能直接用 类名.方法名 进行调用,所有还是会报错。
从上面可以看出方法用classmethod和staticmethod进行装饰后,都不用创建实例对象就可以直接调用类方法。但它们还是有些区别的,如下
- classmethod是需要cls参数的,cls和self一样,代表类本身,但是 cls不能调用实例对象的属性,即不能调用def __ init __ 下面的属性。可以通过 cls.类属性 或 cls.类方法 来调用类的属性和方法。
- staticmethod不需要self和cls参数,它注重的是类的静态变量,跟类的实例化对象没有关系,所以它 也不能调用类实例化对象的属性,即def __ init __ 下面的属性,而且只能通过 类名.类属性,类名.类方法 来调用类的属性和方法。
下面用个例子说明
#classmethod, staticmethod
class my_class():
__pwd = 123456
def __init__(self):
self.name = '老六'
@classmethod
def func1(cls):
#不能调用实例对象的属性,可以通过cls调用类的属性
print("this is func1")
print(cls.__pwd)
@staticmethod
def func2():
#不能调用实例对象的属性,只能调用类的属性
print("this is func2")
print(my_class.__pwd)
def func3(self):
#可以调用实例对象的属性,也可以调用类的属性
print("this is func3")
print(self.__pwd)
print(self.name)
#func1有classmethod装饰,func2有staticmethod,func3没有进行任何装饰
my_class.func1()
my_class.func2()
#需要创建实例对象才能调用func3
my_class().func3()
结果如下
>>>
this is func1
123456
this is func2
123456
this is func3
123456
老六
三 property
python中property一般有两个作用,如下
- 作为装饰器,@property 将类的方法转为只读的类属性
- property 重新实现一个属性的 getter 和 setter 方法
property作为装饰器使用,如下
#property
class my_class():
def __init__(self):
pass
@property
def func1(self):
print("this is func1")
def func2(self):
print("this is func2")
#有@property,转换成类属性
my_class().func1
#无@property,不会转换成类属性
print(my_class().func2)
结果
>>>
this is func1
<bound method my_class.func2 of <__main__.my_class object at 0x0000022E361C7148>>
可以看到,func1用 @property 进行了装饰,转换成了类属性,就可以像调用类属性一样调用该方法,而func2没有进行装饰,因而不能像调用类属性一样调用该方法。
下面@property 重新实现一个私有属性的 getter 和 setter 方法。
class E():
__name = '张三'
def __init__(self):
self.__age = 23
self.__luange = 'python'
def __method(self):
print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
if __name__ == '__main__':
e = E()
#访问
print(e.name)
#修改
print("修改前:", e.name)
e.name = '隔壁老王'
print("修改后:", e.name)
输出结果
>>>
张三
修改前: 张三
修改后: 隔壁老王
上面是首先把name方法送给propert装饰器进行装饰,然后调用装饰后的setter方法,即可实现对私有属性进行修改。
property更多的是用在对类私有属性方面的保护,更详细的可以参考这篇文章:Python面向对象之封装(三)