我正在自学 Python(2.7,以前没有编码经验),我刚刚开始处理类和 OOP 概念。作为练习,我正在尝试编写一个非常简单的地址簿。我想我设法理解了类和实例的基础知识,但我发现很难掌握的是此时如何进一步发展抽象级别。
为了更好地解释,假设我有这个,这通常是许多教程用来介绍类的基本示例:
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(),让我创建一个新联系人并将其存储在列表/字典中?我怎么调用它? 我不明白如何创建一个新实例而无需对其名称进行硬编码,例如“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:(有点相关,为了更好地理解问题)
如果在 python CLI 中我放了类似的东西(假设定义类的前一个 block 已经运行):
>>> Contact('Bob', 'Stevens', '32165497')
我的理解是确实创建了一个具有这些属性的 Contact() 实例……但它没有名称。我如何访问它? (我怎么知道它存在?有没有办法列出与某个类相关的所有现有实例?)
希望我说得有道理。在此先感谢您提供的任何帮助。
最佳答案
将“无名”实例存储在集合中并没有错,但我同意一开始可能很难理解。 ;) 你不需要知道你将创建多少联系人,因为 Python 集合类型都是动态的,所以你不需要提前指定大小,它们会增长以容纳你提供的数据他们。
这是一个使用您的 Contact 类在列表字典中创建简单电话簿的演示。我们将每个联系人都保存在名字和姓氏下,因此我们可以按任一姓名查找联系人。字典的值是列表,因此我们可以处理多个同名的人。
我向 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
的类属性。
当然,要使这个程序真正有用,我们需要能够将电话簿保存到磁盘,并能够将其重新加载。有多种方法可以做到这一点,例如,通过将数据保存到 CSV 或 JSON 文件,或保存到 pickle
文件。但这些是另一个问题的主题。 ;)
关于Python 类 : how to handle "future" instances,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50087845/