2016-09-18 98 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

相关问题