在python中编写通讯录程序的问题

时间:2012-01-08 05:13:56

标签: python typeerror

我正在编写一个程序来添加和更新地址簿。这是我的代码:

EDITED

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 个答案:

答案 0 :(得分:4)

  1. addnewperson 应该将'self'作为第一个参数;实际上,名称无关紧要('self'只是一种约定),但第一个参数代表了对象本身。在您的情况下,它将 n 解释为“self”,将其他3解释为常规参数。

  2. ____ del____除了“自我”之外,不得接受论证。

  3. 编辑:BTW我在你的例子中发现了一些其他问题,也许你不知道:

    1)bookentry中的 d 是类成员,而不是实例成员。它由所有书籍实例共享。要创建实例成员,请使用:

    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)
    

    简要说明:对于具有OO语言背景没有多重继承的人来说,期望隐式调用超类型构造函数是自然而然的,如果没有人提到,则自动选择最合适的构造函数明确。但是,当一个类可以同时从两个或多个继承时,事情会变得混乱,因此Python需要程序员自己做出选择:首先调用哪个超类构造函数?或者根本没有?

    构造函数(和析构函数)的行为可能因语言而异。如果您对Python对象的生命周期有进一步的疑问,一个好的起点可能是hereherehere

答案 1 :(得分:4)

  
      
  1. 为什么d对象不是从bookentry()继承的?
  2.   

那是因为bookEntry的__init__没有在Person的__init__中调用:

super(Person, self).__init__()
顺便说一句,为什么如果不使用它的功能,继承dict?最好删除它并从对象继承(类名通常也是CamelCased):

class BookEntry(object):