Python ConfigParser的子类没有属性\u节

Python ConfigParser的子类没有属性\u节,python,python-2.7,configparser,Python,Python 2.7,Configparser,我正在尝试将ConfigParser子类化。当尝试访问\u部分时会显示 'acc' object has no attribute '_sections' 示例代码(python 2.7): 将子类化的顺序颠倒如下: import ConfigParser class acc(ConfigParser.RawConfigParser, object): def __init__(self, acc_file): super(acc, self).__init__()

我正在尝试将ConfigParser子类化。当尝试访问
\u部分时
会显示

'acc' object has no attribute '_sections'
示例代码(python 2.7):


将子类化的顺序颠倒如下:

import ConfigParser

class acc(ConfigParser.RawConfigParser, object):
    def __init__(self, acc_file):
        super(acc, self).__init__()
        self.lol = 1
        print self.has_section(self.lol)

a=acc(1)

将子类化的顺序颠倒如下:

import ConfigParser

class acc(ConfigParser.RawConfigParser, object):
    def __init__(self, acc_file):
        super(acc, self).__init__()
        self.lol = 1
        print self.has_section(self.lol)

a=acc(1)

对这个问题的描述要好得多


这是Python的

因此,实际发生的情况是,当遇到一个旧式类时,MRO“链接”的表现不好。或者更具体地说-不称为超级的类

