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. CodeForces 588A

    题目链接: http://codeforces.com/problemset/problem/588/A 解题思路: 这个题目很简单, 就是前一天肉的价格比后面几天低还是高,如果是高的话,只要买当天份 ...

  2. javaweb开发过程中的地址写法

    凡是要表示web资源的地址,比如浏览器地址栏中,都是 /凡是要表示硬盘地址, 都是 \  public class ServletDemo1 extends HttpServlet { //实际开发过 ...

  3. .NET中的程序集(Assembly)

    在.NET 中,新引入了一个程序集的概念,就是指经由编译器编译得到的,供CLR进一步编译执行的那个中间产物,在WINDOWS系统中,它一般表现为.dll,或者是.exe的格式,但是要注意,它们跟普通意 ...

  4. Amazon API Gateway Importer整合过程小结

    (1)需要将swagger json转换成amazon api gateway 所需要的格式(根据Method Request中 Request PathsURL Query String Param ...

  5. android——api

    一.1.复用首页做法—从Intent中获取”com.example.android.apis.Path”.根据这个结合PackageManger获得的Activities来展示不同等级的List界面( ...

  6. [Javascript] Logging Pretty-Printing Tabular Data to the Console

    Learn how to use console.table to render arrays and objects in a tabular format for easy scanning ov ...

  7. [Javascript] Log Levels and Semantic Methods

    Go beyond console.log by learning about log levels, filtering log output and structuring your output ...

  8. poj 3154 Graveyard 贪心

    //poj 3154 //sep9 #include <iostream> #include <cmath> using namespace std; double a[204 ...

  9. C++ 让 Win32 Console Application 程序后台运行

    方法一:(无闪现) 添加   #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRT ...

  10. Java EE的十三种核心技术

    1. JDBC: Java Database Connectivity 2. JNDI: Java Name and Directory Interface 3. EJB: Enterprise Ja ...