2013-07-26 53 views
1

我有自定義getter的類,所以我需要使用自定義getter的情況以及需要使用default的情況。如何知道在Python中請求哪個下一個屬性

所以考慮以下。

如果我調用對象C的方法是這樣的:

c.somePyClassProp 

在這種情況下,我需要調用自定義的getter,和getter將返回int值,而不是Python對象。 但如果我呼籲這樣的方法:

c.somePyClassProp.getAttributes() 

在這種情況下,我需要使用默認的二傳手,並首次返回需要是Python對象,然後我們需要調用返回Python對象的getAttributes方法(從c.somePyClassProp)。 請注意somePyClassProp實際上是另一個Python類實例的類的屬性。

那麼,有什麼方法可以在Python上知道在第一次方法調用之後是否會調用其他一些方法?

+1

唯一可能的方式做你想做的就是讓'c.somePyClassProp'返回你想要的兩個接口的對象,聯合收割機(部分或全部)。也就是說,你需要它看起來像一個'int',但也有'getAttributes'方法。如果你需要它可以做任何不平凡的事情,它將是混亂和複雜的。你確定你不能使用不同的方法或屬性名來區分兩種用途嗎? – Blckknght

+0

Kindall的答案似乎是最好的,但前提是你可以在所有上下文中表現爲int的對象,除了**它還支持getAttributes方法。 –

回答

3

你不想根據下一個訪問哪個屬性返回不同的值,你想返回一個int類似的對象,具有所需的屬性。爲此,我們創建一個int的子類,該子類具有getAttributes()方法。當然,這個類的一個實例需要知道它「綁定」了什麼對象,也就是它的getAttributes()方法應該引用哪個對象,所以我們將它添加到構造函數中。

class bound_int(int): 
    def __new__(cls, value, obj): 
     val = int.__new__(cls, value) 
     val.obj = obj 
     return val 
    def getAttributes(self): 
     return self.obj.somePyClassProp 

現在您的getter方法c.somePyClassProp,而不是返回一個整數,你返回bound_int,並把它傳遞給其getAttributes()方法需要了解的對象的引用(在這裏我就必須把它轉交self ,對象它正在從返回):

@property 
def somePyClassProp(self): 
    return bound_int(42, self) 

這樣一來,如果你使用c.somePyPclassPropint,它的行爲就像任何其他int,因爲它是一個,但如果你想進一步呼籲getAttributes()就可以了,你也能做到。在兩種情況下都是相同的價值;它只是爲了實現這兩個目的而建立的。這種方法可以適應幾乎任何類型的問題。

+0

雖然這在技術上起作用,但它非常令人困惑。一個int值爲3的'bound_int'將打印爲'3'並且看起來幾乎完全像一個真正的'3',但它會失敗'type'檢查並導致內存泄漏,如果'bound_int'大於它的創建對象。你不想調試由看起來像'3'的東西引起的內存泄漏。 – user2357112

+0

只要你以正確的方式執行它,就可以通過類型檢查,即使用'issubclass()'。您的其他關注點雖然在技術上不是內存泄漏,但它是一個很好的觀點,並且需要注意的是,如果所涉及的對象很大。有很多情況下'bound_int'完全消失,避免了這個問題,但是在很多情況下,它不會。 – kindall

+0

您可以使用'weakref.ref'來存儲對其他對象的引用,以避免強制它在需要時在內存中掛起。 – kindall

4

No. c.someMethod是一個獨立的表達式;其評估不會受到使用結果的背景的影響。如果有可能達到你想要的,這將是結果:

x = c.someMethod 
c.someMethod.getAttributes() # Works! 
x.getAttributes()   # AttributeError! 

這會混淆爲地獄。

不要試圖使c.someMethod的行爲有所不同,具體取決於使用它的方式,並且如果可能的話,根本不要使c.someMethod成爲方法調用。人們會期望c.someMethod返回一個綁定的方法對象,然後可以調用它來執行該方法;只需按照常規方法def即可,並將其與c.someMethod()聯繫起來。

+0

Tnx在你的答案。其實在我的情況下'someMethod'不是方法,它是其他Python類,所以,我會編輯我的問題 – user232343

0

它看起來像你想要兩種方式來獲得屬性取決於你想要做什麼。我不認爲有任何固有的Pythonic方法來實現這一點,因此您需要爲每個案例存儲變量或屬性名稱。也許:

c.somePyClassProp 

可以在__get__c.somePyClassProp__getAttributes() 使用可以在__getattribute__函數內部多個自定義的方式來實現。我用

的一種方式(這可能不是最好的)的檢查,準確的變量名:

def __getattribute__(self, var_name): 
    if ('__' in var_name): 
     var_name, method = var_name.split('__') 
    return object.__getattribute__(self, var_name).__getattribute__(method) 

使用object.__get__(self, var_name)採用直接獲取屬性的對象類的方法。

+0

對不起,這是一個混亂,應該使用'__getattribute__'方法。 – smakateer

0

您可以將包含的python對象作爲變量存儲,並通過@property dectorator爲所需的任何值存儲create getters。當你想讀取int時,引用該屬性。當您想要包含的對象時,請改用其變量名稱。

class SomePyClass(object): 
    def getInt(self): 
     return 1 
    def getAttributes(self): 
     return 'a b c' 

class MyClass(object): 

    def __init__(self, py_class): 
     self._py_class = py_class 

    @property 
    def some_property(self): 
     return self._py_class.getInt() 

x = MyClass(SomePyClass()) 
y = self.some_property 
x._py_class.getAttributes() 
相關問題