??descriptor(描述符)是python中比較高階的概念,通過以下示例加深一下對(duì)descriptor的理解。
??首先看一組比較費(fèi)解的代碼(functions are descriptiors)
def adder(x,y):
return x+y
add23 = adder.__get__(23)
add23(100)
# 123
python通過非數(shù)據(jù)描述符連接了面向?qū)ο?/strong>和基于函數(shù)構(gòu)建的兩個(gè)重要特性
??那普通函數(shù)和類方法函數(shù)的不同點(diǎn)是什么呢蚓庭,類方法的第一個(gè)參數(shù)存儲(chǔ)了對(duì)象實(shí)例引用岖食,python中通常寫作self
癌蚁。具體如下:
class D(object):
def f(self, x):
return x
d = D()
d.f
# <bound method D.f of <__main__.D object at 0x00000000077EECC0>>
d.f.__self__
# <__main__.D at 0x77eecc0>
d.f.__func__
# <function __main__.D.f>
d.f.__class__
# method
adder.__class__ #文章一開始定義的函數(shù)
# function
??因此python的funcobject
為了同時(shí)支持method
和function
兩種調(diào)用方式邑闲,在獲取類屬性時(shí)候,函數(shù)通過實(shí)現(xiàn)__get__()
方法來綁定刨仑,即: 當(dāng)函數(shù)作為一個(gè)方法被一個(gè)對(duì)象調(diào)用的時(shí)候郑诺,python中所有的函數(shù)都是一個(gè)返回綁定方法的非數(shù)據(jù)描述符夹姥。有類似如下的結(jié)構(gòu):
import types
class Function(object):
. . .
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
if obj is None:
return self
return types.MethodType(self, obj)
# types.MethodType:
# method(function, instance)
# Create a bound instance method object.
??所有的函數(shù)和方法均為上面定義的Function
的實(shí)例,為obj
對(duì)象創(chuàng)建一個(gè)綁定的方法self
辙诞。
??說到這里辙售,應(yīng)該能解釋最開始這個(gè)費(fèi)解的示例了。
??adder.__get__(23)
返回的是:23這個(gè)整數(shù)對(duì)象的adder方法(描述符把a(bǔ)dder這個(gè)方法綁定到了23上)
add23.__class__
# method 可以看到不是function而是method
add23.__self__
# 23
python通過描述符統(tǒng)一了函數(shù)和方法兩種不同調(diào)用方式