Классы Python: как обрабатывать «будущие» экземпляры - PullRequest
0 голосов
/ 29 апреля 2018

Я учу себя Python (2.7, нет опыта программирования), и я только начал изучать классы и концепции ООП. В качестве упражнения я пытаюсь написать очень простую адресную книгу. Я думаю, что мне удалось понять основы классов и экземпляров, но мне трудно понять, как дальше развивать уровень абстракции в данный момент.

Попытка объяснить лучше, скажем, у меня есть это, которое часто является базовым примером, который многие учебные пособия используют для введения классов:

class Contact(object):    

    def __init__(self, name, surname, phone):

        self.name = name
        self.surname = surname
        self.phone = phone

contact1 = Contact('Mark', 'Doe', '123456789')
contact2 = Contact('Sally', 'Preston', '456789123')

Пока все хорошо, я могу сделать много других интересных вещей, используя contact1.attribute или другие методы. Здесь нет проблем.

Что мне трудно понять, так это:

Вопрос 1:

Я не знаю, сколько у меня будет контактов. Как мне создать метод, скажем, create_contact (), который заставляет меня создать новый контакт и сохранить его в списке / dict, если я не знаю, сколько у меня будет? Как я это называю? Я не могу понять, как сделать так, чтобы я мог создать новый экземпляр без жесткого кодирования его имени, такого как "contact1" и т. Д. Как сделать строку с "contact1" и "contact2" динамической вещь

Я попытался решить проблему, используя список в качестве переменной класса. Что-то вроде (при условии, что "contact_list" уже существует как переменная класса):

Contact.contact_list.append(Contact('Mark', 'Doe','123456789')) # obviously I'd use raw_input instead of 'Mark' etc, but I avoided it here for readability

Но я получаю список безымянных объектов, и моему мозгу трудно с этим справиться. Я могу получить к ним доступ с помощью индексов списков, но я не уверен, что нахожусь на правильном пути ... любая помощь будет наиболее ценной.

Вопрос 2: (несколько связанный, чтобы лучше понять проблему)

если в CLI Python я добавлю что-то вроде (при условии, что предыдущий блок, определяющий класс, уже был запущен):

>>> Contact('Bob', 'Stevens', '32165497')

Насколько я понимаю, экземпляр Contact () действительно создается с этими атрибутами ... но у него нет имени. Как мне получить к нему доступ? (Как я узнаю, что он существует? Есть ли способ перечислить все существующие экземпляры, относящиеся к определенному классу?)

Надеюсь, я понял. Заранее благодарим за любую помощь.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Нет ничего плохого в том, что в коллекции хранятся "безымянные" экземпляры, но я согласен, что поначалу может быть сложно обернуть голову. ;) Вам не нужно знать, сколько контактов вы будете создавать, поскольку все типы коллекций Python являются динамическими, поэтому вам не нужно заранее указывать размер, они будут увеличиваться для размещения данных, которые вы вводите. их.

Вот демонстрационная программа, использующая ваш класс Contact для создания простой телефонной книги в словаре списков. Мы сохраняем каждый контакт как под именем, так и по фамилии, чтобы найти контакты по любому имени. Значения словаря являются списками, поэтому мы можем работать с несколькими людьми с одинаковыми именами.

Я добавил __repr__ метод к Contact, чтобы упростить отображение содержимого Contact экземпляра.

from collections import defaultdict

class Contact(object):
    def __init__(self, name, surname, phone):
        self.name = name
        self.surname = surname
        self.phone = phone

    def __repr__(self):
        return '{name} {surname}: {phone}'.format(**self.__dict__)

phonebook = defaultdict(list)

data = [
    ('Mark', 'Doe', '123456789'),
    ('Sally', 'Preston', '456789123'),
    ('John', 'Doe', '789123456'),
]

for name, surname, phone in data:
    contact = Contact(name, surname, phone)
    phonebook[name].append(contact)
    phonebook[surname].append(contact)

for key, val in phonebook.items():
    print(key, val)

выход

Mark [Mark Doe: 123456789]
Doe [Mark Doe: 123456789, John Doe: 789123456]
Sally [Sally Preston: 456789123]
Preston [Sally Preston: 456789123]
John [John Doe: 789123456]

Другой вариант - сделать phonebook атрибутом класса Contact.


Конечно, чтобы сделать эту программу действительно полезной, нам необходимо сохранить телефонную книгу на диск и загрузить ее обратно. Для этого есть различные способы, например: сохраняя данные в файл CSV или JSON или в файл pickle. Но это темы для другого вопроса. ;)

0 голосов
/ 29 апреля 2018

Q1 : Вы можете создать другой класс, который будет служить базой данных

class Contact(object):    
    def __init__(self, name, surname, phone):
        self.name = name
        self.surname = surname
        self.phone = phone

class ContactDatabase:
    def __init__(self, *args):
        self.inner_list = list(args)

    def add_contact(self, new_contact):
        self.inner_list.append(new_contact)


# Initial contacts
contact1 = Contact('Mark', 'Doe', '123456789')
contact2 = Contact('Sally', 'Preston', '456789123')

# Creating a database
my_database = ContactDatabase(contact1, contact2)

# Adding new contacts later
my_database.add_contact(Contact('Jim', 'Miller', '111223123'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...