python基础===装饰器@property 的扩展
- 以下来自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.xwill invoke the getter,c.x = valuewill invoke the setter anddel c.xthe 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
property()as a decorator:class Parrot:
def __init__(self):
self._voltage = 100000 @property
def voltage(self):
"""Get the current voltage."""
return self._voltageThe
@propertydecorator turns thevoltage()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, anddeletermethods 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._xThis code is exactly equivalent to the first example. Be sure to give the additional functions the same name as the original property (
xin this case.)The returned property object also has the attributes
fget,fset, andfdelcorresponding 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 = score s = stu("Botoo")
#s.set_score(100) #score must be an integer~
#s.set_score("dasda") #score must between 0~100
s.set_score(98)
print(s.get_score()) #
这种使用 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 = 50 print(S1.score) #
S1.score = 500 #ValueError: 分数必须0-100之间
第一个score(self)是get方法,用@property装饰,第二个score(self, score)是set方法,用@score.setter装饰,@score.setter是前一个@property装饰后的副产品。
在子类中扩展一个property可能会引起很多不易察觉的问题, 因为一个property其实是 getter、setter 和 deleter 方法的集合,而不是单个方法。 因此,当你扩展一个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
python基础===装饰器@property 的扩展的更多相关文章
- python基础——装饰器
python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...
- python基础—装饰器
python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...
- python 基础——装饰器
python 的装饰器,其实用到了以下几个语言特点: 1. 一切皆对象 2. 函数可以嵌套定义 3. 闭包,可以延长变量作用域 4. *args 和 **kwargs 可变参数 第1点,一切皆对象,包 ...
- day5学python 基础+装饰器内容
基础+装饰器内容 递归特性# 1.必须有一个明确的结束条件# 2.每次进入更深一层递归时,问题规模相比上次递归应有所减少# 3.递归效率不高 def run(n): print(n) if int(n ...
- python基础 (装饰器,内置函数)
https://docs.python.org/zh-cn/3.7/library/functions.html 1.闭包回顾 在学习装饰器之前,可以先复习一下什么是闭包? 在嵌套函数内部的函数可以使 ...
- <Python基础>装饰器的基本原理
1.装饰器 所谓装饰器一般是对已经使用(上线)的函数增加功能. 但是因为一般的大公司的严格按照开放封闭原则(对扩展是开放的,对修改是封闭的),不会让你修改原本的函数. 装饰器就是在不改变原本的函数且不 ...
- Python自动化 【第四篇】:Python基础-装饰器 生成器 迭代器 Json & pickle
目录: 装饰器 生成器 迭代器 Json & pickle 数据序列化 软件目录结构规范 1. Python装饰器 装饰器:本质是函数,(功能是装饰其它函数)就是为其他函数添加附加功能 原则: ...
- python基础-装饰器,生成器和迭代器
学习内容 1.装饰器 2.生成器 3.迭代器 4.软件目录结构规范 一:装饰器(decorator) 1.装饰器定义:本质就是函数,用来装饰其他函数,即为其他函数添加附加功能. 2.装饰器原则:1)不 ...
- python基础-装饰器
一.什么是装饰器 装饰器本质就是函数,功能是为其他函数附加功能 二.装饰器遵循的原则 1.不修改被修饰函数的源代码 2.不修改被修饰函数的调用方式 三.实现装饰器的知识储备 装饰器=高阶函数+函数嵌套 ...
随机推荐
- P1491 集合位置
题目描述 每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要玩的痛快.还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法 ...
- BZOJ4755: [JSOI2016]扭动的回文串——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4755 JYY有两个长度均为N的字符串A和B. 一个“扭动字符串S(i,j,k)由A中的第i个字符到 ...
- BZOJ1856:[SCOI2010]字符串——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1856 lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还 ...
- BZOJ4009 & 洛谷3242 & LOJ2113:[HNOI2015]接水果——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4009 https://www.luogu.org/problemnew/show/P3242 ht ...
- BZOJ3110:[ZJOI2013]K大数查询——题解
+++++++++++++++++++++++++++++++++++++++++++ +本文作者:luyouqi233. + +欢迎访问我的博客:http://www.cnblogs.com/luy ...
- [Leetcode] sqrt 开根号
Implementint sqrt(int x). Compute and return the square root of x. 题意:求根号下x 的值 思路:使用二分搜索.先定义x平方根的取值区 ...
- Promise用法总结
1. Promise的状态 Promise对象有三个状态: 1. 进行中(pending) 2. 成功(resolved) 3. 失败(rejected) 2. 生成一个Promise对象 ...
- bzoj2724: [Violet 6]蒲公英(离散化+分块)
我好弱啊..这题调了2天QwQ 题目大意:给定一个长度为n(n<=40000)的序列,m(m<=50000)次询问l~r之间出现次数最多的数.(区间众数) 这题如果用主席树就可以不用处理一 ...
- Codeforces Round #343 (Div. 2) A
A. Far Relative’s Birthday Cake time limit per test 1 second memory limit per test 256 megabytes inp ...
- udhcpd源码分析4--获取client报文及发包动作
1:重要的结构体 获取的报文是UDP的payload部分,结构体struct dhcpMessage描述了dhcp报文的结构. /* packet.h */ struct dhcpMessage { ...