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. BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]

    1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 4142  Solved: 1964[Submit][Statu ...

  2. 设置tomcat远程debug

    查看端口占用情况命令: netstat -tunlp |grep 8000 tomcat 启动远程debug: startup.sh 中的最后一行 exec "$PRGDIR"/& ...

  3. NLP点滴——文本相似度

    [TOC] 前言 在自然语言处理过程中,经常会涉及到如何度量两个文本之间的相似性,我们都知道文本是一种高维的语义空间,如何对其进行抽象分解,从而能够站在数学角度去量化其相似性.而有了文本之间相似性的度 ...

  4. Python学习

    Python基础教程        网易云课堂-零基础入门学习Python

  5. Javascript高性能编程-提高Dom访问速度

    在浏览器中对于Dom的操作和普通的脚本的操作处于两个不同的dll中,两个dll的交互是比较耗时的,优化对Dom的操作可以提高脚本的执行速度.下面是对如何优化的一些总结: 将需要多次操作的节点存储在一个 ...

  6. Android Weekly Notes Issue #237

    Android Weekly Issue #237 December 25th, 2016 Android Weekly Issue #237 这是本年的最后一篇issue, 感谢大家. 本期内容包括 ...

  7. 基于Ubuntu Hadoop的群集搭建Hive

    Hive是Hadoop生态中的一个重要组成部分,主要用于数据仓库.前面的文章中我们已经搭建好了Hadoop的群集,下面我们在这个群集上再搭建Hive的群集. 1.安装MySQL 1.1安装MySQL ...

  8. FineReport:关于扩展行列求各种条件下的函数运用

    最简单的扩展列,扩展行的求"最大,最小,平均"值的例子 设计图 效果图 相关函数 =MAX(B2:E2) =MIN(B2:E2) =AVERAGE(B2:E2) 这个是(满足条件) ...

  9. 聊聊从web session的共享到可扩展缓存设计

    先从web session的共享说起   许多系统需要提供7*24小时服务,这类系统肯定需要考虑灾备问题,单台服务器如果宕机可能无法立马恢复使用,这必定影响到服务.这个问题对于系统规模来说,从小到大可 ...

  10. 在Linux(Ubuntu/openSUSE/CentOS)下配置ASP.NET(Apache + Mono)

    [题外话] 闲的无聊竟然想尝试测试自己做的项目在不同操作系统上的性能表现,所以决定试试在Linux上部署Apache和Mono的环境.由于平时很少接触Linux,所以从网上找了几篇文章(附在相关链接中 ...