property、setter、deleter装饰器的使用

property装饰器

python的@property是python的一种装饰器,是用来修饰方法的。

作用:

我们可以使用@property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性被修改。

使用场景:

1.修饰方法,是方法可以像属性一样访问。

class DataSet(object):
  @property
  def method_with_property(self): ##含有@property
      return 15
  def method_without_property(self): ##不含@property
      return 15

l = DataSet()
# 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。
print(l.method_with_property) 
#没有加@property , 必须使用正常的调用方法的形式,即在后面加()
print(l.method_without_property())  

如果使用property进行修饰后,又在调用的时候,方法后面添加了(), 那么就会显示错误信息:TypeError: 'int' object is not callable,也就是说添加@property 后,这个方法就变成了一个属性,如果后面加入了(),那么就是当作函数来调用,而它却不是callable(可调用)的。

2.与所定义的属性配合使用,这样可以防止属性被修改。 

由于python进行属性的定义时,没办法设置私有属性,因此要通过@property的方法来进行设置。这样可以隐藏属性名,让用户进行使用的时候无法随意修改。

class DataSet(object):
    def __init__(self):
        self._images = 1
        self._labels = 2 #定义属性的名称
    @property
    def images(self): #方法加入@property后,这个方法相当于一个属性,这个属性可以让用户进行使用,而且用户有没办法随意修改。
        return self._images
    @property
    def labels(self):
        return self._labels
l = DataSet()
#用户进行属性调用的时候,直接调用images即可,而不用知道属性名_images,因此用户无法更改属性,从而保护了类的属性。
print(l.images) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。

setter装饰器

为了可以修改x,我们把x的值1写成实例属性self.num,

当然这个例子中外部也可以直接通过修改num的值来修改x的值,不过这个不要紧,因为只是为了方便理解,

实际使用中我们可以把self.num 写成私有属性,来保障不会被外部直接修改值,

写一个x属性同名方法,并且用x属性同名的setter装饰器(x.setter)来装饰同名方法x,然后在这个方法下实现对self.num的值的修改:

class Num:

    def __init__(self):
        self.num = 1
    @property
    def x(self):
        return self.num
    @x.setter
    def x(self, item):
        self.num = item
    @property
    def y(self):
        return 2
    def printf(self):
        print(f'{self.x}加{self.y}的和是:{self.x+self.y}')

a = Num()  # 把C实例化,命名为a
a.x = 2
a.printf()

deleter装饰器

同setter装饰器,不再详细说明,不同的地方在于被deleter装饰的同名x方法不接收参数,因为我们只是删除了self.num,不需要接收参数:

class Num:

    def __init__(self):
        self.num = 1

    @property
    def x(self):
        return self.num

    @x.setter
    def x(self, item):
        self.num = item

    @x.deleter
    def x(self):
        del self.num

    @property
    def y(self):
        return 2

    def printf(self):
        print(f'{self.x}加{self.y}的和是:{self.x+self.y}')

a = Num()  # 把C实例化,命名为a
a.x = 2
a.printf()
del a.x
print(a.x)

deleter装饰器装饰的方法就可以被使用del 来删除对应的属性,删除属性的操作我们就再同名方法x中进行了实现,

这样外部删除属性的方法也和删除一个属性的方法保持一致,同样保证了高可用性和可读性。

总结


使用property装饰器装饰的方法可以被上层以调用属性的方式来调用,类本身也可以,可以理解为property属性,也是一个属性;

使用property属性同名.setter装饰器装饰的同名方法,提供property=xx 的方法;

使用property属性同名.deleter装饰器装饰的同名方法,提供del xx的方法。

另外,重要的一点是既然我们已经使用property来代替实例属性,那自然我们是不希望外层可以直接修改实例属性的,

既然如此我们就最好不能使用上述例子中使用的self.num的命名方式来定义实例属性,而是使用私有属性的方式来定义(关于私有属性的知识点可以查看文章开头的相关知识点):

class Num:
    def __init__(self):
        self.__num = 1
    @property
    def x(self):
        return self.__num
    @x.setter
    def x(self, item):
        if isinstance(item, int):
            self.__num = item
        else:
            print('不要把非int类型赋值给x!!!')
    @x.deleter
    def x(self):
        if self.__num:
            del self.__num
        else:
            print('属性不存在')
    @property
    def y(self):
        return 2

    def printf(self):
        print(f'{self.x}加{self.y}的和是:{self.x+self.y}')

a = Num()  # 把C实例化,命名为a
a.x=2
a.printf()
a.__name = 3  # 不能直接访问私有属性,新建了一个属性
a.printf()

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值