Python 类: 如何处理 "future" 个实例

Python classes: how to handle "future" instances

我正在自学 Python(2.7,以前没有编码经验)并且我刚刚开始处理 classes 和 OOP 概念。作为练习,我正在尝试编写一个非常简单的地址簿。我想我设法理解了 classes 和实例的基础知识,但我发现很难掌握的是此时如何进一步发展抽象级别。

试图更好地解释,说我有这个,这通常是许多教程用来介绍的基本示例 classes:

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 或其他方法做很多其他有趣的事情。这里没问题。

我无法理解的是:

问题一:

我不知道我会有多少联系人。如果我不知道我将拥有多少个联系人,我该如何创建一个方法,例如 create_contact(),让我创建一个新联系人并将其存储在 list/dict 中?我怎么称呼它? 我不明白如何制作它以便我可以在不硬编码其名称的情况下创建一个新实例,例如 "contact1" 等。 我如何制作带有 [=46 的行=] 和 "contact2" 动态的东西?

我尝试使用列表作为 class 变量来解决问题。类似的东西(假设 "contact_list" 已经作为 class 变量存在):

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:(有点相关,以便更好地理解问题)

如果在 python CLI 中我放了类似的东西(假设定义 class 的前一个块已经 运行):

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

我的理解是确实创建了一个具有这些属性的 Contact() 实例……但它没有名称。我如何访问它? (我怎么知道它存在?有没有办法列出与某个 class 相关的所有现有实例?)

我希望我说得有道理。在此先感谢您提供任何帮助。

Q1: 您可以创建另一个 class 作为数据库

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

将 "nameless" 个实例存储在集合中并没有错,但我同意一开始可能很难理解。 ;) 您不需要知道要创建多少联系人,因为 Python 集合类型都是动态的,所以您不需要提前指定大小,它们会增长以适应您提供给他们的数据。

这是一个演示,它使用您的联系人 class 在列表字典中创建一本简单的 phone 书。我们将每个联系人都保存在名字和姓氏下,因此我们可以按任一姓名查找联系人。字典的值是列表,因此我们可以处理多个同名的人。

我在 Contact 中添加了一个 __repr__ 方法,以便于显示 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 的 class 属性。


当然,为了让这个程序真正有用,我们需要能够将phone这本书保存到磁盘,并且能够将它加载回来in. 有多种方法可以做到这一点,例如将数据保存到 CSV 或 JSON 文件,或保存到 pickle 文件。但这些是另一个问题的主题。 ;)