__setattr__打破代码?

时间:2012-08-25 22:22:24

标签: python setattr

这是我的代码

class Human(object):
  def __init__(self, name, gender):
    self.name = name
    self.gender = gender
    print 'Hi there, I am '+ self.name

  def ThankHeavens(self):
    return 'Thanks Gods!'

class Soldier(Human):
  def __init__(self, name, gender, rank):
    super(Soldier, self).__init__(name, gender)
    self.rank = rank
    print self.rank + ' reporting!'

class Officer(Soldier):
  def __init__(self, name, gender, rank, num_subordinates):
    super(Officer, self).__init__(name, gender, rank)
    self.num_subordinates = num_subordinates

  def __setattr__(self, rank, value):
    if rank not in ['lieutenant', 'captain', 'major', 'colonel', 'commander', 'admiral']:
      print 'Invalid officer rank'
    else:
      super(Officer, self).__setattr__(rank, value)

每当我尝试创建一名军官时,它就会中断:

helo = Officer(name='Agathon',
               gender='m',
               rank='lieutenant',
               num_subordinates=0)

Traceback (most recent call last):
  File "hw7.py", line 39, in <module>
    num_subordinates=0)
  File "hw7.py", line 20, in __init__
    super(Officer, self).__init__(name, gender, rank)
  File "hw7.py", line 14, in __init__
    super(Soldier, self).__init__(name, gender)
  File "hw7.py", line 7, in __init__
    print 'Hi there, I am '+ self.name
AttributeError: 'Officer' object has no attribute 'name'

为什么它不能识别我在定义helo时输入的名称?

2 个答案:

答案 0 :(得分:5)

您尚未发布的内容是__setattr__

创建的两条消息
Invalid officer rank
Invalid officer rank

这些来自以下几行:

self.name = name
self.gender = gender

由于这些失败,您无法在以后检索该名称:

 print 'Hi there, I am '+ self.name

修正:

def __setattr__(self, key, value):
    if key == "rank" and value not in [.....]

答案 1 :(得分:0)

__setattr__的任何属性随时以任何方式设置时,包括在通过超类Officer进行初始化期间,都会调用__init__

调用__setattr__时,self将是Officer个实例,rank将是要设置的属性的名称,并且value将是该归因所需的值。

您所做的就是让Officer课程对您的列表中的值设置为.lieutenant等,而不是.rank(或.name.gender) - 您根本没有实际限制该属性的值。

这比你想要的更深刻;您明确希望限制在专门设置.rank属性时使用的。为此,请使用属性。