2010-03-26 10 views
13

Ich schreibe eine Klasse Benutzer in eine Datenbank einzufügen, und bevor ich zu weit in, ich möchte nur sicherstellen, dass meine OO Ansatz ist sauber:Die richtige Art und Weise Variablen Objektinstanz zu setzen

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() 

Ist das der richtige Ansatz? Soll ich Klassenvariablen nach oben deklarieren? Sollte ich _ vor allen Klassenvariablen verwenden, um sie privat zu machen?

Vielen Dank für Ihre Hilfe.

+0

Keine Klassenvariablen in Ihrem Code. Überlege dir, deinen Titel zu aktualisieren. –

+0

In welchem ​​Tutorial lernst du Python? Dies sollte abgedeckt werden. Da es nicht ist, würde ich gerne wissen, welches Tutorial Sie verwenden. –

+0

"Objektinstanzvariablen" heißen in Python "Attribute" –

Antwort

19

Es ist grundsätzlich richtig, AFAIK, aber man konnte es mit properties aufzuräumen.

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() 

Es gibt auch eine bequeme dekoratorbasierte Syntax, die Dokumentation erklärt das auch.

+0

Das war sehr hilfreich. Vielen Dank. – ensnare

+1

Ich bemerkte, dass Ihr Konstruktor ein obligatorisches 'name' Argument akzeptierte, so würde Ihre Beispielverwendung von' User() 'einen Fehler verursachen. Ich habe mein Beispiel so bearbeitet, dass der 'name' auf' None' gesetzt wurde, um dies zu vermeiden, aber Sie möchten vielleicht eine überladene Implementierung ohne Argumente anbieten. – bcherry

+0

Ja, danke! – ensnare

3

In diesem Code gibt es keine Klassenvariablen, nur Instanzattribute. Und verwenden Sie properties anstelle von Accessoren. Und tun erstellen die Instanz in der Initialisierungsliste Attribute, vorzugsweise von Werten in geben:

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

    ... 
+0

Danke für die Antwort. Ich bin mir nicht sicher, welche Eigenschaften sind, aber ich werde nachlesen. Das User-Objekt hat viele Variablen, 50 oder so, ich denke, das wäre zu viel, um in den Konstruktor zu gelangen, nein? Ich weiß, dass es derzeit keine Klassenvariablen im Code gibt. Was ich meine ist, sollte ich diese Klassenvariablen machen? Danke. – ensnare

+0

Verwenden Sie niemals Klassenvariablen, wenn der Wert von Instanz zu Instanz variieren muss. –

7

mit einem einzigen _ macht nicht Ihre Attribute privat: Es ist eine Konvention, die besagt, dass es ein internes Attribut ist und nicht unter normalen Umständen durch externen Code zugegriffen werden sollte. Mit Ihrem Code bedeutet es auch, dass Passwort und Name nur gelesen werden können.

Ich empfehle dringend, einen Initialisierer für Ihre Klasse zu verwenden, der Ihre Attribute initialisiert, auch wenn sie auf einen Standardwert wie None gesetzt ist: Es erleichtert die Commit-Methode, bei der Sie nicht auf Existenz prüfen müssen die Attribute _name und _password (mit hasattr).

Verwenden Sie Pyylint auf Ihrem Code.

2

Andere haben bereits darauf hingewiesen: Vermeiden Sie die Verwendung von Setter und Getter und verwenden Sie einfachen Attributzugriff, wenn Sie beim Abrufen/Festlegen Ihres Attributs keine zusätzliche Logik ausführen müssen. Wenn Sie diese zusätzliche Logik benötigen, dann verwenden Sie Eigenschaften.

Wenn Sie viele Parameter zu einer Instanz initializer passieren prüfen, mit separatem Objekt oder Wörterbuch hält alle Parameter:

>>> 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' 

P. S. In diesem Fall müssen Sie Ihre Attribute nicht auf Klassenebene deklarieren. Dies ist normalerweise der Fall, wenn Sie für alle Klasseninstanzen den gleichen Wert verwenden möchten:

>>> 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' 
Verwandte Themen