Python类:如何处理“未来”实例

时间:2018-04-29 14:48:49

标签: python class oop instance

我自学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()实例,并使用这些属性...但它没有名称。我该如何访问它? (我怎么知道它存在?有没有办法列出相对于某个类的所有现有实例?)

我希望我有所了解。提前感谢您的任何帮助。

2 个答案:

答案 0 :(得分:2)

拥有"无名"没有错。存储在集合中的实例,但我同意最初可能难以理解。 ;)您不需要知道您将要创建多少联系人,因为Python集合类型都是动态的,因此您不需要提前指定大小,他们是'我会逐渐适应你喂它们的数据。

这是一个使用您的Contact类在列表字典中创建简单电话簿的演示。我们以名字和姓氏保存每个联系人,因此我们可以通过任一名称查找联系人。字典的值是列表,因此我们可以处理多个具有相同名称的人。

我向__repr__添加了Contact方法,以便于显示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文件。但这些是另一个问题的主题。 ;)

答案 1 :(得分:0)

<强> Q1 : 您可以创建另一个将用作数据库的类

Path directory = ...;
Files.walk(directory)
     .forEach(p -> {
         try {
                // same code ....
         } catch (IOException e) {
             // FIXME to handle
         }

     });