python中的builtin函数详解-第二篇
classmethod(function)
这里不过多说明这个builtin方法的具体用法,python的文档和help函数已经给了这个方法充足的使用说明,所以我这里要说的时关于 classmethod , property之流的注解方法背后所用的技术细节,也是python中比较难以理解的一个知识点, 那就是 python中的 描述符。
从现象开始分析
class Person(object):
country = 'china'
def __init__(self, name):
self.name = name
def say(self):
print self.name
这个类开始分析,首先运行如下代码
me = Person('younger')
Person.__dict__
me.__dict__
结果为
>>> Person.__dict__
dict_proxy({'__module__': '__main__', 'country': 'china', 'age': 20, 'say': <function say at 0x1047e0b18>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, ' __doc__': None, '__init__': <function __init__ at 0x1047e0b90>})
>>> me.__dict__
{'name': 'younger'}
我们的类和实例都具有__dict__属性,这个字典中囊括了该对象中所有的属性(类也是对象)。
继续运行代码
me.country
结果为
>>> me.country
'china'
继续运行代码
me.__dict__['country]
结果为
>>> me.__dict__['country']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'country'
由此可见,当我们调用实例属性的时候,me.name和me.dict['name'] 的结果是一样的,当调用的是类属性的时候,就截然不同了,结果显而易见,当我们再调用不同的属性的时候,系统会自动做出一些判断,但是我们现在还不知道判断是怎么进行的,也不知道是什么时候进行的,这里还不做解答,再看一个关于类中方法调用的例子。
我们继续运行代码
Person.say
Person.__dict__['say']
me.say
me.__dict__['say']
运行结果为
>>> Person.say
<unbound method Person.say>
>>> Person.__dict__['say']
<function say at 0x1047e0b18>
>>> p.say
<bound method Person.say of <__main__.Person object at 0x10473a190>>
>>> p.__dict__['say']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'say'
先不管方法有没有被绑定,先看下结果,我们再用点和__dict__访问一个方法的时候,得到的是全然不同的结果,理论上来说应该是会得到一样的结果,因为都是要再当前对象的__dict__ 中进行查找,为什么Person的返回会完全不同呢?而且就返回结果来说,Person.say返回的结果类型为 未绑定的instancemethod, 而 Person.__dict__['say'] 返回的是普通的function类型对象, 方法的返回和调用完全和与其的不一样, 这就是描述符的作用。
官方对描述符的定义是:
一个描述符, 是一个对象对某个 “绑定” 方法的描述。
用自己的话来说,就是一个类中实现一些类似于 __get__, __set__, __getattr__, __getattribute__ 的方法,然后再对属性进行各种操作的时候,这些方法将会进行类似过滤的操作,来帮助你做一些额外的工作。
拿上面的例子来说,调用一个方法有两种情况,一种是在类中调用,另一种是实例种调用,如果是对象种调用,那么对象的 __getattribute__方法会做返回 type(obj).__dict__['func'].__get__(obj, type(obj)), 如果是类在调用,那么会被返回为 cls.__dict__['func'].__get__(None, cls), 这里___getattribute__, 起到了巨大的作用,用各种get方法进行了过滤, 所以在对方法进行操作的时候,用点和__dict__进行调回会有不同的结果,这也是描述符的作用所在。
你可以写自己的描述符,来对属性的读写进行操作。
现在我们回到staticmethod这个装饰器方法上来
class StaticMethod(object):
"Emulate PyStaticMethod_Type() in Objects/funcobject.c
def __init__(self, f):
self.f = f
def __get__(self, obj, objtype=None):
return self.f
上面是文档种对这个方法的python模拟,实际上builtin种的方法都是c的方法,该装饰器在get的时候进行自定义操作。
举个例子
>>> class E(object):
def f(klass, x):
return klass.__name__, x
f = classmethod(f)
>>> print E.f(3)
('E', 3)
>>> print E().f(3)
('E', 3)
python中的builtin函数详解-第二篇的更多相关文章
- python中的buildin函数详解(第一篇)
这会是很长的一个帖子,因为我打算从python最基础的东西开始,尝试去完全的掌握它,buildin中有一些常用的函数比如 abs, open, setattr, getattr, 大家都很了解他们的用 ...
- python中的 zip函数详解
python中zip()函数用法举例 定义:zip([iterable, ...]) zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素打包成一个个tuple ...
- Python中的getattr()函数详解
最近看Dive into python第四章自省中提到getattr()函数,作为一个内建函数平时自己没怎么用过所以也不太理解这个函数的一些用法 看了下函数本身的doc getattr(object, ...
- python种的builtin函数详解-第三篇
exec_stmt ::= "exec" or_expr ["in" expression ["," expression]] eval(e ...
- 75.Python中ORM聚合函数详解:Sum
Sum:某个字段的总和. 1. 求图书的销售总额,示例代码如下: from django.http import HttpResponse from django.db import connecti ...
- 72.Python中ORM聚合函数详解:Avg,aggregate,annotate
聚合函数: 如果你用原生SQL语句,则可以使用聚合函数提取数据.比如提取某个商品销售的数量,那么就可以使用Count,如果想要知道销售的平均价格,那么就可以使用Avg. 聚合函数是通过aggregat ...
- 74.Python中ORM聚合函数详解:Max,Min
Max和Min:获取指定对象的最大值和最小值. 1. 比如:想要获取Author表中的最大的年龄和最小的年龄.示例代码如下: from django.http import HttpResponse ...
- 73.Python中ORM聚合函数详解:Count
Count:用来求某个数据的个数. 在以下所有的示例中所采用的模型为: from django.db import models # 定义作者模型 class Author(models.Model) ...
- Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释
上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: JNIEXPO ...
随机推荐
- HDOJ(HDU) 2164 Rock, Paper, or Scissors?
Problem Description Rock, Paper, Scissors is a two player game, where each player simultaneously cho ...
- 《University Calculus》-chaper8-无穷序列和无穷级数-等比级数
前言:其实无穷序列和无穷级数和数列{an}以及我们接触微积分就给出的极限概念lim有着紧密的联系,它对于我们在具体的问题当中进行建模和数据分析有着非常重要的作用. 无穷序列: 最简单的一种说法,就是一 ...
- CentOS squid代理内网主机上网 openVpn配置
- ural 1136. Parliament
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1136 题目描述:给定一个按照(左子树-右子树-根)(即先序)遍历序列的树,求其按照 右子 ...
- 004_Eclipse编写第一个Java_Web程序
1.MyEclipse的菜单栏--File--Web Project,新建一个web工程 Project name 填上自己的项目名称,例如HelloWorld. 需要选择Java EE版本以及Tar ...
- Android 图片选择器
图片选择器,遍历系统所有图片并显示,点击查看大图,长按选中,并将结果返回 字体颜色res/color建立text_selecor.xml <selector xmlns:android=&quo ...
- 关于Build Active Architecture Only属性
关于Build Active Architecture Only属性 Architecture 属性在BuildSetting里. 这个属性设置为yes,是为了debug的时候编译速度更快,它只编译当 ...
- Java8特性详解 lambda表达式 Stream
1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正 ...
- TCP异常终止(reset报文)
在之前做智能家居系统时,师弟做的服务端与WiFI盒子(客户端)进行通信时,总是出现异常情况,然后服务端不停地向客户端发送RESET报文,之前一直都不知道是什么情况,因此一直不知道是什么问题导致的,今天 ...
- Android程序版本更新--通知栏更新下载安装(转)
Android应用检查版本更新后,在通知栏下载,更新下载进度,下载完成自动安装,效果图如下: 检查当前版本号 AndroidManifest文件中的versionCode用来标识版本,在服务器放一个新 ...