2016-04-23 98 views

回答

2

在蟒蛇當一個類定義要麼__get____set__,或者__delete__據說是一個描述符類。這些給出了一個類屬性「綁定」的行爲。這基本上意味着無論何時通過使用通常點符號的類通過類訪問該對象作爲屬性,它都將根據所調用的類型運行一個定義的方法。您發佈的代碼只定義了__get__,這使得它成爲非數據描述符。

這裏有覆蓋另一個dunder方法進場,__call__這使得你的類調用對象:

Class CallableClass(object): 

    def __init__(self, fun): 
     self.fun = fun 

    def __call__(self, *args): 
     return self.fun(*args) 

>>> cc = CallableClass(lambda *args: return sum(args)) 
>>> cc(1, 2, 3) 
6 
>>> cc(0) 
0 

正如你所看到的,你可以對實例調用,就像你喜歡的只是像任何其他可調用函數(例如函數)。我要回顧一下,因爲描述符類返回types.MethodType(self, obj)types.MethodType(self, obj, objtype),具體取決於您使用的是哪個Python版本。

MethodType綁定其第一個參數,必須將其第一個參數調用到它的第二個參數,該參數是一個類實例。基本上,您每次訪問primitive描述符對象時都會在類實例對象上創建綁定方法。

這裏的「描述符」功能只有在用作類屬性時纔會使用,通過primitive文檔字符串讀取時會提到該類將函數包裝爲裝飾器。

一些線下來,你可以看到它在行動作爲裝飾:

@primitive 
def merge_tapes(x, y): return x 
merge_tapes.defgrad(lambda ans, x, y : lambda g : g) 
merge_tapes.defgrad(lambda ans, x, y : lambda g : g, argnum=1) 

但作爲一個描述符類在這裏:

differentiable_ops = ['__add__', '__sub__', '__mul__', '__pow__', '__mod__', 
         '__neg__', '__radd__', '__rsub__', '__rmul__', '__rpow__', 
         '__rmod__', DIV, RDIV] 

nondifferentiable_ops = ['__eq__', '__ne__', '__gt__', '__ge__', '__lt__', '__le__',] 
for float_op in differentiable_ops + nondifferentiable_ops: 
    setattr(FloatNode, float_op, primitive(getattr(float, float_op))) 

在這裏,你可以看到類FloatNode呼籲setattr來自兩個「操作」列表的所有 字符串。在同樣的setattr調用primitive是 打電話給getattr,該調用檢索相同 名稱的類型float的內部方法將其作爲其初始func參數傳入。現在,無論何時訪問任何這些操作,它們都是綁定方法。

所以,如果你對被設定爲FloatNode屬性的「OPS」之一:

>> FloatNode(1, []).__add__ 
<bound method __add__ of <__main__.FloatNode object at 0xb6fd61ec>> 

你會得到封裝了primitive持有的所有利益綁定方法(即梯度功能) 。

0

您發佈的代碼被用作描述符。 具有以下效果:如果某個類具有描述符的對象,那麼該實例的屬性與該類中的對象具有相同的名稱。

如果設置了該屬性,則調用該描述符的__set__(self, instance, value)命令。

如果刪除它,則調用__delete__(self, instance)函數(如果調用描述符)。

如果您嘗試接收存儲在該屬性中的數據,則會調用描述符的__get__(self, instance, owner)方法。 (所有者是包含描述符對象的類)

自參數是描述符本身(就像在python中的任何其他對象一樣),而實例參數是包含被修改屬性的對象。

因此,在這種情況下,接收的屬性的數據與下面primitive導致types.MethodType(self, instance)用於PY2或types.MethodType(self, instance, owner)在PY3,其中self是原始的,instance是的屬性被檢索出的目標和owner是類保持primitive對象。 (如前所述)

我希望我能幫上忙,

CodenameLambda

相關問題