用Python编写通讯录程序的问题
我正在写一个程序,用来添加和更新通讯录。以下是我的代码:
已编辑
import sys
import os
list = []
class bookEntry(dict):
total = 0
def __init__(self):
bookEntry.total += 1
self.d = {}
def __del__(self):
bookEntry.total -= 1
list.remove(self)
class Person(bookEntry):
def __init__(self, n):
self.n = n
print '%s has been created' % (self.n)
def __del__(self):
print '%s has been deleted' % (self.n)
def addnewperson(self, n, e = '', ph = '', note = ''):
self.d['name'] = n
self.d['email'] = e
self.d['phone'] = ph
self.d['note'] = note
list.append()
def updateperson(self):
key = raw_input('What else would you like to add to this person?')
val = raw_input('Please add a value for %s' % (key))
self.d[key] = val
def startup():
aor = raw_input('Hello! Would you like to add an entry or retrieve one?')
if aor == 'add':
info = raw_input('Would you like to add a person or a company?')
if info == 'person':
n = raw_input('Please enter this persons name:')
e = raw_input('Please enter this persons email address:')
ph = raw_input('Please enter this persons phone number:')
note = raw_input('Please add any notes if applicable:')
X = Person(n)
X.addnewperson(n, e, ph, note)
startup()
当我运行这段代码时,出现了以下错误:
in addnewperson
self.d['name'] = n
AttributeError: 'Person' object has no attribute 'd'
我有两个问题:
更新的问题
1. 为什么d
这个对象没有从 bookentry()
继承呢?
我知道这个问题和代码比较长,但我不知道接下来该怎么做。任何帮助都将非常感谢。
2 个回答
- 为什么d对象没有从bookentry()继承呢?
这是因为在Person的__init__方法里没有调用bookEntry的__init__方法:
super(Person, self).__init__()
顺便问一下,如果不使用字典(dict)的功能,为什么还要继承它呢?不如去掉它,直接继承自object类会更好(而且类名通常是大写驼峰式命名):
class BookEntry(object):
addnewperson 方法的第一个参数应该是 'self';其实名字并不重要('self' 只是个约定),但第一个参数代表的是对象本身。在你的例子中,它把 n 解释成了 "self",而其他三个参数则被当作普通参数。
____del____ 方法除了 'self' 之外不能接受其他参数。
补充:顺便说一下,我在你的例子中发现了一些其他问题,可能你还没有注意到:
1) d 在 bookentry 中是一个类成员,而不是实例成员。它是所有 bookentry 实例共享的。要创建一个实例成员,可以使用:
class bookentry(dict):
def __init__(self,n):
self.d = {}
# rest of your constructor
2) 你试图直接访问 d(就像在 Java、C++ 等语言中那样),但 Python 不支持这样做。你必须在方法中有一个 'self' 参数,并通过它来访问实例变量:
class person(bookentry):
def foo(self,bar):
self.d[bar] = ...
person().foo(bar)
更新:关于最后一个问题,解决方案是显式调用父类构造函数(在 Python 中必须这样做):
class Person(bookEntry):
def __init__(self, n):
super(Person, self).__init__()
self.n = n
print '%s has been created' % (self.n)
简单解释一下:对于没有多重继承背景的面向对象语言的人来说,期望父类构造函数被隐式调用是很自然的,自动选择最合适的一个,如果没有明确提到的话。然而,当一个类可以同时继承两个或多个类时,事情就会变得复杂,因此 Python 要求程序员自己做出选择:要先调用哪个父类构造函数?或者根本不调用?
构造函数(和析构函数)的行为在不同语言中可能差异很大。如果你对 Python 对象的生命周期还有其他问题,可以从 这里、这里 和 这里 开始了解。