python中基于descriptor的一些概念(下)
@python中基于descriptor的一些概念(下)
3. Descriptor介绍
3.1 Descriptor代码示例
"""创建一个Descriptor类,用来打印出访问它的操作信息
"""
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
print 'Retrieving', self.name
return self.val
def __set__(self, obj, val):
print 'Updating' , self.name
self.val = val
#使用Descriptor
class MyClass(object):
#生成一个Descriptor实例,赋值给类MyClass的x属性
x = RevealAccess(10, 'var "x"')
y = 5 #普通类属性

3.2 定义
3.3 Descriptor Protocol(协议)
3.4 Descriptor调用方法
"模拟type.__getattribute__()实现"
#通过默认方式查找到目标
v = object.__getattribute__(self, key)
#如果目标属性含有__get__方法,则表示它是一个descriptor
if hasattr(v, '__get__'):
#优先使用descriptor中定义的方法返回值
return v.__get__(None, self)
#如果不是descriptor,就按默认的方式返回
return v
- descriptor是被__getattribute__方法调用的。
- 重写__getattribute__方法,会阻止自动的descriptor调用,必要时需要你自己加上去。
- __getattribute__方法只在新式类和新式实例中有用。
- object.__getattribute__和class.__getattribute__会用不一样的方式调用__get__
- data descriptors总是覆盖instance dictionary
- non-data descriptors有可能被instance dictionary覆盖
4. 基于Descriptor实现的功能
- Property
- 绑定和非绑定方法
- 静态方法
- 类方法
- super
4.1 property
def getX(self):
print 'get x'
return self.__x
def setX(self, value):
print 'set x', value
self.__x = value
def delX(self):
print 'del x'
del self.__x
x = property(getX, setX, delX, "This is 'x' property.")
def __init__(self, width, heigth):
self.width = width
self.heigth = heigth
def getArea(self):
return self.width * self.heigth
area = property(getArea, doc='area of the rectangle')
"模拟在Objects/descrobject.c文件中的PyProperty_Type()函数"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError, "unreadable attribute"
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError, "can't set attribute"
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError, "can't delete attribute"
self.fdel(obj)
4.2 函数和方法,绑定与非绑定
. . .
def __get__(self, obj, objtype=None):
"模拟Objects/funcobject.c文件中的func_descr_get()"
return types.MethodType(self, obj, objtype)

4.3 super

def __init__(self, type, obj=None):
self.__type__ = type
self.__obj__ = obj
def __get__(self, obj, type=None):
if self.__obj__ is None and obj is not None:
return Super(self.__type__, obj)
else:
return self
def __getattr__(self, attr):
if isinstance(self.__obj__, self.__type__):
starttype = self.__obj__.__class__
else:
starttype = self.__obj__
mro = iter(starttype.__mro__)
for cls in mro:
if cls is self.__type__:
break
# Note: mro is an iterator, so the second loop
# picks up where the first one left off!
for cls in mro:
if attr in cls.__dict__:
x = cls.__dict__[attr]
if hasattr(x, "__get__"):
x = x.__get__(self.__obj__)
return x
raise AttributeError, attr
5. 结尾
python中基于descriptor的一些概念(下)的更多相关文章
- python中基于descriptor的一些概念
python中基于descriptor的一些概念(上) 1. 前言 2. 新式类与经典类 2.1 内置的object对象 2.2 类的方法 2.2.1 静态方法 2.2.2 类方法 2.3 新式类(n ...
- python中基于descriptor的一些概念(上)
@python中基于descriptor的一些概念(上) python中基于descriptor的一些概念(上) 1. 前言 2. 新式类与经典类 2.1 内置的object对象 2.2 类的方法 2 ...
- python 中关于descriptor的一些知识问题
这个问题从早上日常扫segmentfault上问题开始 有个问题是 class C(object): @classmethod def m(): pass m()是类方法,调用代码如下: C.m() ...
- python中的 descriptor
学好和用好python, descriptor是必须跨越过去的一个点,现在虽然Python书籍花样百出,但是似乎都是在介绍一些Python库而已,对Python语言本身的关注很少,或者即使关注了,但是 ...
- 轻松理解python中的闭包和装饰器 (下)
在 上篇 我们讲了python将函数做为返回值和闭包的概念,下面我们继续讲解函数做参数和装饰器,这个功能相当方便实用,可以极大地简化代码,就让我们go on吧! 能接受函数做参数的函数我们称之为高阶函 ...
- python中模块与包的概念
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护.为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多 ...
- python中模块和包的概念
1.模块 一个.py文件就是一个模块.这个文件的名字是:模块名.py.由此可见在python中,文件名和模块名的差别只是有没有后缀.有后缀是文件名,没有后缀是模块名. 每个文件(每个模块)都是一个独立 ...
- (数据科学学习手札136)Python中基于joblib实现极简并行计算加速
本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 我们在日常使用Python进行各种数据计算 ...
- python中基于tcp协议的通信(数据传输)
tcp协议:流式协议(以数据流的形式通信传输).安全协议(收发信息都需收到确认信息才能完成收发,是一种双向通道的通信) tcp协议在OSI七层协议中属于传输层,它上承用户层的数据收发,下启网络层.数据 ...
随机推荐
- 撩课-Web大前端每天5道面试题-Day5
1.写一个深度克隆方法(es5)? /** * 深拷贝 * @param {object}fromObj 拷贝的对象 * @param {object}toObj 目标对象 */ function d ...
- 武汉邀请赛 Key Logger 双向链表
Key Logger Time Limit: 3000ms Case Time Limit: 3000ms Memory Limit: 65536KB 64-bit integer IO form ...
- C# 进程通信-命名管道
之前看wcf服务的时候看到wcf有支持管道通信协议,之前不知道,最近刚好有用到这个,这里写个简单实例 .net有已经封装好的pip通信的对象NamedPipeServerStream 和NamedPi ...
- android中利用HttpURLConnection进行Get、Post和Session读取页面。
直接上代码,调用的时候要放在线程中. package slj.getsms; import java.io.BufferedReader; import java.io.InputStreamRead ...
- 【数据库】10.0 MySQL常用语句(一)
显示数据库语句: SHOW DATABASES 只是显示数据库的名字 显示数据库创建语句: SHOW CREATE DATABASE db_name 数据库删除语句: DROP DATABASE ...
- Html5 锚 <a>的页内跳转, name=abc herf=#abc
锚点是网页制作中超级链接的一种,又叫命名锚记.命名锚记像一个迅速定位器一样是一种页面内的超级链接,运用相当普遍. 英文名:anchor 使用命名锚记可以在文档中设置标记,这些标记通常放在文档的特定主题 ...
- HTML表单相关
表单:<input type="text" name="" value="" size="显示字符数" maxle ...
- OSMC Vs. OpenELEC Vs. LibreELEC – Kodi Operating System Comparison
Kodi's two slim-and-trim kid brothers LibreELEC and OpenELEC were once great solutions for getting t ...
- unity震动效果
using System.Collections; using System.Collections.Generic; using UnityEngine; //思想:在短时间内在规定圆内随机震动对象 ...
- GPU 编程语言 Harlan
Harlan 是一个声明式的.GPU 领域特定的编程语言.目前主要是用于技术实现和优化的测试用途.该语言很小,用于简化浏览新的分析器和优化. 支持的操作系统: Mac OS X 10.6 (Snow ...