zoukankan      html  css  js  c++  java
  • python中的builtin函数详解第二篇 C

    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)
  • 相关阅读:
    C#获取中英文混合字符串长度和截取函数
    页面和块高度在JavaScript中的属性总结
    跨浏览器兼容添加到收藏夹/书签的Javascript
    转:28个免费的在线文件格式转换工具
    2009年十大经典网络小说
    某企业网站建设步骤
    转:Web安全工具大汇聚
    枚举
    VS中不显示解决方案的解决方法
    SQL 分页存储过程
  • 原文地址:https://www.cnblogs.com/youngershen/p/3987418.html
Copyright © 2011-2022 走看看