pythonin详解_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': , '__dict__': , '__weakref__': , '__doc__': None, '__init__': })

>>> me.__dict__

{'name': 'younger'}

我们的类和实例都具有__dict__属性,这个字典中囊括了该对象中所有的属性(类也是对象)。

继续运行代码

me.country

结果为

>>> me.country

'china'

继续运行代码

me.__dict__['country]

结果为

>>> me.__dict__['country']

Traceback (most recent call last):

File "", line 1, in

KeyError: 'country'

由此可见,当我们调用实例属性的时候,me.name和me.dict['name'] 的结果是一样的,当调用的是类属性的时候,就截然不同了,结果显而易见,当我们再调用不同的属性的时候,系统会自动做出一些判断,但是我们现在还不知道判断是怎么进行的,也不知道是什么时候进行的,这里还不做解答,再看一个关于类中方法调用的例子。

我们继续运行代码

Person.say

Person.__dict__['say']

me.say

me.__dict__['say']

运行结果为

>>> Person.say

>>> Person.__dict__['say']

>>> p.say

>

>>> p.__dict__['say']

Traceback (most recent call last):

File "", line 1, in

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值