我在ClassA中调用构造函数,并且如果满足某个条件,则希望结果对象具有不同的类(ClassB)。我已经尝试将第一个参数替换为__init __()(在下面的示例中为'self') __init __()中的但它似乎没有按照我想要的那样做。
在main中:
import ClassA
my_obj = ClassA.ClassA(500)
# unfortunately, my_obj is a ClassA, but I want a ClassB!
在ClassA / __ init __。py:
import ClassB
class ClassA:
def __init__(self,theirnumber):
if(theirnumber > 10):
# all big numbers should be ClassB objects:
self = ClassB.ClassB(theirnumber)
return
else:
# numbers under 10 are ok in ClassA.
return
在ClassB / __ init __。py:
class ClassB:
pass
答案 0 :(得分:32)
您需要__new__()
。 (并且你还需要使它成为一个新式的类,假设你使用Python 2,通过继承object
。)
class ClassA(object):
def __new__(cls,theirnumber):
if theirnumber > 10:
# all big numbers should be ClassB objects:
return ClassB.ClassB(theirnumber)
else:
# numbers under 10 are ok in ClassA.
return super(ClassA, cls).__new__(cls, theirnumber)
__new__()
作为__init__()
之前的类实例化过程的一部分运行。基本上__new__()
是实际创建新实例的内容,然后调用__init__()
来初始化其属性。这就是为什么你可以使用__new__()
而不是__init__()
来改变创建的对象的类型:一旦__init__()
启动,对象就已经被创建了,改变它的类型为时已晚。 (嗯......不是真的,但是这会产生非常神秘的Python黑魔法。)见the documentation。
在这种情况下,我会说工厂功能更合适,比如
def thingy(theirnumber):
if theirnumber > 10:
return ClassB.ClassB(theirnumber)
else:
return ClassA.ClassA(theirnumber)
顺便提一下,请注意,如果您使用上面__new__()
执行的操作,如果返回ClassB
,则__init__()
实例的ClassB
方法将< em> not 被叫!如果从__init__()
返回的对象是包含__new__()
方法的类的实例(此处为__new__()
),则Python仅调用ClassA
。这是支持工厂功能方法的另一个论点。
答案 1 :(得分:14)
我建议使用工厂模式。例如:
def get_my_inst(the_number):
if the_number > 10:
return ClassB(the_number)
else:
return ClassA(the_number)
class_b_inst = get_my_inst(500)
class_a_inst = get_my_inst(5)
答案 2 :(得分:12)
不要试图歪曲构造函数的目的:使用工厂函数。为一个类调用构造函数并返回一个不同类的实例是一种引起混淆的可靠方法。