我正在尝试子类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)发布于 2014-12-23 22:30:28
这里更好地描述了这个问题。
这是Python的方法分解顺序。
因此,实际发生的情况是,MRO“链接”在封装旧样式类时表现得不太好。或者是特定的--不调用超级的类。
在您的代码中,configParser.RawConfigParser__init__(..)是,从未调用过。要解决这个问题,您可以手动调用它(只需将ConfigParser.RawConfigParser.__init__(self ...)添加到acc的init中),尽管我不确定这是推荐的,甚至不是有效的。
另一个选项是使所有类都符合新样式,调用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的__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的新样式类
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()在本例中,纵深第一,从左到右是MRO的顺序。
输出:
旧式 [医]三叠纪 非经典 印自经典版
现在让我们尝试一下新的样式,它与super类似
# will init ANew and BNew
class TestNewSuper(ANew, BNew, object):
def __init__(self):
super(TestNewSuper, self).__init__()
TestNewSuper()由于两个类都调用了super,所以它们都被实例化,输出如下:
重新开始 无新意
现在,我们尝试使用一些经典风格类(ConfigParser.RawConfigParser是一个经典的类。 )的“混合”,并且不能调用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()将初始化ANew和BClassic,但不初始化BNew。
重新开始 非经典 印自经典版
并创建一个不一致的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发布于 2014-12-23 22:03:06
将子类的顺序颠倒如下:
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)https://stackoverflow.com/questions/27628471
复制相似问题