从其他语言转入python的程序员,可能会习惯性的实现getter(获取类属性)和setter(类属性赋值)方法,以实现对类属性的操作。在python中,为了方便对于属性的操作,自带了@property修饰器。
property主要有两种使用场景:
- 将类方法转换为只读属性
- 重新实现一个属性的setter和getter方法,控制属性的访问和赋值
property主要有两种定义方式:
方式一:使用property函数,显示的将普通的set方法转换为属性set设置器
class PropertyDemo(object):
def __init__(self):
self._voltage = 0
def get_vol(self):
print("get voltage: {}".format(self._voltage))
return self._voltage
def set_vol(self, voltage):
self._voltage = voltage
print("set voltage: {}".format(self._voltage))
voltage = property(get_vol, set_vol)
vol_inst = PropertyDemo()
vol_inst.voltage = 11
data = vol_inst.voltage
print(data)
输出:
set voltage: 11
get voltage: 11
11
方法二:使用修饰符@property 修饰get方法
class PropertyDemo(object):
def __init__(self):
self._voltage = 0
@property
def voltage_new(self):
print("get voltage: {}".format(self._voltage))
return self._voltage
@voltage_new.setter
def voltage_new(self, voltage):
self._voltage = voltage
print("set voltage: {}".format(self._voltage))
vol_inst = PropertyDemo()
vol_inst.voltage_new = 11
data = vol_inst.voltage_new
print(data)
使用场景:
场景一:设置只读属性
class PropertyDemo(object):
def __init__(self):
self._voltage = 0
@property
def voltage_new(self):
print("get voltage: {}".format(self._voltage))
return self._voltage
vol_inst = PropertyDemo()
data = vol_inst.voltage_new
print(data)
vol_inst.voltage_new = 11
此种情况下未设置setter方法,属性赋值会抛出异常AttributeError: can't set attribute
场景二:重新实现一个属性的setter和getter方法,控制属性的访问和赋值
例1: 对属性的赋值检查
class Resistor(object):
def __init__(self, ohms):
self.current = 0
self.ohms = ohms
class VoltageResistor(Resistor):
def __init__(self, ohms):
super().__init__(ohms)
self._voltage = 1
@property
def voltage(self):
return self._voltage
@voltage.setter
def voltage(self, voltage):
if voltage > 10:
self._voltage = voltage
else:
raise ValueError("voltage must > 10")
r2 = VoltageResistor(1e3)
r2.voltage = 10
print(r2.voltage)
输出:
Traceback (most recent call last):
File "property.py", line 78, in <module>
r2.voltage = 10
File "property.py", line 43, in voltage
raise ValueError("voltage must > 10")
ValueError: voltage must > 10
例2: 对属性的初始化检查
class Resistor(object):
def __init__(self, voltage):
self.voltage = voltage
class VoltageResistor(Resistor):
def __init__(self, voltage):
super().__init__(voltage)
@property
def voltage(self):
return self._voltage
@voltage.setter
def voltage(self, voltage):
if voltage > 10:
self._voltage = voltage
else:
raise ValueError("voltage must > 10")
r2 = VoltageResistor(0)
r2.voltage = 111
print(r2.voltage)
输出:
Traceback (most recent call last):
File "property.py", line 80, in <module>
r2 = VoltageResistor(0)
File "property.py", line 35, in __init__
supeproperty.py", line 31, in __init__
self.voltage = voltage
File "property.py", line 46, in voltage
raise ValueError("voltage must > 10")
ValueError: voltage must > 10
例3: 控制对父类属性的访问修改
class Resistor(object):
def __init__(self, voltage):
self.voltage = voltage
class FixedResistance(Resistor):
def __init__(self, voltage):
super().__init__(voltage)
@property
def voltage(self):
print("getter")
return self._voltage
@voltage.setter
def voltage(self, voltage):
if hasattr(self, "_voltage"):
raise AttributeError("can not set attr")
self._voltage = voltage
r5 = FixedResistance(1e3)
data = r5.voltage
print(data)
r5.voltage = 2e3
print(r5.voltage)
输出:
Traceback (most recent call last):
getter
File "property.py", line 93, in <module>
1000.0
r5.voltage = 2e3
File "property.py", line 77, in voltage
raise AttributeError("can not set attr")
AttributeError: can not set attr