Wednesday, November 18, 2009

method和function在python一样吗?

之前学习了descriptor和decorator之后就感觉到python里的类方法中第一个参数: cls 有淫技的存在, 还没有时间理会它. 当然, 学习有不一定通的情况, 只是到刚刚能感觉到"淫"意的地步.

今天和朋友又聊到了self.

结果他妈的...... self不是keyword!! 我靠.... 还有这种事..... 自欺!! 人类的死点....

就是因为这样, 就把下面的事挖出来了.

自然提出一个问题: method与function是不是同一概念? 如下代码:

In [12]: class M(object):
   ....:     def func_or_method(self,name):
   ....:         print name
   ....:         
   ....:        
In [13]: M.func_or_method
Out[13]: <unbound method M.func_or_method>

In [14]: M.__dict__['fun_or_method']
Out[14]: <function func_or_method at 0x94e66f4>

同一个事物, 不同的调用方式, 产生了不同的结果. 不得不让人想到"淫技"一词.

这一切都是源于object和type的__getatrribute__. 因为它是一个hook. 偷天换日只有它能做到.

在: http://users.rcn.com/python/download/Descriptor.htm 里 Invoking Descriptors 一节中道出了__getattribute__的黑暗事实: 把对object和type的"."这种属性获取语法全换成了:
1. 对于object : type(b).__dict__['x'].__get__(b, type(b))
2. 对于type : B.__dict__['x'].__get__(None, B)

这部份转换工作是C实现的. 上面的python代码只是模拟代码(Descriptor.htm指出)

明白这些后, 再回到method与function的区别上.
为什么: M.func_or_method 和 M.__dict__['func_or_method'] 会不同呢?
使用dir()函数, 可以看到, M.func_or_method是有__get__属性的. 但是M.__dict__是没有.

也就是说: M.func_or_method已经被调用了func_or_method.__get__ ! 这样, type()打印出的东西已经是__get__返回的

按照上面了解的, 只是object和type调用__get__的参数不同. 并不是因为定义的函数中有self的原因!


总的来说: A.B都是使用A.__dict__字典, 至于调不调用字典返回的value的__get__和传给它的参数是什么由__getattribute__处理










No comments:

Post a Comment

Note: Only a member of this blog may post a comment.