博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python基础===装饰器@property 的扩展
阅读量:6756 次
发布时间:2019-06-26

本文共 3851 字,大约阅读时间需要 12 分钟。

 

以下来自Python 3.6.0 Document:
class property(fget=None, fset=None, fdel=None, doc=None)

Return a property attribute.

fget is a function for getting an attribute value. fset is a function for setting an attribute value. fdel is a function for deleting an attribute value. And doc creates a docstring for the attribute.

A typical use is to define a managed attribute x:

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    x = property(getx, setx, delx, "I'm the 'x' property.")

 

If c is an instance of C, c.x will invoke the getter, c.x = value will invoke the setter and del c.x the deleter.

If given, doc will be the docstring of the property attribute. Otherwise, the property will copy fget‘s docstring (if it exists). This makes it possible to create read-only properties easily using as a :

class Parrot:    def __init__(self):        self._voltage = 100000    @property    def voltage(self):        """Get the current voltage."""        return self._voltage

 

The @property decorator turns the voltage() method into a “getter” for a read-only attribute with the same name, and it sets the docstring for voltage to “Get the current voltage.”

A property object has getter, setter, and deleter methods usable as decorators that create a copy of the property with the corresponding accessor function set to the decorated function. This is best explained with an example:

class C:    def __init__(self):        self._x = None    @property    def x(self):        """I'm the 'x' property."""        return self._x    @x.setter    def x(self, value):        self._x = value    @x.deleter    def x(self):        del self._x

 

This code is exactly equivalent to the first example. Be sure to give the additional functions the same name as the original property (x in this case.)

The returned property object also has the attributes fget, fset, and fdel corresponding to the constructor arguments.

Changed in version 3.5: The docstrings of property objects are now writeable.

 

 

先看一段代码:

 

class stu:    def __init__(self,name):        self.name = name    def get_score(self):        return self.score    def set_score(self, score):        if not isinstance(score, int):            raise ValueError("score must be an integer~")        if score>100 or score<0:            raise ValueError("score must between 0~100")        self.score = scores = stu("Botoo")#s.set_score(100)            #score must be an integer~#s.set_score("dasda")    #score must between 0~100s.set_score(98)print(s.get_score())        #98

 

这种使用 get/set 方法来封装对一个属性的访问在许多面向对象编程的语言中都很常见。

但是写 s.get_score() 和 s.set_score() 没有直接写 s.score 来得直接。

因为Python支持高阶函数,可以用装饰器函数把 get/set 方法“装饰”成属性调用:

 

再比较:

class Student:    def __init__(self,name):        self.name = name    @property    def score(self):        return self._score    @score.setter    def score(self,value):        if not isinstance(value, int):            raise ValueError('分数必须是整数才行呐')        if value < 0 or value > 100:            raise ValueError('分数必须0-100之间')        self._score = value        S1 = Student("botoo")S1.score = 50print(S1.score)         #50S1.score = 500         #ValueError: 分数必须0-100之间

 

第一个score(self)是get方法,用@property装饰,第二个score(self, score)是set方法,用@score.setter装饰,@score.setter是前一个@property装饰后的副产品。

在子类中扩展一个property可能会引起很多不易察觉的问题, 因为一个property其实是 gettersetterdeleter 方法的集合,而不是单个方法。 因此,当你扩展一个property的时候,你需要先确定你是否要重新定义所有的方法还是说只修改其中某一个。

  • 只有@property表示只读。
  • 同时有@property和@x.setter表示可读可写。
  • 同时有@property和@x.setter和@x.deleter表示可读可写可删除。

 

参考:

http://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p08_extending_property_in_subclass.html

https://blog.csdn.net/u013205877/article/details/77804137

https://blog.csdn.net/sxingming/article/details/52916249

转载于:https://www.cnblogs.com/botoo/p/8883944.html

你可能感兴趣的文章
Wndows server 2008 R2 总是卡住 “Applying computer settings”
查看>>
序列化解决方案,就是采用二进制通信协议(数据报文格式)
查看>>
如何使用Spring优雅地处理REST异常
查看>>
原生JS上传图片(FormData,可预览,一次多图)
查看>>
讲讲Java溢出JVM爆炸的几种方式及自救方法
查看>>
[HAOI2015]T2
查看>>
bzoj 1293: [SCOI2009]生日礼物
查看>>
RadioButton+Fragment 实现导航栏碰到的一些常见问题
查看>>
sudo 出现unable to resolve host 解决方法
查看>>
「小程序JAVA实战」微信开发者工具helloworld(三)
查看>>
文档相关命令-cat命令查看一个文件
查看>>
Java的版本、特性以及开发工具
查看>>
版本控制报告:回答问题
查看>>
巴什博弈------最少取件数 不是1的情况下 hdu---2897
查看>>
因修改/etc/sudoers权限导致sudo和su不能使用的解决方法
查看>>
AT3576 Popping Balls
查看>>
springboot入门_多数据源
查看>>
如果一个游戏上面加一个透明层,js能不能实现 点击透明层的任意点 而正常玩游戏...
查看>>
获取cpu真实型号
查看>>
5月8日团队博客
查看>>