2013-08-01 24 views
2

我有一個變量,它可能會或可能不會在實例中得到一個值:檢查類實例變量是否在Python中設置的最佳方法是什麼?

class EC(): 
    __init__(self, a=False): 
    ... 
    if a: self.__var = ... 

後來我想,以檢查是否存在於實例__var。由於前面加上__的名稱更改內部名稱以_EC__var檢查代碼變得有點有點亂:

if ''.join(['_',self.__class__.__name__,'__name']) in self.__dict__: ... 

代碼是高於被認爲是正常?如果不是什麼更好的選擇?我能想到的

一種選擇是無論如何給__var一些值,例如:

_no_value = object() 
... 
    def __init__(self, a): 
     self.__var = _no_value 
     ... 
     if a: self.__var = ... 

所以後來我可以比較__var_no_value,而不是與內部變量一塌糊塗。

+2

參見['getattr' ](http://docs.python.org/2/library/functions.html#getattr)函數。 –

+0

我試過了,它有相同的問題(python 2.6.6)。我必須使用getattr(self,'_EC__var') – Phoenix

回答

4

你已經忘記了EAFP原則:

try: 
    value = self.__var 
except AttributeError: 
    # do something else 

如果你決定使用一個哨兵,你可以用一個類變量結合起來:

class EC(): 
    __var = object(): 
    ... 
    if self.__var is not EC.__var: 
     ... 
3

只要使用hasattr(self,'_var')來查看它是否存在 - 它可能被設置爲None,但如果hasattr說它存在,它將會存在。

例如爲:

>>> class a(): 
... def __init__(self): 
...  self.a = 3 
...  self._a_ = 4 
...  self.__a__ = 'Fred' 
... 
>>> A=a() 
>>> hasattr(a, 'a') 
False 
>>> hasattr(A, 'a') 
True 
>>> hasattr(A, '_a_') 
True 
>>> hasattr(A, '__a__') 
True 
>>> hasattr(A, '__b__') 
False 
>>> 
+0

這可以用於單個下劃線,但它不適用於雙精度型 – Phoenix

+0

我認爲您沒有正確地閱讀該問題,或者瞭解Python對'__var'類的雙下劃線屬性。不,它並不那麼簡單。 –

+0

正如你可以從我的擴展答案中看到的,它在這裏使用單下劃線和雙下劃線都很好。 –

2

只要將它設置爲None的類

class EC(): 
    __var = None 

    __init__(self, a=False): 
     ... 
     if a: self.__var = ... 

然後測試if self.__var is not None

如果None應該是屬性的有效值,使用不同單哨兵:

_sentinel = object() 

class EC(): 
    __var = _sentinel 

    __init__(self, a=False): 
     ... 
     if a: self.__var = ... 

並測試if self.__var is not _sentinel

這樣,全部__var的引用被正確地重寫爲包括類名稱。

其他路徑將不使用雙下劃線名稱爲您的屬性。 __var只應用於你想命名空間到你的特定類的屬性,以便的子類不會意外地用它們自己的屬性來打開它。

換句話說,不要使用雙下劃線的名字,除非你真的明白他們是什麼,實際上需要它。任何不屬於未知第三方更廣泛消費框架的代碼?只需堅持單下劃線。

相關問題