2010-01-20 3 views
6

Я пытаюсь найти лучший способ разработать пару классов. Я довольно новичок в Python (и OOP в целом) и просто хочу убедиться, что я делаю это правильно. У меня есть два класса: «Пользователи» и «Пользователь».Python newbie class design question

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

Если я хочу, чтобы получить мои пользователи, я использую:

for u in users.users: 
    print u.email 

"users.users", кажется, немного излишним. Правильно ли я это делаю?

ответ

11

это в вашем Users:

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

Теперь вы можете:

for u in users: 
    print u.email 

Docs

6

Вы, вероятно, просто хотите получить список объектов пользователя, а не класс, который содержит несколько пользователей ,

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

Все атрибуты участника для пользователя должны находиться в классе User, а не в классе Users.

4

Я не вижу ничего плохого в users.users, но если вы предпочитаете более удобный способ сделать это, вы можете переопределить __iter__ в Users.

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) 

Теперь вы можете сделать это:

for u in users: 
    print u.email 

__iter__ специального метод делает ваш объект вести себя как итератор

17

Я бы сказал, не совсем. Ваш класс Users представляется просто списком пользователей, поэтому я бы просто сделал его списком, а не целым классом. Вот что я хотел бы сделать:

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 

Если вы хотите Users быть классом своих собственных по какой-то другой причине, вы могли бы его наследовать от list, или (если нет), вы можете добавить их к определению:

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

Таким образом, вы можете просто сказать:

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

TypeError: итерация без последовательности - если вы используете + = RHS также должен быть списком. – Jorenko

1

Там нет "черного" и "белого" здесь, только оттенки серого. Вам не нужен специальный класс Users, если он просто будет списком.

Другой способ:

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) 

Затем, если вы ввели выше в 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]) 
>>> 

Просто пример, чтобы вы думали.

+0

Не должно быть 'self.all_users.append (self)' или даже 'A.all_users.append (self)' (оба работают) вместо 'self.users.append (self)'? – voyager

+0

Да, опечатка теперь исправлена. Спасибо за подсказку! –