首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ConfigParser的子类没有属性_sections

ConfigParser的子类没有属性_sections
EN

Stack Overflow用户
提问于 2014-12-23 21:45:27
回答 2查看 1.2K关注 0票数 0

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

代码语言:javascript
复制
'acc' object has no attribute '_sections'

示例代码(python 2.7):

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-23 22:30:28

这里更好地描述了这个问题。

这是Python的方法分解顺序

因此,实际发生的情况是,MRO“链接”在封装旧样式类时表现得不太好。或者是特定的--不调用超级类。

在您的代码中,configParser.RawConfigParser__init__(..),从未调用过。要解决这个问题,您可以手动调用它(只需将ConfigParser.RawConfigParser.__init__(self ...)添加到accinit中),尽管我不确定这是推荐的,甚至不是有效的。

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

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

由于这种情况,其他答案不太安全:

代码语言:javascript
复制
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__应该通知显式实例化类:

代码语言:javascript
复制
ConfigParser.RawConfigParser.__init__(self)
TheClassicClass.__init__(self)

为了确认代码中的问题,让我们尝试在一个简单的设置中重现这个问题.

我们将做一些古老的(经典的)课程:

代码语言:javascript
复制
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的新样式类

代码语言:javascript
复制
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__以确保类被实例化。这看起来应该是:

代码语言:javascript
复制
class TestOldStyle(AClassic, BClassic):
    def __init__(self):
        AClassic.__init__(self)
        BClassic.__init__(self)
        self.m()

print "old style"
TestOldStyle()

在本例中,纵深第一,从左到右是MRO的顺序。

输出:

旧式 [医]三叠纪 非经典 印自经典版

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

代码语言:javascript
复制
# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
    def __init__(self):
        super(TestNewSuper, self).__init__()

TestNewSuper()

由于两个类都调用了super,所以它们都被实例化,输出如下:

重新开始 无新意

现在,我们尝试使用一些经典风格类(ConfigParser.RawConfigParser是一个经典的类。 )的“混合”,并且不能调用super

代码语言:javascript
复制
# will init ANew , but not BClassic
class TestOldStyleSuper(ANew, BClassic):
    def __init__(self):
        super(TestOldStyleSuper, self).__init__()
        self.m()

输出:

重新开始

并且立即有一个例外:

代码语言:javascript
复制
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没有实例化。

更多意外行为的例子:

代码语言:javascript
复制
# init ANew, BClassic
class TestHybrid(ANew, BClassic, BNew):
    def __init__(self):
        super(TestHybrid, self).__init__()
        self.m()

TestHybrid()

将初始化ANewBClassic,但不初始化BNew

重新开始 非经典 印自经典版

并创建一个不一致的MRO:

代码语言:javascript
复制
# no consistent MRO exception
class TestHybrid(ANew, object, BNew):
    def __init__(self):
        super(TestHybrid, self).__init__()
        self.m()

TestHybrid()

例外:

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2014-12-23 22:03:06

将子类的顺序颠倒如下:

代码语言:javascript
复制
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)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27628471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档