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



我正在自学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'))

最新更新