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函数详解-第二篇的更多相关文章

  1. python中的buildin函数详解(第一篇)

    这会是很长的一个帖子,因为我打算从python最基础的东西开始,尝试去完全的掌握它,buildin中有一些常用的函数比如 abs, open, setattr, getattr, 大家都很了解他们的用 ...

  2. python中的 zip函数详解

    python中zip()函数用法举例 定义:zip([iterable, ...]) zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素打包成一个个tuple ...

  3. Python中的getattr()函数详解

    最近看Dive into python第四章自省中提到getattr()函数,作为一个内建函数平时自己没怎么用过所以也不太理解这个函数的一些用法 看了下函数本身的doc getattr(object, ...

  4. python种的builtin函数详解-第三篇

    exec_stmt ::= "exec" or_expr ["in" expression ["," expression]] eval(e ...

  5. 75.Python中ORM聚合函数详解:Sum

    Sum:某个字段的总和. 1. 求图书的销售总额,示例代码如下: from django.http import HttpResponse from django.db import connecti ...

  6. 72.Python中ORM聚合函数详解:Avg,aggregate,annotate

    聚合函数: 如果你用原生SQL语句,则可以使用聚合函数提取数据.比如提取某个商品销售的数量,那么就可以使用Count,如果想要知道销售的平均价格,那么就可以使用Avg. 聚合函数是通过aggregat ...

  7. 74.Python中ORM聚合函数详解:Max,Min

    Max和Min:获取指定对象的最大值和最小值. 1. 比如:想要获取Author表中的最大的年龄和最小的年龄.示例代码如下: from django.http import HttpResponse ...

  8. 73.Python中ORM聚合函数详解:Count

    Count:用来求某个数据的个数. 在以下所有的示例中所采用的模型为: from django.db import models # 定义作者模型 class Author(models.Model) ...

  9. Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释

    上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: JNIEXPO ...

随机推荐

  1. android导入项目出错处理

    问题: 执行Import-Android下的Existing Android Code Into Workspace 解决方法:

  2. mac下的改装人生——把主硬盘换成ssd

    这两天搞得最多的事情就是我的这两块硬盘,基本上的时间都被他们占用去了,但是最后的结果也是让我很开心--开机瞬秒,程序瞬秒,生活质量瞬间高了很多哈. 关于ssd的各种事情,我的另外一篇博客有讲,算是比较 ...

  3. 尚学堂 JAVA DAY12 概念总结

    面向过程和面向对象的区别.(5 分)面向过程就好像:一位父亲吩咐自己8岁的小儿子去买啤酒.他需要考虑儿子从出门后的每一个步骤,叮嘱儿子出门怎么走,如何过马路,到了超市如何找到酒水区,怎么识别需要的品牌 ...

  4. P - The Shortest Path in Nya Graph-hdu4725(双端队列+拆点)

    题意:有N个点和N层..一层有X个点(0<=X<=N).两邻两层间有一条路花费C.还有M条小路在两个点之间.问从第一个点走到第N个点最短路是多少... 可以考虑在每一层增加一个点,这个点到 ...

  5. hdoj 1513 Palindrome【LCS+滚动数组】

    Palindrome Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  6. java 编辑报错 非法字符: \ufeff 解决方案

    用Notepad ++ 调成utf-8 格式 bom 或无bom根据情况 新建类 把代码一句句粘进去 ok

  7. angularJS 过滤器 表单验证

    过滤器1.filter的作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果,主要用于数据的格式化.2.内置过滤器(1)Currency(货币)将一个数值格式化为货币格式,默认为$(2)D ...

  8. Solr系列二:Solr与mmseg4j的整合

    mmseg4j是一个很好的中文分词器,solr与mmseg4j的整合也非常简单.如下: 第一步:下载mmseg4j的jar包,网上搜索一下有很多下载地址,如下是csdn上的一个连接:http://do ...

  9. Android中的Zip解压缩

    import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import ...

  10. MaxReceivedMessageSize :已超过传入消息(65536)的最大消息大小配额

    做的windows应用程序(后台调用webservice),数据量大的时候,报错如下: System.ServiceModel.CommunicationException: 已超过传入消息(6553 ...