Python中的描述符是一个相对底层的概念

descriptor

Any object which defines the methods get(), set(), or delete(). When a class attribute is a descriptor, its special binding behavior is triggered upon attribute lookup. Normally, using a.b to get, set or delete an attribute looks up the object named b in the class dictionary for a, but if b is a descriptor, the respective descriptor method gets called. Understanding descriptors is a key to a deep understanding of Python because they are the basis for many features including functions, methods, properties, class methods, static methods, and reference to super classes. For more information about descriptors’ methods, see Implementing Descriptors.

描述符

任何实现了__get__(), __set__(), 或者 __delete__()方法的对象就是描述符。一个class的属性是一个描述符的时候,对这个属性的访问会触发特定的绑定行为。一般的我们使用a.b的方式访问,修改和删除属性,它通过查找class的字典来访问属性b,当时如果b是一个描述符,那么get,set和delete相关的描述符方法会被调用。理解描述符是深入理解python的关键,因为描述符是很多特性实现的基础,比如:方法,函数,属性,类方法,静态方法还有对父类方法的引用。详细的说明请看描述符的实现。--CooMark译

极客学院 - 描述符

Python方法绑定——Unbound/Bound method object的一些梳理

http://www.it165.net/pro/html/201406/15171.html - 最后总结的很好

在说描述符之前,先看一小段代码:

class Foo(object):
"""docstring for Foo""" def __init__(self, arg=''):
super(Foo, self).__init__()
self.arg = arg def foo(self):
print(self)
print('foo:', 123) print(Foo.foo) print(Foo().foo) print(Foo.foo.__get__) # 输出
# <function Foo.foo at 0x00550738>
# <bound method Foo.foo of <__main__.Foo object at 0x0054DB10>>
# <method-wrapper '__get__' of function object at 0x00550738>

主要想说的是这个__get__,他是一个method-wrapper。每次调用一个方法,其实都是调用这个__get__构造的method对象。我们定义的方法其实都是descriptor,它通过__get__控制了对相应method的访问

def __get__(self, instance, owner)
Foo.foo -- Foo.__dict__['foo'].__get__(None,Foo) # 隐式传递的self是Foo class对象, 一切皆对象,class在模块级别中也有instance

下面三种方式的调用输出的结果是一样的,这个None咋来的呢?,有一点可以确认:self都是class对象实例

# 两种访问方式是一样的
print(Foo.foo.__get__(Foo(), Foo)())
print(Foo.__dict__['foo'].__get__(Foo(), Foo)()) c = Foo()
print(Foo.foo.__get__(c, Foo)()) # <__main__.Foo object at 0x0032DB10>
# foo: 123
# None
# <__main__.Foo object at 0x0032DB10>
# foo: 123
# None
# <__main__.Foo object at 0x0032DB70>
# foo: 123
# None

再说说bound method和unbound method

区分依据就是是否给method绑定了实例对象,也就是调用的时候是否会隐式传递self参数

print(Foo.foo)
# 当时3.0之后不再叫unbound method,因为定义为function更贴切
# <function Foo.foo at 0x006406F0> print(Foo().foo)
# <bound method Foo.foo of <__main__.Foo object at 0x0063DB30>>

描述符

我们定义的属性,方法其实都是描述符,只不过我们习以为常,而没有刻意的去了解背后的机制

class Bar(object):
"""docstring for Bar"""
_name = 'Mark Xiao' def __init__(self, arg=''):
super(Bar, self).__init__()
self.arg = arg
self._name = 'CooMark' def _get_name(self):
return self._name def _set_name(self, value):
self._name = value def _del_name(self):
del self._name name = property(_get_name, _set_name, _del_name, 'description of property name') print(Bar.name)
print(Bar().name) # <property object at 0x004FBAE0>
# CooMark

描述符协议:

__get__(self, instance, owner) --> return value
__set__(self, instance, value)
__delete__(self, instance)

描述符对象以类型 (owner class) 成员的方式出现,且最少要实现一个协议方法。最常见的描述符有 property、staticmethod、classsmethod。访问描述符类型成员时,解释器会自动调用与行为相对应的协议方法。

  1. 实现 get 和 set 方法,称为 data descriptor。
  2. 仅有 get 方法的,称为 non-data descriptor。
  3. get 对 owner_class、owner_instance 访问有效。
  4. set、delete 仅对 owner_instance 访问有效。

instance method, class method, static method

实例方法bound到instance

类方法bound到class

静态方法没有绑定,仅仅是个方法

总结

描述符是一种协议,实现了相应的描述符方法便会有相应的描述符行为,property就是一个特定的描述符类型,我们可以自己实现类似的功能

