ConfigParser的子类没有属性_sections

时间:2014-12-23 21:45:28

标签: python python-2.7 configparser

我正在尝试将ConfigParser子类化。在尝试访问_sections时,它说

'acc' object has no attribute '_sections'

示例代码(python 2.7):

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

a=acc(1)

2 个答案:

答案 0 :(得分:3)

问题描述得更好here


这是Python的Method Resolution Order

所以,实际发生的事情是MRO“链接”在绑定旧样式类时表现不佳。或者具体 - 不称为超级

的类

在您的代码中,configParser.RawConfigParser__init__(..) 从不调用。要解决此问题,您可以手动调用它(只需在ConfigParser.RawConfigParser.__init__(self ...)的{​​{1}}中添加acc),但我不确定这是推荐的,甚至是有效的。

您的另一个选择是使所有类符合新样式,并调用init或旧样式,并显式初始化。

唯一可行的方法是,如果所有经典风格的类在<{1}}的输出中>之后 ,特别是super之后的所有新风格类。这会阻止Class.mro()调用它们。

由于这种情况,other answer不是很安全:

object

修复其他答案:将这些行添加到super的{​​{1}}应该通知显式实例化类:

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

调用__init__的新样式类:

ConfigParser.RawConfigParser.__init__(self)
TheClassicClass.__init__(self)

在最简单的情况下,我们手动调用class AClassic: def __init__(self): print "init aclassic" class BClassic: def __init__(self): print "init bclassic" self.name = "bclassic" def m(self): print "print from " + self.name 以确保实例化类。这看起来像是:

super

在这种情况下,depth-first, left-to-right是MRO的顺序。

输出:

  

旧式

     

init aclassic

     

init bclassic

     

从bclassic打印

现在让我们尝试使用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" 看起来像这样的新样式:

__init__

由于两个类都调用class TestOldStyle(AClassic, BClassic): def __init__(self): AClassic.__init__(self) BClassic.__init__(self) self.m() print "old style" TestOldStyle() ,因此它们都被实例化,输出为:

  

重新启动

     

init bnew

现在,我们尝试使用经典风格类的一些“混合”(ConfigParser.RawConfigParser is a classic-style-class,而不能调用super

# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
    def __init__(self):
        super(TestNewSuper, self).__init__()

TestNewSuper()

输出:

  

重新启动

立即例外:

super

这是因为super未实例化。

更多意外行为的例子:

# 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' BClassic,但不会# init ANew, BClassic class TestHybrid(ANew, BClassic, BNew): def __init__(self): super(TestHybrid, self).__init__() self.m() TestHybrid()

  

重新启动

     

init bclassic

     

从bclassic打印

创建一个不存在的MRO:

ANew

例外:

BClassic

答案 1 :(得分:2)

按如下方式颠倒子类的顺序:

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)