Python高级用法之property

从其他语言转入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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值