python描述符理解的更多相关文章

  1. 杂项之python描述符协议

    杂项之python描述符协议 本节内容 由来 描述符协议概念 类的静态方法及类方法实现原理 类作为装饰器使用 1. 由来 闲来无事去看了看django中的内置分页方法,发现里面用到了类作为装饰器来使用 ...

  2. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  3. 【转载】Python 描述符简介

    来源:Alex Starostin 链接:www.ibm.com/developerworks/cn/opensource/os-pythondescriptors/ 关于Python@修饰符的文章可 ...

  4. Python描述符 (descriptor) 详解

    1.什么是描述符? python描述符是一个“绑定行为”的对象属性,在描述符协议中,它可以通过方法重写属性的访问.这些方法有 __get__(), __set__(), 和__delete__().如 ...

  5. python描述符descriptor(一)

    Python 描述符是一种创建托管属性的方法.每当一个属性被查询时,一个动作就会发生.这个动作默认是get,set或者delete.不过,有时候某个应用可能会有 更多的需求,需要你设计一些更复杂的动作 ...

  6. python描述符 descriptor

    descriptor 在python中,如果一个新式类定义了__get__, __set__, __delete__方法中的一个或者多个,那么称之为descriptor.descriptor通常用来改 ...

  7. Python描述符的使用

    Python描述符的使用 前言 作为一位python的使用者,你可能使用python有一段时间了,但是对于python中的描述符却未必使用过,接下来是对描述符使用的介绍 场景介绍 为了引入描述符的使用 ...

  8. python描述符和属性查找

    python描述符 定义 一般说来,描述符是一种访问对象属性时候的绑定行为,如果这个对象属性定义了__get__(),__set__(), and __delete__()一种或者几种,那么就称之为描 ...

  9. Iterator Protocol - Python 描述符协议

    Iterator Protocol - Python 描述符协议 先看几个有关概念, iterator 迭代器, 一个实现了无参数的 __next__ 方法, 并返回 '序列'中下一个元素,在没有更多 ...

随机推荐

  1. 对抗假人 —— 前后端结合的 WAF

    前言 之前介绍了一些前后端结合的中间人攻击方案.由于 Web 程序的特殊性,前端脚本的参与能大幅弥补后端的不足,从而达到传统难以实现的效果. 攻防本为一体,既然能用于攻击,类似的思路同样也可用于防御. ...

  2. MVC5 网站开发之九 网站设置

    网站配置一般用来保存网站的一些设置,写在配置文件中比写在数据库中要合适一下,因为配置文件本身带有缓存,随网站启动读入缓存中,速度更快,而保存在数据库中要单独为一条记录创建一个表,结构不够清晰,而且读写 ...

  3. Angular企业级开发(3)-Angular MVC实现

    1.MVC介绍 Model-View-Controller 在20世纪80年代为程序语言Smalltalk发明的一种软件架构.MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并 ...

  4. iOS开发之ReactiveCocoa下的MVVM(干货分享)

    最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...

  5. UWP开发之ORM实践:如何使用Entity Framework Core做SQLite数据持久层?

    选择SQLite的理由 在做UWP开发的时候我们首选的本地数据库一般都是Sqlite,我以前也不知道为啥?后来仔细研究了一下也是有原因的: 1,微软做的UWP应用大部分也是用Sqlite.或者说是微软 ...

  6. 十分钟玩转 jQuery、实例大全

    一.简介 定义 jQuery创始人是美国John Resig,是优秀的Javascript框架: jQuery是一个轻量级.快速简洁的javaScript库.源码戳这 jQuery对象 jQuery产 ...

  7. Entity Framework 教程——Entity Framework中的实体类型

    Entity Framework中的实体类型 : 在之前的章节中我们介绍过从已有的数据库中创建EDM,它包含数据库中每个表所对应的实体.在EF 5.0/6.0中,存在POCO 实体和动态代理实体两种. ...

  8. WinForm设置控件焦点focus

    winform窗口打开后文本框的默认焦点设置,进入窗口后默认聚焦到某个文本框,两种方法: ①设置tabindex 把该文本框属性里的tabIndex设为0,焦点就默认在这个文本框里了. ②Winfor ...

  9. CSS3自定义滚动条样式 -webkit-scrollbar(转)

    有没有觉得浏览器自带的原始滚动条很不美观,同时也有看到很多网站的自定义滚动条显得高端,就连chrome32.0开发板都抛弃了原始的滚动条,美观多了.那webkit浏览器是如何自定义滚动条的呢? 前言 ...

  10. CentOS下Zabbix安装部署及汉化

    搭建环境:Centos6.5_x86_64,Zabbix2.4.5,epel 源 服务端: 1.安装开发软件包yum -y groupinstall "Development Tools&q ...