在如此相似的问题包括: 这个和这个 。 我还通过所有的在线文档可以找我看,但我仍然很困惑。 我会是你的帮助表示感谢。
我想用法杖类.wandtype属性在我CastSpell类Lumus公司的方法。 不过,我不断收到错误“AttributeError的:‘CastSpell’对象有没有属性‘wandtype’。”
此代码的工作:
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()
此代码,企图继承,其实不然。
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()
我一直在使用超()方法无济于事尝试。 我真的明白为什么类继承不是在这种情况下工作的帮助理解A),B)如何得到它的工作。
简单地说,你重写Wand.__init__
中,从它继承的类,所以CastSpell.wandtype
从未在设定CastSpell
。 除此之外, my_wand
无法传递信息到cast_spell
,让你感到困惑传承的作用。
不管你怎么做,你必须以某种方式传递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
或东西? Wand
呢?),而是使每个棒能够有一些CastSpell
,它出现:而不是“是一个”(一CastSpell
是一种Wand
),尝试“有-A”(一Wand
具有Spell
或多个)。
这里有一个魔杖店法术简单,没有那么伟大的方式:
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"
是啊, super()
是不是你想要的。 请参阅本文的详细信息,何乐而不为。
在Python超正常通话(不幸)参照超做了明确。
如果我解释你的问题吧,你想知道为什么.length
和.wandtype
属性不显示的情况下,高达CastSpell
。 这是因为魔杖。 init()方法不被调用。 你应该做的是这样的:
class CastSpell(Wand):
def __init__(self, spell, thing):
Wand.__init__(self, whateverdefaultvalue_youwantforwandtype, default_value_for_length)
self.spell = spell
etc.
这就是说,你似乎没有使用权的继承是。 CastSpell是一个“行动”,而棒是一个“东西”。 这是不是一个真正的抽象,它是有道理的继承。
您需要调用父类的init方法。 否则,wandtype和长度永远不会对当前CastSpell实例设置。
class CastSpell(Wand):
def __init__(self, spell, thing):
super(CastSpell, self).__init__(A, B) # A, B are your values for wandtype and length
self.spell = spell
self.thing = thing
可替代地,可以添加wandtype和长度init方法以外的对象属性:
class Wand(object):
wandtype = None
length = None
然后,他们将永远是可用的(虽然直到他们已经被初始化它们会没有值)。
但是,你确定CastSpell应该是棒的一个子类? CastSpell是一个动作,这听起来更像它应该是棒的方法。
class Wand(object):
[...]
def cast_spell(self, spell, thing):
[etc.]