【发布时间】:2014-01-11 20:05:52
【问题描述】:
我将首先编写代码,然后详细解释我想要实现的目标,因为这样更容易:
global child_selector
class Base(object):
def __init__(self):
self.extended_name = self.name + '_Base'
class Child1(Base):
def __init__(self):
super(Child1, self).__init__()
def print_my_name(self):
print 'I am ChildOne'
class Child2(Base):
def __init__(self):
super(Child2, self).__init__()
def print_my_name(self):
print 'I am ChildTwo'
class ChildAsBaseSelector(object):
def __new__(cls):
if child_selector == 1:
return Child1()
elif child_selector == 2:
return Child2()
else:
print 'No child selected'
现在,如果我创建一个继承自 Child1 或 Child2 并将 self.name 作为实例变量的类,一切都会按预期工作:
class Testing1(Child1):
def __init__(self):
self.name = 'Testing1'
super(Testing1, self).__init__()
a = Testing1()
a.print_my_name() # 'I am ChlidOne'
print a.extended_name # 'Testing1_Base'
但是,如果我创建另一个将直接从 ChildAsBaseSelector() 继承的类,事情就会变得可疑:
class Testing2(ChildAsBaseSelector):
def __init__(self):
self.name = 'Testing2'
super(Testing2, self).__init__()
child_selector = 1
a = Testing2()
# Will raise AttributeError: 'Child1' object has no attribute 'name'
在阅读了 '__new__()' 的 python 文档后,我认为问题在于:'如果 __new__() 没有返回 cls 的实例,则不会调用新实例的 __init__() 方法。这并没有真正的帮助,因为我不知道如何“修复它”。
我也知道我可以这样做:
if child_selector == 1:
ChildAsBaseSelector = Child1
if child_selector == 2:
ChildAsBaseSelector = Child2
并且比直接从 ChildAsBaseSelector 继承。但我发现这在某种程度上并不优雅,并将 python 的灵活性推向了极限。 我真正想做的是有一个类,它会根据条件返回另一个类,然后我可以使用它来继承。有什么提示吗?我想元类(一个我正在努力理解的概念)现在会派上用场。
感谢任何提示。谢谢!
【问题讨论】:
标签: python class inheritance metaclass