在Python中实践继承:为什么AttributeError,尽管我的类和属性似乎设置正确?

时间:2016-09-18 18:02:26

标签: python python-2.7 inheritance

我为我的Python项目(练习继承)设置了以下文件/文件夹,如下所示:

my_project/new_classes.py
my_project/human/Human.py
my_project/human/__init__.py (note, this is a blank file)

虽然我的class Samurai(Human)设置正确,但我收到以下错误:

line 41, in <module>
tom.sacrifice()
AttributeError: 'Samurai' object has no attribute 'sacrifice'

这是我my_project/new_classes.py文件中的代码:

from human.Human import Human
class Wizard(Human):
    def __init__(self):
        super(Wizard, self).__init__()   
        self.intelligence = 10           
    def heal(self):
        self.health += 10
class Ninja(Human):
    def __init__(self):
        super(Ninja, self).__init__()    
        self.stealth = 10                
    def steal(self):
        self.stealth += 5
class Samurai(Human):
    def __init__(self):
        super(Samurai, self).__init__()  
        self.strength = 10               
    def sacrifice(self):
        self.health -= 5
# create new instance of Wizard, Ninja, and Samurai
harry = Wizard()
rain = Ninja()
tom = Samurai()
print harry.health
print rain.health
print tom.health
harry.heal()
print harry.health
rain.steal()
print rain.stealth
tom.sacrifice()
print tom.health
print tom.stealth

代码在到达tom.sacrifice()行时会中断 - 有什么想法吗?

我最初遇到的另一个问题是,在尝试导入父类时,我使用了from human import Human语句,我认为该语句可行(因为我认为该公式来自module_directory import ModuleFileName,但是收到了如下错误:TypeError: Error when calling the metaclass bases module.__init__() takes at most 2 arguments (3 given)。我通过将导入语句更改为from human.Human import Human来解决这个问题,并且想知道为什么这个有效,而另一个没有?我可能对正确导入类感到困惑,并希望有人也可以帮助澄清。

[编辑]删除了评论。

3 个答案:

答案 0 :(得分:1)

  

我通过将我的import语句更改为human.Human import Human来解决这个问题,并且想知道为什么这个有效而另一个没有?

这是因为第一个“Human”是你的Python模块(Human.py)。 Human类在其中,所以这就是你的import语句必须像你上次写的那样。您不想导入模块,而是导入类。

至于你的AttributeError问题,因为你的课程似乎没问题,这很奇怪。在Human类中,这可能是不寻常的。我们可以在其中加入代码吗?

修改

我看到你找到了AttributeError问题的解决方案,所以我只留下第二个问题的答案。

答案 1 :(得分:0)

如果在同一文档中初始化该类,则运行以下代码。您收到错误的原因是您尝试更改在初始化期间从未设置的变量。

class Human(object):
    def __init__(self):
        self.health = 100
        self.stealth = 0
        self.strength = 15

您必须初始化变量。确保每个Human都具有您想要更改的属性。您可以设置=运行状况,但如果未初始化则不会更改-=5

答案 2 :(得分:0)

我找到了我的解决方案,在我的Samurai方法中,我有一个间距问题!

我使用适当的标签重新格式化了我的代码,一切正常!

正确的代码如下:

class Samurai(Human):
    def __init__(self):
        super(Samurai, self).__init__()  # use super to call the Human __init__ method
        self.strength = 10               # every Samurai starts off with 10 strength
    def sacrifice(self):
        self.health -= 5