2010-01-20 15 views
6

Ich versuche, den besten Weg, um ein paar Klassen zu entwerfen. Ich bin ziemlich neu in Python (und OOP im Allgemeinen) und möchte nur sicherstellen, dass ich das richtig mache. Ich habe zwei Klassen: "Benutzer" und "Benutzer".Python Newbie Klasse Design Frage

class User(object): 
    def __init__(self): 
     pass 

class Users(object): 
    def __init__(self): 
     self.users = [] 

    def add(self, user_id, email): 
     u = User() 
     u.user_id = user_id 
     u.email = email 
     self.users.append(u) 

users = Users() 
users.add(user_id = 1, email = '[email protected]') 

Wenn ich meine Benutzer abrufen möchten, verwende ich:

for u in users.users: 
    print u.email 

"users.users" scheint ein wenig überflüssig. Mache ich das richtig?

Antwort

11

dies in Ihrer Users:

def __iter__(self): 
    return iter(self.users) 

Jetzt können Sie:

for u in users: 
    print u.email 

Docs

6

Sie wahrscheinlich eher nur eine Liste von Benutzerobjekte wollen, als eine Klasse, die mehrere Benutzer enthält .

Alle Mitgliedsattribute für Benutzer sollten sich in der Benutzerklasse und nicht in der Benutzerklasse befinden.

4

Ich sehe nichts falsch mit users.users, aber wenn Sie einen besseren Weg bevorzugen, können Sie __iter__ in Benutzer überschreiben.

class Users(object): 
    def __init__(self): 
     self.users = [] 

    def add(self, user_id, email): 
     u = User() 
     u.user_id = user_id 
     u.email = email 
     self.users.append(u) 

    def __iter__(self): 
     return iter(self.users) 

Jetzt können Sie dies tun:

for u in users: 
    print u.email 

Die __iter__ spezielle Methode verhalten als Iterator Ihr Objekt macht

17

Ich würde sagen, nicht wirklich. Ihre Users Klasse scheint nur eine Liste von Benutzern zu sein, also würde ich sie nur zu einer Liste anstatt einer ganzen Klasse machen. Hier ist, was ich tun würde:

class User(object): 
    def __init__(self, user_id=None, email=None): 
     self.user_id, self.email = user_id, email 

users = [] 
users.append(User(user_id = 1, email = '[email protected]')) 

for u in users: 
    print u.email 

Wenn Sie Users wollen aus einem anderen Grund eine Klasse für sich sein, könnten Sie haben es von list erben, oder (wenn nicht) Sie diese auf die Definition hinzufügen könnte:

class Users(object): 
    # rest of code 
    def __iter__(self): 
     return iter(self.users) 

Auf diese Weise können Sie einfach sagen:

users = Users() 
... 
for u in users: 
    print u.email 
+0

TypeError: Iteration über Nicht-Sequenz - wenn Sie + = verwenden, sollte die RHS auch eine Liste sein. – Jorenko

1

Es gibt keine "schwarz" und "weiß" hier, nur Graustufen. Sie brauchen keine spezielle Users Klasse, wenn es nur eine Liste sein wird.

Ein anderer Weg:

class User: 
    all_users = [] 

    def __init__(self, id, email): 
     self.id = id # No need to call it user_id - it's a User object, after all! 
     self.email = email 
     self.all_users.append(self) #automatically add to list of all users 

    def __str__(self): 
     return '%s(%s)' % (self.id, self.email) 

Dann, wenn Sie die oben in user.py getippt:

 
>>> from user import * 
>>> bob = User('bob', '[email protected]') 
>>> alice = User('alice', '[email protected]') 
>>> for u in User.all_users: 
...  print u 
... 
bob([email protected]) 
alice([email protected]) 
>>> 

Nur ein Beispiel bekommen Sie denken.

+0

Sollte es nicht "self.all_users.append (self)" oder gar "A.all_users.append (self)" (beide funktionieren) statt "self.users.append (self)" sein? – voyager

+0

Ja, Tippfehler korrigiert. Danke für den Hinweis! –