2012-08-25 39 views
0

下面的代碼我有__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當我輸入的名稱?

+1

爲什麼你重寫'__setattr__'?也許更好的辦法是在'Solider'或'officer'類中爲'__init__'方法添加一些邏輯。 –

+2

與其使用'setattr'來檢查參數有效性,你應該使用屬性設置器。 –

回答

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 [.....] 
0

你當Officer的任何屬性被以任何方式初始化過程中通過超__init__設置在任何時候,包括__setattr__被調用。

__setattr__被調用時,self將是Officer實例,rank將是名稱的屬性的設定,和value將期望針對歸因值。

你所做的是使Officer類,使得它可以對您的列表中值的.lieutenant等,但沒有一個.rank(或.name.gender) - 你並沒有真正限制該屬性的值在所有。

這是比你想要的更深的魔法;您顯然想限制在設置.rank屬性時特別使用。要做到這一點,請使用屬性。