88.@property装饰器
@property
可以将一个方法的调用方式变成“属性调用”
。下面是一个简单的示例,让大 家体会一下这种转变:
也就是访问的时候 无需加括号
执行函数。
一般用来给我们的属性增加 get
# 简单测试 @property
class Employee:
@property
def salary(self):
print('salary run')
return 10000
emp1 = Employee()
# emp1.salary()# 这是方法的 调用方法
print(emp1.salary) # 这是 属性的调用方法
# emp1.salary = 20000 # 这里会报错 ,不能设置 属性 ,只能使用
# 需要编写一个 函数 使用setter
# 或者使用函数 来设置 属性。
# 普通版本
class Employee:
def __init__(self, name, salary):
self.__name = name
self.__salary = salary
def salary(self):
return self.__salary
def set_salary(self, salary):
if 1000 < salary < 50000:
self.__salary = salary
else:
print('录入错误!薪水在1000*-50000之间')
# 不写装饰器 函数名字同名就会被覆盖
In [37]: emp1 = Employee('onepis', 30000)
In [38]: emp1.salary
# print(emp1.salary)
# 私有之后不能直接访问 会报错 当然我们定义了一个 salary 方法。 所以 这里不报错, 但是返回的是一个 方法函数 对象。
Out[38]: <bound method Employee.salary of <__main__.Employee object at 0x00D9BDD0>>
In [39]: emp1.salary()
Out[39]: 30000
In [40]: emp1.set_salary(-2000) # 无法直接赋值。 除非使用装饰器。
录入错误!薪水在1000*-50000之间
# 用 @property做上面 普通版的 事情
class Employee:
def __init__(self, name, salary):
self.__name = name
self.__salary = salary
@property
def salary(self):
return self.__salary
@salary.setter # xxxx.setter 就是自己取的名字 setter 固定写法不能改
def salary(self, salary):
if 1000 < salary < 50000:
self.__salary = salary
else:
print('录入错误!薪水在1000*-50000之间')
In [23]: emp1 = Employee('onepis', 30000)
In [24]: emp1.salary
Out[24]: 30000
In [25]: emp1.salary = 2000
In [26]: emp1.salary
Out[26]: 2000
In [27]: emp1.salary = -2000
录入错误!薪水在1000*-50000之间
In [33]: del emp1.salary # 我们没有定义 deleter 函数 所以报错
----------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-33-a009c28d3cb2> in <module>
----> 1 del emp1.salary
AttributeError: can't delete attribute
# 普通版本 就需要 以 函数的方式 传递参数进去。
# emp1.set_salary(-2000) 类似这样的写法
In [28]: emp1.__dict__ # 我们自己定义的属性
Out[28]: {'_Employee__name': 'onepis', '_Employee__salary': 2000}
In [29]: dir(emp1)
Out[29]: # 所有的属性 最后面有一个 salary 就是我们定义的 装饰器 写的属性。可以返回 私有的salary 以及 设置 salary 属性。
['_Employee__name',
'_Employee__salary',
'__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'salary']
普通的创建属性的方式
class C:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
# 使用property类创建 property 属性
x = property(getx, setx, delx, "I'm the 'x' property.")
使用装饰器创建 属性(增删查改都实现了)
class C:
def __init__(self):
self._x = None
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x