自学内容网 自学内容网

python-@property 和setter属性

T

一个装饰器,使得类中方法像属性一样被使用。

W

这是原本的类及其属性的访问

class Person():

    def __init__(self, firstname:str, lastname:str):
        self.first = firstname
        self.last = lastname
        self.full_name = self.first + ' '+ self.last

    def printFullname(self):
        return f"Full name is {self.full_name}."
    
person = Person('Jack','Swingming')
print(f"{person.first=}")
print(f"{person.last=}")
print(f"{person.full_name=}")
print(f"{person.printFullname()=}")
person.first='Jack'
person.last='Swingming'
person.full_name='Jack Swingming'
person.printFullname()='Full name is Jack Swingming.'

但是如果我修改了self.first,我希望full_name 一起修改,该如何做呢?

这里就用函数可以实现

class Person():

    def __init__(self, firstname:str, lastname:str):
        self.first = firstname
        self.last = lastname
    def full_name(self):
        return self.first + ' '+ self.last

    def printFullname(self):
        return f"Full name is {self.full_name()}."
    
person = Person('Jack','Swingming')
print(f"{person.first=}")
print(f"{person.last=}")
print(f"{person.full_name()=}")
print(f"{person.printFullname()=}")
person.first = 'Donminic'
print(f"{person.full_name()=}")
print(f"{person.printFullname()=}")

但是这样改变了原有的调用方法,这时候可能会影响其他人的开发,那么该如何在即不改变原有调用方法,也能实现属性更改呢? 这时候就用到了@property .

class Person():

    def __init__(self, firstname:str, lastname:str):
        self.first = firstname
        self.last = lastname
    @property
    def full_name(self):
        return self.first + ' '+ self.last

    def printFullname(self):
        return f"Full name is {self.full_name}."
    
person = Person('Jack','Swingming')
print(f"{person.first=}")
print(f"{person.last=}")
print(f"{person.full_name=}")
print(f"{person.printFullname()=}")
person.first = 'Donminic'
print(f"{person.full_name=}")
print(f"{person.printFullname()=}")

但是呢我又想通过修改full_name 修改的同时修改last或者first呢?

这就得用到setter方法 了,每当为full_name属性设置的时候,对应变量也随之改变。

规则

  • 方法定义添加@{methodname}.setter装饰器
  • setter 方法需要和@property 修饰的方法具有相同的名字
  • 需要传入修改参数,也就是full_name
class Person():

    def __init__(self, firstname:str, lastname:str):
        self.first = firstname
        self.last = lastname
    @property
    def full_name(self):
        return self.first + ' '+ self.last
    @full_name.setter
    def full_name(self,fullname:str):
        self.first,self.last = fullname.split() # split()默认以空格为分隔符
        

    def printFullname(self):
        return f"Full name is {self.full_name}."
    
person = Person('Jack','Swingming')
print(f"{person.first=}")
print(f"{person.last=}")
print(f"{person.full_name=}")
print(f"{person.printFullname()=}")
print()
person.first = 'Donminic'
person.last = 'Long'
print(f"{person.full_name=}")
print(f"{person.printFullname()=}")
print(f"{person.first=}")
print(f"{person.last=}")
person.first='Jack'
person.last='Swingming'
person.full_name='Jack Swingming'
person.printFullname()='Full name is Jack Swingming.'

person.full_name='Donminic Long'
person.printFullname()='Full name is Donminic Long.'
person.first='Donminic'
person.last='Long'

总结

当属性与其他属性关联的时候,可以使用@property来进行装饰,使其具备兼容属性,方便开发。另外一方面,可以控制对属性的修改,确保数据的安全性。如下面的代码执行就会报错

class MyClass:
    def __init__(self):
        self._value = 0

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, new_value):
        if new_value < 0:
            raise ValueError("Value must be non-negative")
        self._value = new_value
my_cl = MyClass()
my_cl.value = -1  

Ref

https://zhuanlan.zhihu.com/p/366156798


原文地址:https://blog.csdn.net/qq_37087723/article/details/144406620

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!