Python类继承AttributeError - 为什么?怎么修? [英] Python Class Inheritance AttributeError - why? how to fix?

查看:113
本文介绍了Python类继承AttributeError - 为什么?怎么修?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SO上的类似问题包括:这一个。我也阅读了所有的在线文档,我可以找到,但我还是很困惑。我将感谢您的帮助。



我想在我的CastSpell类lumus方法中使用Wand类.wandtype属性。但我不断得到错误AttributeError:'CastSpell'对象没有属性'wandtype'。



此代码的工作原理:

  class Wand(object):
def __init __(self,wandtype,length):
self.length = length
self.wandtype = wandtype

def fulldesc(self):
print 这是一个%s魔杖,它是一个%s长%(self.wandtype,self.length)

类CastSpell(对象):
def __init __(self,spell,事物):
self.spell = spell
self.thing = thing

def lumus(self):
print你用你的魔法施放法术%s at%s%(self.spell,self.thing)

def wingardium_leviosa(self):
print你施放了悬浮法术。

my_wand = Wand('Phoenix-feather','12 inches')
cast_spell = CastSpell('lumus','door')
my_wand.fulldesc $ b cast_spell.lumus()

这个代码,

  class Wand(object):
def __init __(self,wandtype,length):
self。 length = length
self.wandtype = wandtype

def fulldesc(self):
print这是一个%s魔杖,它是一个%s长%(self。 wandtype,self.length)

class CastSpell(Wand):
def __init __(self,spell,thing):
self.spell = spell
self.thing = thing

def lumus(self):
print你用%s的魔杖在%s处施法法术%s%(self.spell,self.wandtype,self.thing )#这行导致AttributeError!
print房间亮起来了。

def wingardium_leviosa(self):
print你施放了悬浮法术。

my_wand = Wand('Phoenix-feather','12 inches')
cast_spell = CastSpell('lumus','door')
my_wand.fulldesc $ b cast_spell.lumus()



我试过使用super()方法无效。我真的很感谢你的帮助理解a)为什么类继承不工作在这种情况下,b)如何让它工作。

解决方案

简单来说,您可以覆写 Wand .__ init __ 类,因此 CastSpell.wandtype 从不在 CastSpell 中设置。除此之外, my_wand 不能将信息传递到 cast_spell ,所以你对继承的作用感到困惑。 / p>

无论如何,你必须通过 length wandtype CastSpell 。一种方法是将它们直接包含到 CastSpell .__ init __

  class CastSpell(Wand):
def __init __(self,spell,thing,length,wandtype):
self.spell = spell
self.thing = thing
self.length = length
self.wandtype = wandtype

另一个更通用的方法是传递这两个到基类的 __ init __()

  class CastSpell Wand):
def __init __(self,spell,thing,length,wandtype):
self.spell = spell
self.thing = thing
super(CastSpell,self)。 __init __(length,wandtype)

另一种方法是停止制作 CastSpell 继承 Wand CastSpell 一种 Wand ?或某事a Wand 会吗?),而让每个魔杖能够有一些 CastSpell 代替is-a( CastSpell 是一种 Wand ),请尝试has -a(a Wand Spell s)。



这里有一个简单的,不是很好的方法有一个魔杖商店法术:

  class Wand(object):
def __init __(self,wandtype,length):
self.length = length
self.wandtype = wandtype
self.spells = {}#我们的法术的容器。
#你也可以直接添加:my_wand.spells ['accio'] = Spell(aguamenti,fire)

def fulldesc这是一个%s魔杖,它是一个%s长%(self.wandtype,self.length)

def addspell(self,spell):
self.spells [ name] = spell

def cast(self,spellname):
检查请求的法术是否存在,然后调用它的cast方法。
如果self.spells中的spellname:#按名称检查存在
spell = self.spells [spellname]#检索之前添加的法术,将其命名为spell
spell.cast(self.wandtype) #调用该法术的cast方法,将wandtype作为参数传递
else:
print这个魔杖没有%s法术。 %spellname
print可用法术:
print\\\
.join(sorted(self.spells.keys()))


(object):
def __init __(self,name,target):
self.name = name
self.target = target

def cast(self,wandtype =):
print你用%s的魔杖在%s施法术%s。 %(
self.name,wandtype,self.target)
如果self.name ==lumus:
print房间亮起来。
elif self.name ==wingardium leviosa:
print你施放悬浮法术。,
print%s开始浮动! %self.target

def __repr __(self):
return self.name

my_wand = Wand('Phoenix-feather','12 inches')
lumus = Spell('lumus','door')
wingardium = Spell(wingardium leviosa,enemy)

my_wand.fulldesc .cast()#不是从魔杖!也就是说,我们直接调用Spell.cast
print\\\
\\\


my_wand.addspell(lumus)#与my_wand.spells [lumus] = lumus
my_wand.addspell(wingardium)
print\\\
\\\


my_wand.cast(lumus)#与my_wand.spells [lumus]相同.cast(my_wand.wandtype)
print\\\
\\\

my_wand.cast(wingardium leviosa)
print\\\
\\\

my_wand.cast(avada kadavra)#Wand.cast中的检查失败,打印拼写列表
print\\\
\\\


