在描述符中,__get__
和__set__
的第二個參數綁定到調用對象實例(並且__get__
的第三個參數綁定到調用的所有者類對象) :將描述符方法的實例參數綁定到調用對象實例
class Desc():
def __get__(self,instance,owner):
print("I was called by",str(instance),"and am owned by",str(owner))
return self
class Test():
desc = Desc()
t = Test()
t.desc
我將如何去創造一個裝飾到另一個描述方法的實例對象(除__get__
,__set__
,或者__delete__
等)的第二個參數綁定?
例(只是舉個例子,不是我真正想要做):
class Length(object):
'''Descriptor used to manage a basic unit system for length'''
conversion = {'inches':1,'centimeters':2.54,'feet':1/12,'meters':2.54/100}
def __set__(self,instance,length):
'''length argument is a tuple of (magnitude,unit)'''
instance.__value = length[0]
instance.__units = length[1]
def __get__(self,instance,owner):
return self
@MagicalDecoratorOfTruth
def get_in(self, instance, unit): #second argument is bound to instance object
'''Returns the value converted to the requested units'''
return instance.__value * (self.conversion[units]/self.conversion[instance.__units])
class Circle(object):
diameter = Length()
def __init__(self,diameter,units):
Circle.diameter.__set__((diameter,units))
c = Circle(12,'inches')
assert c.diameter.get_in('feet') == 1
c.diameter = (1,'meters')
assert c.diameter.get_in('centimeters') == 100
一種方法我也考慮過嘗試被包裹get_in
方法與裝飾。
class Test():
@classmethod
def myclassmethod(klass):
pass
t = Test()
t.myclassmethod()
不過,我不能確定如何將其應用到:類似的東西使用@classmethod裝飾,其中一類方法的第一個參數被綁定到類對象,而不是類的實例對象來完成上面的情況。
,以避免整個問題將是實例對象傳遞給明確的描述方法的一種方式:
c = Circle(12,'inches')
assert c.diameter.get_in(c,'feet') == 1
c.diameter = (1,'meters')
assert c.diameter.get_in(c,'centimeters') == 100
然而,這似乎違背了D.R.Y.,是十分可怕的引導。
而你的問題是什麼? –
我覺得有很多困惑正在進行。如果你使用'__get__'來僅僅這樣返回'self',你將如何實際訪問'instance .__ value'或'instance .__ units'中的數據?通常,使用描述符,您需要將其設置爲使用三種語法模式「x.d = foo」,「x.d」或「del x.d」。 – ely
你可以在實際的'Circle'類中使用'__set__'來看這個問題,這是行不通的。相反,您想將其更改爲'self.diameter =(diameter,units)',因爲'self'指的是'Circle'實例,它會自動傳遞到'__set__'中作爲'Length'。 (嘗試手動傳遞它會導致錯誤,與魔術裝飾器問題無關)。 – ely