Вопрос дизайна класса новичка Python - PullRequest
6 голосов
/ 20 января 2010

Я пытаюсь выяснить, как лучше спроектировать пару классов. Я довольно плохо знаком с 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 = 'bob@example.com')

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

for u in users.users:
    print u.email

"users.users" кажется немного избыточным. Я правильно это делаю?

Ответы [ 5 ]

17 голосов
/ 20 января 2010

Я бы сказал, не совсем. Ваш класс 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 = 'bob@example.com'))

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
11 голосов
/ 20 января 2010

Поместите это в ваш Users:

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

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

for u in users:
    print u.email

Docs

6 голосов
/ 20 января 2010

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

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 = 'bob@example.com'))

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

4 голосов
/ 20 января 2010

Я не вижу ничего плохого в 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__ заставляет ваш объект вести себя как итератор

1 голос
/ 20 января 2010

Здесь нет «черного» и «белого», только оттенки серого. Вам не нужен специальный класс 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', 'bob@test.com')
>>> alice = User('alice', 'alice@test.com')
>>> for u in User.all_users:
...     print u
...
bob(bob@test.com)
alice(alice@test.com)
>>>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...