2010-03-26 87 views
13

我正在寫一個類用戶插入到數據庫中,而之前,我太遠,我只是想確保我的OO方法是乾淨的:正確的方式來設置對象的實例變量

class User(object): 

    def setName(self,name): 

     #Do sanity checks on name 
     self._name = name 

    def setPassword(self,password): 

     #Check password length > 6 characters 
     #Encrypt to md5 
     self._password = password 

    def commit(self): 

     #Commit to database 

>>u = User() 
>>u.setName('Jason Martinez') 
>>u.setPassword('linebreak') 
>>u.commit() 

這是正確的做法嗎? 我應該向上聲明類變量嗎? 我應該在所有類變量前面使用_來使它們變爲私有的嗎?

感謝您的幫助。

+0

代碼中沒有類變量。考慮更新您的標題。 – 2010-03-26 08:02:30

+0

你使用什麼教程來學習Python。這應該包括在內。既然不是,我想知道你正在使用什麼教程。 – 2010-03-26 10:14:27

+0

「對象實例變量」在Python中被稱爲「屬性」 – 2010-03-26 10:19:57

回答

19

這通常是正確的,據我所知,但你可以用properties清理。

class User(object): 

    def _setName(self, name=None): 
     self._name = name 

    def _getName(self): 
     return self._name 

    def _setPassword(self, password): 
     self._password = password 

    def _getPassword(self): 
     return self._password 

    def commit(self): 
     pass 

    name = property(_getName, _setName) 
    password = property(_getPassword, _setPassword) 

>>u = User() 
>>u.name = 'Jason Martinez' 
>>u.password = 'linebreak' 
>>u.commit() 

還有一個方便的基於裝飾器的語法,文檔也解釋了這一點。

+0

這真的很有幫助。謝謝。 – ensnare 2010-03-26 08:17:36

+1

我注意到你的構造函數接受了一個強制的'name'參數,所以你的'User()'的例子用法會引發一個錯誤。我編輯我的示例默認'name'爲'None'來避免這種情況,但是您可能想要提供一個沒有參數的重載實現。 – bcherry 2010-03-26 08:36:37

+0

是的,謝謝! – ensnare 2010-03-26 17:14:32

3

該代碼中沒有類變量,只有實例屬性。並使用properties而不是訪問器。而且確實創造了在初始化實例的屬性,最好在傳遞的值:

class User(object): 
    def __init__(self, name, password='!!'): 
    self.name = name 
    self.password = password 

    ... 
+0

感謝您的迴應。我不確定哪些屬性,但我會閱讀。用戶對象有很多變量,大約50個,所以我認爲這將是太多的傳遞給構造函數,不是嗎? 我知道代碼中目前沒有類變量。我的意思是,我應該製作這些類變量嗎? 謝謝。 – ensnare 2010-03-26 08:04:22

+0

永遠不要使用類變量,當值需要隨實例而變化時。 – 2010-03-26 08:06:28

7

使用單個_不會使您的屬性變爲私有:它是一種約定,它告訴它是內部屬性,並且不應在正常情況下由外部代碼訪問。使用您的代碼也意味着密碼和名稱是隻讀的。

我強烈建議爲您的類使用初始化程序,它將初始化您的屬性,即使是默認值(如None):它會使事情變得更容易,您不必檢查是否存在_name和_password屬性(使用hasattr)。

在您的代碼上使用Pylint。

2

其他人已經指出:如果在獲取/設置屬性時不需要執行額外的邏輯,請避免使用setter和getter並使用簡單的屬性訪問。 如果您確實需要額外的邏輯,請使用屬性。

如果有許多參數傳遞給一個實例初始化考慮使用單獨的對象或辭典保持所有參數:

>>> class User(object): 
...  def __init__(self, params): 
...   self.__dict__.update(params) 
... 

>>> params = { 
...  'username': 'john', 
...  'password': 'linebreak', 
...  } 
>>> user = User(params) 
>>> user.username 
'john' 
>>> user.password 
'linebreak' 

附:在你的情況下,你不需要在課堂級別聲明你的屬性。 通常情況下,如果要在所有類實例中共享相同的值,請執行以下操作:

>>> class User(object): 
...  type = 'superuser' 
... 
>>> user = User() 
>>> user2 = User() 
>>> 
>>> user.type 
'superuser' 
>>> user2.type 
'superuser' 
>>> 
>>> user2.type = 'instance superuser' 
>>> 
>>> user.type 
'superuser' 
>>> user2.type 
'instance superuser' 
>>> User.type 
'superuser' 
相關問題