2016-09-18 99 views
0

我重新編寫了整個類從頭開始在一個單獨的文件和一切神奇的工作,條件和所有。所以,我只是將這個類和幾個函數從新文件導入到主文件中。我仍然不知道第一次出了什麼問題。Python - 對象沒有任何屬性錯誤

請注意下面的問題在技術上解決。您可以看到代碼底部的錯字。然而,這其中發現我所有的條件語句(如,嘗試等)停止運作的問題,這就是爲什麼我重新寫了類在一個單獨的模塊

刪除,因爲這個職位它讓所有人都無處可去,但顯然,這並不是Stack Overflow的工作方式。

好的,我一直在學習Python 3.4,並決定在練習時做一些功課。我開始製作一個腳本,對2個人的戰鬥進行了非常基本的模擬,並且可以使用我學習的任何新東西(例如添加GUI)來擴展它。

該腳本開始正常,但我做出更多的更改開始出現更多的錯誤。現在是到了我無法訪問「戰鬥機」類的任何領域,沒有它拋出類似的錯誤點:

'duelist' object has no attribute '_duelist__health' 

除了「‘決鬥’對象有沒有屬性‘_duelist__XXX’」,我除了錯別字之外,還有其他0個錯誤。 谷歌遺憾地無法幫助這個,所以這就是我製作第一個StackOverflow文章的原因。

這裏的節課下來的第一個錯誤快樂領域,「健康」:

class duelist: 
    def __init__(self): 
     self.name = "Duelist" #must not be "" 
     self.health = 5 #must be >0 
     self.damage = [1, 3] #random attack range. Must be >=0 0 and the first must not be higher. 
     self.skill = 10 #% chance to pass a skill check. Representative of parrying/dodging. Must be >=0 
     self.shield = True #can block? 
     self.shieldE = 80 #max block %. Must be >0 
     self.agility = 0.5 #rate of attack in seconds. Must be >=0.05 
     self.precision = 10 #critical hit chance. Must be >=0 
     self.critical = 2.0 #critical multiplier. Must be >= 1.1 


    #name 
    @property 
    def name(self): 
     return self.__name 

    @name.setter 
    def name(self, value): 
     if value != "": 
      self.__name = value 
     else: 
      print("Invalid Name.\n") 
    #name 

    #health 
    @property 
    def health(self): 
     return self.__health 

    @health.setter 
    def health(self, value): 
     try: 
      value = value(int) 
      if value>=1: 
       self.__health = value 
      else: 
       print("Health must be above 0.\n") 
     except: 
      print("Invalid Health.\n") 
    #health 

此外,對於那些建議更改的字段名稱不包含「__」(或者包括一個' __'無處不在),導致無限循環。 打字正是這一點:

class duelist: 
    def __init__(self): 
     self.health = 5 

    @property 
    def health(self): 
     return self.__health 

    @health.setter 
    def health(self, value): 
     self.__health = value 

D = duelist() 
print(D.health) 
D.health = 15 
print(D.health) 

正確返回

5 
15 
+1

您不應該將'health'屬性作爲'self .__ health'來訪問。改用'self.health'。從你的代碼看,你應該改變訪問'name'的方式。 – TuanDT

+0

請更正您的縮進。另外,請提供證明問題的[mcve]。我們不會爲您掃描整個代碼。 – MattDMo

+0

你能發佈展示問題的代碼嗎?我無法用問題中發佈的代碼複製問題。另外,你確定你正在使用Python 3嗎?如果使用Python 2,則必須從'object'派生類才能使屬性正常工作。 – mhawke

回答

3

你的代碼做:

  1. 設置的.name =__init__()
  2. 即通過setter雲的價值,並設置.__name =
  3. 當您.name通過吸氣讀,讀.__name

和你的問題的說明「我不能訪問任何領域的‘戰鬥機’級」,我懷疑是錯誤的閱讀,因爲訪問他們的一些工作。

健康不,雖然和第45行上你有這樣的:

value = value(int) 

代替

value = int(value) 

所以引起吸氣拋出一個異常,print("Invalid Health.\n")__health從未組。

隨着self.shield = True,設置器試圖做:

if value.lower() == 'y': 

,你不能在一個布爾叫lower(),所以它崩潰了以往任何時候都得到嘗試type(value) == bool面前,__shield從未設置。

0

例外情況可能會導致如果您的班級未在其__init__()方法中定義屬性__health。試圖閱讀它的價值會觸發問題。該屬性將通過調用setter方法(間接通過屬性分配)創建,之後該屬性變爲可用。

這裏是你的類的簡化版本:

class Duelist: 
    def __init__(self): 
#  self.health = 5 
     pass 

    @property 
    def health(self): 
     return self.__health 

    @health.setter 
    def health(self, value): 
     self.__health = value 

>>> d = Duelist() 
>>> d.health 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "p.py", line 9, in health 
    return self.__health 
AttributeError: 'Duelist' object has no attribute '_Duelist__health' 
>>> d.health = 123 
>>> d.health 
123 

所以一個修復它是使用相同名初始化屬性的方法:

class Duelist: 
    def __init__(self): 
#  self.health = 5 # this will also work 
     self.__health = 5 

>>> d.health 
5 
>>> d.health = 123 
>>> d.health 
123 

因此,考慮到如果您未初始化屬性(self.health)或基礎屬性(self.__health),則會引發異常,您是否發佈了導致問題的實際代碼?

+0

@FierySwordswoman:對不起,我的錯誤,我發佈的代碼並沒有引發我所展示的異常。引發該異常的代碼省略了__init __()方法。這是我能夠複製您的問題的唯一方法。 – mhawke

+0

@FierySwordswoman:我更新了導致問題的代碼。 – mhawke

+0

@FierySwordswoman:我認爲['TessellatingHeckler的答案'](http://stackoverflow.com/a/39553785/21945)解釋了爲什麼該屬性沒有在'__init __()'中設置。你現在有什麼問題? – mhawke

相關問題