python三大装饰器
- @staticmethod(静态方法)、@classmethod(类方法)、@property(描述符)
@classmethod、@staticmethod
class Dog:
dogbook = {'黄色':30, '黑色':20, '白色':10} #类变量
def __init__(self, name, color, weight): #类属性
self.name = name
self.color = color
self.weight = weight
#实例方法:定义时,必须把self作为第一个参数,可以访问实例变量,只能通过实例名访问
def bark(self):
print(f'{self.name} 叫了起来')
#类方法:定义时,必须把类作为第一个参数,可以访问类变量,可以通过实例名或类名访问
@classmethod
def dog_num(cls):
num = 0
for v in cls.dogbook.values():
num = num + v
return num
#静态方法:不强制传入self或者cls,它对类和实例一无所知。不能访问类变量,也不能访问实例变量,可以通过实例名或类名访问
@staticmethod
def total_weights(dogs):
total = 0
for o in dogs:
total = total + o.weight
return total
print(f'共有{Dog.dog_num()} 条狗')
d1 = Dog('大黄', '黄色', 10)
d1.bark()
print(f'共有{d1.dog_num()} 条狗') #classmethod 可以访问全局变量
d2 = Dog('旺财', '黑色', 8)
d2.bark()
print(f'狗共重{Dog.total_weights([d1,d2])} 公斤') #staticmethod和对于类和实例一无所知,依然把他放在类里面,完全是因为它的逻辑和 类有关联,让代码看起来更加的整洁
@property应用
一、@property的应用,其功能1是可定义只读属性
举例:
class Person(object):
def __init__(self, name, age=18):
self.name = name
self._age = age
@property
def age(self):
return self._age
xm = Person('xiaoming')
print(xm.age)
#输出结果是 18
xm.age = 8
print(xm.age)
#结果报错,说明不能够赋值,因为它是只读属性
- 在python中定义只读属性非@property莫属,如果细心留意大部分源码,都跑不了@property的身影。而定义只读属性也很简单:以需要定义的属性为方法名(上例age属性定义为方法),其上装饰内置装饰器@property就ok了。
二、@property真正强大的是可以限制属性的定义。
举例:
class Person(object):
def __init__(self, name, age):
self.name = name
self.__age = 18
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if age < 18:
print('年龄必须大于18岁')
return
self.__age = age
return self.__age
xm = Person('xiaoming', 20)
print(xm.age)
xm.age = 20
print(xm.age)
xm.age = 15
print(xm.age)
- 这就是@property定义可访问属性的语法,即仍旧以属性名为方法名,并在方法名上增加@属性.setter就行了