Similar questions on SO include: this one and this. I've also read through all the online documentation I can find, but I'm still quite confused. I'd be grateful for your help.

I want to use the Wand class .wandtype attribute in my CastSpell class lumus method. But I keep getting the error "AttributeError: 'CastSpell' object has no attribute 'wandtype'."

This code works:

class Wand(object):
    def __init__(self, wandtype, length):
        self.length = length 
        self.wandtype = wandtype

    def fulldesc(self):
        print "This is a %s wand and it is a %s long" % (self.wandtype, self.length) 

class CastSpell(object):
    def __init__(self, spell, thing):
        self.spell = spell 
        self.thing = thing

    def lumus(self):
        print "You cast the spell %s with your wand at %s" %(self.spell, self.thing) 

    def wingardium_leviosa(self): 
        print "You cast the levitation spell."

my_wand = Wand('Phoenix-feather', '12 inches') 
cast_spell = CastSpell('lumus', 'door') 
my_wand.fulldesc()  
cast_spell.lumus() 

This code, with attempted inheritance, doesn't.

class Wand(object):
    def __init__(self, wandtype, length):
        self.length = length 
        self.wandtype = wandtype

    def fulldesc(self):
        print "This is a %s wand and it is a %s long" % (self.wandtype, self.length) 

class CastSpell(Wand):
    def __init__(self, spell, thing):
        self.spell = spell 
        self.thing = thing

    def lumus(self):
        print "You cast the spell %s with your %s wand at %s" %(self.spell, self.wandtype, self.thing)   #This line causes the AttributeError! 
        print "The room lights up."

    def wingardium_leviosa(self): 
        print "You cast the levitation spell."

my_wand = Wand('Phoenix-feather', '12 inches') 
cast_spell = CastSpell('lumus', 'door') 
my_wand.fulldesc()  
cast_spell.lumus() 

I've tried using the super() method to no avail. I'd really appreciate your help understanding a) why class inheritance isn't working in this case, b) how to get it to work.

解决方案

To put it simply, you override Wand.__init__ in the class that inherits from it, so CastSpell.wandtype is never set in CastSpell. Besides that, my_wand can't pass information into cast_spell, so you're confused about the role of inheritance.

Regardless of how you do it, you have to somehow pass length and wandtype to CastSpell. One way would be to include them directly into CastSpell.__init__:

class CastSpell(Wand):
    def __init__(self, spell, thing, length, wandtype):
        self.spell = spell 
        self.thing = thing
        self.length = length
        self.wandtype = wandtype

Another, more generic way would be to pass these two to the base class' own __init__():

class CastSpell(Wand):
    def __init__(self, spell, thing, length, wandtype):
        self.spell = spell 
        self.thing = thing
        super(CastSpell, self).__init__(length, wandtype)

Another way would be to stop making CastSpell inherit from Wand (is CastSpell a kind of Wand? or something a Wand does?) and instead make each Wand be able to have some CastSpells in it: instead of "is-a" (a CastSpell is a kind of Wand), try "has-a" (a Wand has Spells).

Here's a simple, not so great way to have a Wand store spells:

class Wand(object):
    def __init__(self, wandtype, length):
        self.length = length
        self.wandtype = wandtype
        self.spells = {} # Our container for spells. 
        # You can add directly too: my_wand.spells['accio'] = Spell("aguamenti", "fire")

    def fulldesc(self):
        print "This is a %s wand and it is a %s long" % (self.wandtype, self.length)

    def addspell(self, spell):
        self.spells[spell.name] = spell

    def cast(self, spellname):
        """Check if requested spell exists, then call its "cast" method if it does."""
        if spellname in self.spells: # Check existence by name
            spell = self.spells[spellname] # Retrieve spell that was added before, name it "spell"
            spell.cast(self.wandtype) # Call that spell's cast method, passing wandtype as argument
        else:
            print "This wand doesn't have the %s spell." % spellname
            print "Available spells:"
            print "\n".join(sorted(self.spells.keys()))


class Spell(object):
    def __init__(self, name, target):
        self.name = name
        self.target = target

    def cast(self, wandtype=""):
        print "You cast the spell %s with your %s wand at %s." % (
               self.name, wandtype, self.target)
        if self.name == "lumus":
            print "The room lights up."
        elif self.name == "wingardium leviosa":
            print "You cast the levitation spell.",
            print "The %s starts to float!" % self.target

    def __repr__(self):
        return self.name

my_wand = Wand('Phoenix-feather', '12 inches')
lumus = Spell('lumus', 'door')
wingardium = Spell("wingardium leviosa", "enemy")

my_wand.fulldesc()
lumus.cast() # Not from a Wand! I.e., we're calling Spell.cast directly
print "\n\n"

my_wand.addspell(lumus) # Same as my_wand.spells["lumus"] = lumus
my_wand.addspell(wingardium)
print "\n\n"

my_wand.cast("lumus") # Same as my_wand.spells["lumus"].cast(my_wand.wandtype)
print "\n\n"
my_wand.cast("wingardium leviosa")
print "\n\n"
my_wand.cast("avada kadavra") # The check in Wand.cast fails, print spell list instead
print "\n\n"

这篇关于Python类继承AttributeError - 为什么?怎么修?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