问题
With a simple pair of classes, I cannot get super working:
class A(object):
q = 'foo'
class B(A):
q = 'bar'
def __init__(self):
self.a = super(A, self).q
a = B()
errors like so:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-210-802575054d17> in <module>()
5 def __init__(self):
6 self.a = super(A, self).q
----> 7 a = B()
<ipython-input-210-802575054d17> in __init__(self)
4 q = 'bar'
5 def __init__(self):
----> 6 self.a = super(A, self).q
7 a = B()
AttributeError: 'super' object has no attribute 'q'
I've looked through similar problems on stack exchange, read documentation and articles, and by all accounts this should be working. What obvious thing am I missing?
EDIT: The answer is that I'm referencing the wrong class, and fixing it fixes the example, but not my real code which is below:
class D(object):
pwd = ['~/']
def __init__(self,*args):
if len(args) == 1:
self.cd(args[0])
else:
return
def __str__(self):
if len(self.pwd) == 1:
return self.pwd[0]
else:
return ''.join(self.pwd)
def __add__(self,other):
if type(other) is str:
return str(self) + other
elif type(other) is list:
return pwd + other
def cd(self, directory):
#import pdb; pdb.set_trace()
reset = False
if directory[0] is '~':
reset = True
if directory[0] is '/':
reset = True
directory = directory[1:]
if directory[-1] is '/':
directory = directory[:-1]
directory = [folder+'/' for folder in directory.split('/')]
rverse = directory.count('../')
if rverse > 0 and type(directory) is list:
end = False
for folder in directory:
if folder == '../' and end:
raise Exception('improperly placed ".."')
if folder != '../':
end = True
if reset:
self.pwd = directory
else:
self.pwd = self.pwd + directory
print self
class Dirchanger(D):
def __init__(self,client,*args):
if len(args) == 1:
self.cd(args[0])
def cd(self,directory):
super(D, self).cd(directory)
Obviously, that code is incomplete, but it should work based on the answer.
回答1:
You are using the wrong search target (the first argument); use super(B, self)
instead:
def __init__(self):
self.a = super(B, self).q
The first argument gives super()
a starting point; it means look through the MRO, starting at the next class past the one I gave you, where the MRO is the method resolution order of the second argument (type(self).__mro__
).
By telling super()
to start looking past A
, you effectively told super()
to start the search too far down the MRO. object
is next, and that type doesn't have a q
attribute:
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
Your real code has the exact same issue:
class Dirchanger(D):
def __init__(self,client,*args):
if len(args) == 1:
self.cd(args[0])
def cd(self,directory):
super(D, self).cd(directory)
You are starting the MRO search at D
, not Dirchanger
here.
来源:https://stackoverflow.com/questions/24000419/i-cant-get-super-to-work-in-python-2-7