我无法让 super() 在 python 2.7 中工作 [英] I can't get super() to work in python 2.7

查看:59
本文介绍了我无法让 super() 在 python 2.7 中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用一对简单的类,我无法获得超级工作:

A 类(对象):q = '富'B(A)类:q = '酒吧'def __init__(self):self.a = super(A, self).qa = B()

像这样的错误:

---------------------------------------------------------------------------AttributeError 回溯(最近一次调用最后一次)<ipython-input-210-802575054d17>在 <module>()5 def __init__(self):6 self.a = super(A, self).q---->7 a = B()<ipython-input-210-802575054d17>在 __init__(self) 中4 q = '酒吧'5 def __init__(self):---->6 self.a = super(A, self).q7 a = B()AttributeError: 'super' 对象没有属性 'q'

我在堆栈交换中查看了类似的问题,阅读了文档和文章,并且所有人都认为这应该有效.我错过了什么明显的东西?

答案是我引用了错误的类,修复它修复了示例,但不是我下面的真实代码:

D 类(对象):pwd = ['~/']def __init__(self,*args):如果 len(args) == 1:self.cd(args[0])别的:返回def __str__(self):如果 len(self.pwd) == 1:返回 self.pwd[0]别的:返回 '​​'.join(self.pwd)def __add__(self,other):如果类型(其他)是 str:返回 str(self) + 其他elif 类型(其他)是列表:返回密码 + 其他def cd(自我,目录):#导入PDB;pdb.set_trace()重置 = 错误如果目录 [0] 是~":重置 = 真如果目录 [0] 是/":重置 = 真目录 = 目录 [1:]如果目录 [-1] 是/":目录 = 目录 [:-1]directory = [folder+'/' for directory.split('/')]rverse = directory.count('../')如果反向>0 和类型(目录)是列表:结束 = 错误对于目录中的文件夹:如果文件夹 == '../' 并结束:raise Exception('放置不当.."')如果文件夹 != '../':结束 = 真如果重置:self.pwd = 目录别的:self.pwd = self.pwd + 目录打印自己类目录转换器(D):def __init__(self,client,*args):如果 len(args) == 1:self.cd(args[0])def cd(自我,目录):super(D, self).cd(目录)

显然,该代码不完整,但它应该可以根据答案工作.

解决方案

您使用了错误 搜索目标(第一个参数);使用 super(B, self) 代替:

def __init__(self):self.a = super(B, self).q

第一个参数给 super() 一个起点;这意味着查看 MRO,从我给你的课程之后的下一个课程开始,其中 MRO 是第二个参数的方法解析顺序(type(self).__mro__).

通过告诉 super() 开始查看 A,你有效地告诉 super() 开始在 MRO 下搜索太远了.object 是下一个,并且该类型没有 q 属性:

<预><代码>>>>B.__mro__(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)

您的真实代码存在完全相同的问题:

class Dirchanger(D):def __init__(self,client,*args):如果 len(args) == 1:self.cd(args[0])def cd(自我,目录):super(D, self).cd(目录)

您是在 D 处开始 MRO 搜索,而不是此处的 Dirchanger.

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.

解决方案

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.

这篇关于我无法让 super() 在 python 2.7 中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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