我正在自学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中,我放了类似的东西(假设定义类的上一个块已经运行(:
>>> 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
文件。但这些都是另一个问题的主题。;)
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'))