在您的代码中,
configParser.RawConfigParser\uuuuu init\uuuuu(…)
从未调用过。要修复此问题,您可以手动调用它(只需在
acc
init
中添加
ConfigParser.RawConfigParser.\uuuu初始化(self…
),尽管我不确定这是推荐的还是有效的

另一个选项是使所有类都符合新样式,并调用
super
或旧样式,并显式初始化

唯一有效的方法是,如果所有经典样式类都在
Class.mro()
输出中的所有新样式类之后,特别是在
对象之后。这将阻止
super
调用它们

由于以下情况,安全性不是很高:

class TheClassicClass:
   def __init__(self):
       print "instantiating clasic class!"
       self._msg = "the classic class!"
   def m(self):
       print self._msg

class acc(ConfigParser.RawConfigParser, TheClassicClass, object):
    def __init__(self, acc_file):
            super(acc,self).__init__()
            self.lol = 1
            print self.has_section(self.lol)

a=acc(1)
a.m()
修复其他答案:将这些行添加到
acc
\uuuu init\uuuuu
应通知您显式实例化类:

ConfigParser.RawConfigParser.__init__(self)
TheClassicClass.__init__(self)
为了确认代码中的问题,让我们尝试在一个简单的设置中重现这个问题

我们将制作旧(经典)类:

以及调用
super
的新样式类:

class ANew(object):

    def __init__(self):
        print "init anew"
        super(ANew, self).__init__()

class BNew(object):

    def __init__(self):
        print "init bnew"
        super(BNew, self).__init__()

    def m(self):
        print "print from bnew"
# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
    def __init__(self):
        super(TestNewSuper, self).__init__()

TestNewSuper()
# will init ANew , but not BClassic
class TestOldStyleSuper(ANew, BClassic):
    def __init__(self):
        super(TestOldStyleSuper, self).__init__()
        self.m()
在最简单的情况下,我们手动调用
\uuuu init\uuu
以确保类被实例化。这看起来像:

class TestOldStyle(AClassic, BClassic):
    def __init__(self):
        AClassic.__init__(self)
        BClassic.__init__(self)
        self.m()

print "old style"
TestOldStyle()
在这种情况下,是MRO的顺序

输出:

旧式

初始化aclassic

初始B经典

从bclassic打印

现在,让我们尝试新的样式,它与
super
类似:

class ANew(object):

    def __init__(self):
        print "init anew"
        super(ANew, self).__init__()

class BNew(object):

    def __init__(self):
        print "init bnew"
        super(BNew, self).__init__()

    def m(self):
        print "print from bnew"
# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
    def __init__(self):
        super(TestNewSuper, self).__init__()

TestNewSuper()
# will init ANew , but not BClassic
class TestOldStyleSuper(ANew, BClassic):
    def __init__(self):
        super(TestOldStyleSuper, self).__init__()
        self.m()
由于两个类都调用
super
,因此它们都被实例化,并且输出为:

重新开始

init bnew

现在,我们尝试使用一些经典样式类的“混合体”(,不能调用
super

class ANew(object):

    def __init__(self):
        print "init anew"
        super(ANew, self).__init__()

class BNew(object):

    def __init__(self):
        print "init bnew"
        super(BNew, self).__init__()

    def m(self):
        print "print from bnew"
# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
    def __init__(self):
        super(TestNewSuper, self).__init__()

TestNewSuper()
# will init ANew , but not BClassic
class TestOldStyleSuper(ANew, BClassic):
    def __init__(self):
        super(TestOldStyleSuper, self).__init__()
        self.m()
输出:

重新开始

并且立即成为一个例外:

Traceback (most recent call last):
  File "./inhert.py", line 35, in <module>
    TestOldStyleSuper()
  File "./inhert.py", line 33, in __init__
    self.m()
  File "./inhert.py", line 15, in m
    print "print from " + self.name
AttributeError: 'TestOldStyleSuper' object has no attribute 'name'
将重新初始化
b经典
,但不初始化
b新

重新开始

初始B经典

从bclassic打印

以及创建不一致的MRO:

# no consistent MRO exception
class TestHybrid(ANew, object, BNew):
    def __init__(self):
        super(TestHybrid, self).__init__()
        self.m()

TestHybrid()
例外情况:

Traceback (most recent call last):
  File "./inhert.py", line 33, in <module>
    class TestHybrid(ANew, object, BNew):
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases BNew, object
回溯(最近一次呼叫最后一次):
文件“/inhert.py”,第33行,在
类TestHybrid(新、对象、BNew):
TypeError:调用元类基时出错
无法创建一致的方法解析
新基地、目标的订单(MRO)

对这个问题的描述要好得多


这是Python的

因此,实际发生的情况是,当遇到一个老式类时,MRO“链接”的行为不好。或者更具体地说,不调用super的类

在您的代码中,
configParser.RawConfigParser\uuuuu init\uuuu(…)
从未被调用过。要解决这个问题,您可以手动调用它(只需在
acc
init
中添加
configParser.RawConfigParser.\uuu init\uuuuuuuuuuu(self…
),尽管我不确定这是推荐的还是有效的

另一个选项是使所有类都符合新样式,并调用
super
或旧样式,并显式初始化

唯一有效的方法是,如果所有经典样式类都在
Class.mro()
的输出中的所有新样式类之后,特别是在
object
之后。这将阻止
super
调用它们

由于以下情况,安全性不是很高:

class TheClassicClass:
   def __init__(self):
       print "instantiating clasic class!"
       self._msg = "the classic class!"
   def m(self):
       print self._msg

class acc(ConfigParser.RawConfigParser, TheClassicClass, object):
    def __init__(self, acc_file):
            super(acc,self).__init__()
            self.lol = 1
            print self.has_section(self.lol)

a=acc(1)
a.m()
修复其他答案:将这些行添加到
acc
\uuuu init\uuuuu
应通知您显式实例化类:

ConfigParser.RawConfigParser.__init__(self)
TheClassicClass.__init__(self)
为了确认代码中的问题,让我们尝试在一个简单的设置中重现这个问题

我们将制作旧(经典)类:

以及调用
super
的新样式类:

class ANew(object):

    def __init__(self):
        print "init anew"
        super(ANew, self).__init__()

class BNew(object):

    def __init__(self):
        print "init bnew"
        super(BNew, self).__init__()

    def m(self):
        print "print from bnew"
# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
    def __init__(self):
        super(TestNewSuper, self).__init__()

TestNewSuper()
# will init ANew , but not BClassic
class TestOldStyleSuper(ANew, BClassic):
    def __init__(self):
        super(TestOldStyleSuper, self).__init__()
        self.m()
在最简单的情况下,我们手动调用
\uuuu init\uuuu
以确保类被实例化。这类似于:

class TestOldStyle(AClassic, BClassic):
    def __init__(self):
        AClassic.__init__(self)
        BClassic.__init__(self)
        self.m()

print "old style"
TestOldStyle()
在这种情况下,是MRO的顺序

输出:

旧式

初始化aclassic

初始B经典

从bclassic打印

现在,让我们尝试新的样式,它与
super
类似:

class ANew(object):

    def __init__(self):
        print "init anew"
        super(ANew, self).__init__()

class BNew(object):

    def __init__(self):
        print "init bnew"
        super(BNew, self).__init__()

    def m(self):
        print "print from bnew"
# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
    def __init__(self):
        super(TestNewSuper, self).__init__()

TestNewSuper()
# will init ANew , but not BClassic
class TestOldStyleSuper(ANew, BClassic):
    def __init__(self):
        super(TestOldStyleSuper, self).__init__()
        self.m()
由于两个类都调用
super
,因此它们都被实例化,并且输出为:

重新开始

init bnew

现在,我们尝试使用一些经典样式类的“混合体”(,不能调用
super

class ANew(object):

    def __init__(self):
        print "init anew"
        super(ANew, self).__init__()

class BNew(object):

    def __init__(self):
        print "init bnew"
        super(BNew, self).__init__()

    def m(self):
        print "print from bnew"
# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
    def __init__(self):
        super(TestNewSuper, self).__init__()

TestNewSuper()
# will init ANew , but not BClassic
class TestOldStyleSuper(ANew, BClassic):
    def __init__(self):
        super(TestOldStyleSuper, self).__init__()
        self.m()
输出:

重新开始

并且立即成为一个例外:

Traceback (most recent call last):
  File "./inhert.py", line 35, in <module>
    TestOldStyleSuper()
  File "./inhert.py", line 33, in __init__
    self.m()
  File "./inhert.py", line 15, in m
    print "print from " + self.name
AttributeError: 'TestOldStyleSuper' object has no attribute 'name'
将重新初始化
b经典
,但不初始化
b新

重新开始

初始B经典

从bclassic打印

以及创建不一致的MRO:

# no consistent MRO exception
class TestHybrid(ANew, object, BNew):
    def __init__(self):
        super(TestHybrid, self).__init__()
        self.m()

TestHybrid()
例外情况:

Traceback (most recent call last):
  File "./inhert.py", line 33, in <module>
    class TestHybrid(ANew, object, BNew):
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases BNew, object
回溯(最近一次呼叫最后一次):
文件“/inhert.py”,第33行,在
类TestHybrid(新、对象、BNew):
TypeError:调用元类基时出错
无法创建一致的方法解析
新基地、目标的订单(MRO)

以下划线开头的属性被认为是私有的。请看是,但是请看最新的代码,更新以反映该行为。以下划线开头的属性被认为是私有的。请看是,但是请看最新的代码,更新以反映该行为。工作很神秘,有人能解释吗?@Reut Sharabani击败了我下面是一个很好的解释,解释了我们为什么需要遵循这个。看看吧。这个解释很神秘,有人能解释吗?@Reut Sharabani在下面给了我一个很好的解释,解释了我们为什么需要遵循这个