手动实现property装饰器
首先,property装饰器是通过数据描述符实现的。用法很简单,大家应该都知道,这里就不细说了。
这里主要分析一下property是如何通过描述符实现的。
class Property:
def __init__(self, fget):
self.fget = fget # 为实例增加方法,这里的方法是未绑定实例的,不会自动传入实例self
self.fset = None # 同上,未绑定实例
def __get__(self, instance, owner):
if instance is not None:
return self.fget(instance) # 调用原方法,传入实例self
return self
def __set__(self, instance, value):
self.fset(instance, value) # 调用原方法,传入实例self和value
def setter(self, func):
self.fset = func # 更新属性
return self
class A:
def __init__(self, data):
self._data = data
@Property # data = Property(data) 描述符实例
def data(self):
return self._data
@data.setter # data = data.setter(data) 更新属性,并返回描述符实例
def data(self, value):
self._data = value
访问
a = A(100)
print(a.data) # 访问描述符实例,调用__get__()方法
# 100
执行过程如下:
1. 在装饰器中,data变量指向Property(func)描述符实例
2. 原data()函数被赋值给fget变量
3. a.data就是访问描述符实例,触发调用__get__()方法
4. 最后,调用fget()也就是原data()方法,并传入owner class的实例,亦即调用data(self)
赋值
a.data = 200 # 访问描述符实例,调用__set__()方法
print(a.data) # 访问描述符实例,调用__get__()方法
# 200
执行过程如下:
1. 在装饰器中,data变量指向data.setter(func)描述符实例。注意,后面的data是__get__()方法返回的描述符实例
2. 原data()函数被赋值给fset变量
3. 赋值操作触发调用__set__方法
4. 最后,调用fset也就是原data()方法,并传入owner class的实例和要赋的值,亦即调用data(self, value)
这里涉及到装饰器,需要对装饰器和面向对象有足够的了解才能弄明白当中的变量传递,希望你不会被挡住。
参考:
https://docs.python.org/3/library/functions.html#property
手动实现property装饰器的更多相关文章
- 浅尝装饰器--property装饰器
[写在前面] 本帖归属于装饰器单元的学习,可以点击关键词'装饰器'查看其他博文讲解 [正文部分] property属性:将类方法用类属性的形式进行调用 class Good: def __init__ ...
- Python的property装饰器的基本用法
Python的@property装饰器用来把一个类的方法变成类的属性调用,然后@property本身又创建了另一个装饰器,用一个方法给属性赋值.下面是在类中使用了@property后,设置类的读写属性 ...
- 面向对象之组合、封装、多态、property装饰器
概要: 组合 封装 property装饰器 多态 Python推崇鸭子类型:解耦合,统一标准(不用继承) 1. 组合 继承:会传递给子类强制属性 组合:解耦合,减少占用内存.如:正常继承,如果一个班级 ...
- import导入模块,==和is,浅拷贝和深拷贝,进制转换,位运算,私有化,property装饰器
'''import导入模块'''import sysprint(sys.path) sys.path.append('D://ASoft/Python/PycharmProjects')import ...
- property装饰器
# 需要了解的property的用法 class People: def __init__(self,name): self.__name=name @property def name(self): ...
- 组合,多态与多态性,封装以及property装饰器介绍
一:组合: 什么是组合:组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象. 为何要用组合:通过为某一个对象添加属性(属性的值是另外一个类的对象)的方式,可以间接地将两个类关联/整合/组合 ...
- Python10/24--组合/封装/property装饰器/多态
组合的应用: 1. 什么是组合 一个对象的属性是来自于另外一个类的对象,称之为组合 2. 为何用组合 组合也是用来解决类与类代码冗余的问题 3. 如何用组合 '''class Foo: aaa=111 ...
- PYTHON-组合 封装 多态 property装饰器
# 组合'''软件重用的重要方式除了继承之外还有另外一种方式,即:组合组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合 1. 什么是组合 一个对象的属性是来自于另外一个类的对象,称之 ...
- [转载]Python使用@property装饰器--getter和setter方法变成属性
原贴:为什么Python不需要getter和setter getter 和 setter在java中被广泛使用.一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和sette ...
随机推荐
- Roslyn入门(一)-C#语法分析
演示环境 Visual Studio 2017 .NET Compiler Platform SDK 简介 今天,Visual Basic和C#编译器是黑盒子:输入文本然后输出字节,编译管道的中间阶段 ...
- C#使用FFMPEG推流,并且获取流保存在本地,随时取媒体进行播放!
最近开发了基于C#的推流器一直不大理想,终于在不懈努力之后研究了一点成果,这边做个笔记:本文着重在于讲解下如何使用ffmpeg进行简单的推流,看似简单几行代码没有官方的文档很吃力.并获取流的源代码:如 ...
- Appium Studio 初体验(windows做ios自动化,录制appium脚本)
偶然的机会遇到了这个工具——Appium Studio, 在官网是这么解释的 Get your Appium testing projects going within minutesInstall ...
- iphone忘记锁屏密码却记得appleID密码的不保存数据的刷机办法
请注意看清题目再看本文,另外一切后果博主不负任何责任.操作实现环境:原装数据线,拔掉sim卡昨天,iPhone6sp忘记密码被锁定,尝试通过找回手机抹除手机功能后,提示需要手机接入互联网才能实现,而我 ...
- 使用Zabbix服务端本地邮箱账号发送报警邮件及指定报警邮件操作记录
邮件报警有两种情况:1)Zabbix服务端只是单纯的发送报警邮件到指定邮箱,发送报警邮件的这个邮箱账号是Zabbix服务端的本地邮箱账号(例如:root@localhost.localdomain), ...
- Lotto HDU
链接 [http://acm.hdu.edu.cn/showproblem.php?pid=1342] 题意 分析 DFS 代码 #include<cstdio> #include< ...
- 个人博客作业-Week2 (代码规范, 代码复审)
代码规范: 1.这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 编码规范它包含了代码格式,还包括了编码风格和其他规范,通常涉及:缩进.空格使用.Tab使用 注释. ...
- 第二次作业:Git的安装与使用
---恢复内容开始--- 本次作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2103 1.首先安装git bash软件, ...
- TitleLayout——一个Android轻松实现通用、标准、支持沉浸式状态栏的标题栏库
TitleLayout 多功能.通用的.可在布局或者使用Java代码实现标题栏:支持沉浸式状态栏,支持左侧返回按钮(不需要手动实现页面返回),左侧支持图片+文字.图片.文字:右侧支持图片.文字等. 堆 ...
- ACL访问控制
/etc/squid/squid.conf 定义语法: acl aclname acltype string acl aclname acltype "file" s ...