Python classes: how to handle “future” instances
我正在自学Python(2.7,没有以前的编码经验),我刚刚开始处理类和OOP概念。作为练习,我试图编写一个非常简单的通讯簿。我认为我已经设法理解了类和实例的基本知识,但是我发现很难理解的是如何在这一点上进一步开发抽象的层次。
尝试更好地解释,假设我有这个,这通常是许多教程用来介绍类的基本示例:
1 2 3 4 5 6 7 8 9 10 | 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"的行成为动态的东西?
我试图用一个列表作为类变量来解决这个问题。类似(假设"联系人列表"已经作为类变量存在):
1 | 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中我放置了类似的内容(假设定义类的前一个块已经运行了):
1 | >>> Contact('Bob', 'Stevens', '32165497') |
我的理解是contact()的一个实例确实是用这些属性创建的…但它没有名字。如何访问它?(我怎么知道它的存在呢?是否有方法列出与某个类相关的所有现有实例?)
我希望我说得有道理。事先谢谢你的帮助。
将"无名"实例存储在集合中并没有什么错,但我同意,一开始很难让您全神贯注。;)您不需要知道要创建多少联系人,因为python集合类型都是动态的,所以您不需要事先指定大小,它们将增长以适应您提供的数据。
这是一个使用联系人类在列表字典中创建简单电话簿的演示。我们将每个联系人都保存在名字和姓氏下,这样我们就可以按任一名称查找联系人。字典的值是列表,因此我们可以处理多个同名的人。
我在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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) |
输出
1 2 3 4 5 | Mark [Mark Doe: 123456789] Doe [Mark Doe: 123456789, John Doe: 789123456] Sally [Sally Preston: 456789123] Preston [Sally Preston: 456789123] John [John Doe: 789123456] |
另一种选择是使
当然,要使这个程序真正有用,我们需要能够将电话簿保存到磁盘上,并能够将其重新加载。有多种方法可以做到这一点,例如将数据保存到csv或json文件,或保存到
Q1:您可以创建另一个将用作数据库的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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')) |