2014-09-26 100 views
1

我正在寫一個庫,它解析一個文件,創建一個代表該文件的對象,並允許將該對象導出迴文件。有沒有一種方法可以確保對變量執行比@property驗證?

我想驗證所需的標題和列在任何時候這些值被更改。由於這個原因,我試圖用@property裝飾器設置驗證。

我注意到在@property的python文檔中,如果屬性名稱是'variable',他們使用'_variable'。我知道前面的一個下劃線是表示這個變量是爲弱內部使用而設計的。不過,我的印象是@property裝飾者的觀點是任何調用設置變量都會導致setter函數運行。

_headers = None 

required_headers = ['FIELD_DELIM', 'VIDEO_FORMAT', 'FPS'] 

@property 
def headers(self): 
    return self._headers 

@headers.setter 
def headers(self, value): 
    for header in self.required_headers: 
     if header not in value: 
      raise Exception 
    self._headers = value 

儘管此代碼的工作,我知道我還可以做myObject._headers =值繞過我的二傳手。

有沒有一種方法可以確保始終執行驗證,而不依賴於用戶尊重_headers是否供內部使用?

+2

作爲一個便箋,'_headers = None'設置_class_屬性,一個屬於類的所有實例共享,而不是_instance_屬性。另一方面,'@屬性'是針對每個實例的值。所以,你寫的代碼充其量是誤導性的。 – abarnert 2014-09-26 19:10:54

+0

我從課堂上拿出_headers = None,實際上並不需要。謝謝你的提示。 – 2014-09-26 19:19:04

回答

7

Python是不是設計來幫助你「保證」沒有人盜用你的對象類的。私人屬性的下劃線前綴以及用於隱藏屬性的getter和setter機制可以確保很明顯,人們不應該使用這樣的對象,並且使它更難以這樣做意外,但它不能阻止他們實際上惡意地這樣做。

雖然有很多技巧可以用來更好地隱藏你的屬性,但是像Python這樣的高度動態的,可反省內容的語言,總會有一種方法來解決這個問題 - 直接在你的__dict__或其他任何其他屬性可以隱藏它們,或者只是將對象的__class__更改爲限制較少的東西。

換句話說,你已經可以依靠用戶尊重_headers是供內部使用,如果你所擔心的是你的用戶是白癡;如果你擔心它們是惡意的,Python對你來說是錯誤的語言。

+0

我主要關注看我的源代碼的人,不瞭解@property是什麼,然後改用_headers版本。謝謝。 – 2014-09-26 19:22:34

+2

@KEngle這是doc字符串的用途。 :) – 2014-09-26 19:39:44

+2

@KEngle:如果你正在編寫新手使用的代碼,並期望他們使用代碼作爲自己的文檔,你可能想添加一些額外的註釋,比如'self._headers = None#don' t直接在你的代碼中設置它,使用spam.header屬性或類似的名稱,以及一個列出公共屬性的文檔字符串(無論是真實還是'@ property')。 – abarnert 2014-09-26 19:40:20

1

不,Python不強制的私人概念VS 公共像Java那樣

+0

Python確實有私有與公共的概念;這就是下劃線前綴。它並不試圖像Java那樣強化這個概念。 – abarnert 2014-09-26 19:11:54

+1

此外,您的簡化版本不會簡化任何事情,它完全改變了邏輯。他問他是否有'required_headers'是'value'的_substring_,你問他們中的任何一個是否'_equal_'value'。 – abarnert 2014-09-26 19:12:57

+0

我知道,但人們總是可以訪問obj .__ dict__或任何強調的變量/成員 – 2014-09-26 19:13:55

2

您可以使用雙下劃線進行名稱修改或實現自定義描述符,但是Python的核心原則之一是,用戶應該尊重接口並盡力而爲地不做那些會中斷接口的事情一個非常好的理由。基本上,不要擔心它,只需使用單個下劃線將數據存儲在對象上。

+0

爲什麼downvote?這是一個正確的答案。 – 2014-09-26 19:13:32

1

之類的。在Python中沒有真正的隱私,用戶可以繞過隱私安全事件工作。

如果你願意,你可以實現__getattribute__,當你嘗試訪問你的類的某個元素時,它會檢查它,但即使這樣也不是萬無一失的。看看這個鏈接Difference between __getattr__ vs __getattribute__

相關問題