2010-01-20 11 views
6

Estoy tratando de encontrar la mejor manera de diseñar un par de clases. Soy bastante nuevo en Python (y OOP en general) y solo quiero asegurarme de estar haciendo esto bien. Tengo dos clases: "Usuarios" y "Usuario".Pregunta de diseño de clase para principiantes de Python

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

Si quiero recuperar mis usuarios, utilizo:

for u in users.users: 
    print u.email 

"users.users" parece ser un poco redundante. ¿Lo estoy haciendo bien?

Respuesta

11

Ponga esto en su Users:

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

Ahora usted puede:

for u in users: 
    print u.email 

Docs

6

Es probable que desea es una lista de los objetos de usuario en lugar de una clase que contiene múltiples usuarios .

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

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

Todos los atributos de miembro para el usuario deberían residir en la clase de usuario, no en la clase de usuarios.

4

No veo nada malo con usuarios.usuarios, pero si prefiere una manera más agradable de hacerlo, puede anular __iter__ en Usuarios.

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) 

Ahora usted puede hacer esto:

for u in users: 
    print u.email 

El método especial __iter__ hace que su objeto se comportan como un iterador

17

no diría realmente. Su clase Users parece ser solo una lista de usuarios, así que simplemente la convertiría en una lista en lugar de una clase completa. Esto es lo que yo haría:

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 

Si desea Users a ser una clase propia por alguna otra razón, usted podría tener que herede de list, o (si no) se podría añadir estos a la definición:

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

esta manera, se puede decir simplemente:

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

TypeError: iteración sin secuencia: si usa + = la RHS también debe ser una lista. – Jorenko

1

no hay "negro" y "blanco" aquí, sólo matices de gris. No necesita una clase especial Users si solo va a ser una lista.

Otra forma:

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) 

Entonces, si ha escrito lo anterior en user.py:

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

Sólo un ejemplo para hacerle pensar.

+0

¿No debería ser 'self.all_users.append (self)' o incluso 'A.all_users.append (self)' (ambos funcionan) en lugar de 'self.users.append (self)'? – voyager

+0

Sí, ahora se corrigió el error tipográfico. Gracias por el consejo! –