我在ClassA中调用构造函数,并且如果满足某个条件,则希望生成的对象具有不同的类(ClassB).我试着更换的第一个参数__init __()(在下面的例子中"自我")内 __init __(),但它似乎并没有做我想做的.
在主要:
import ClassA
my_obj = ClassA.ClassA(500)
# unfortunately, my_obj is a ClassA, but I want a ClassB!
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
在ClassB/__ init__.py中:
class ClassB:
pass
Run Code Online (Sandbox Code Playgroud)
Dav*_*d Z 33
你需要__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)
Run Code Online (Sandbox Code Playgroud)
__new__()作为类实例化过程的一部分运行之前__init__().基本上__new__()是实际创建新实例的内容,__init__()然后调用它来初始化其属性.这就是为什么你可以使用__new__()但不能__init__()改变创建的对象的类型:一旦__init__()启动,对象已经被创建,并且改变它的类型为时已晚.(嗯......不是真的,但是这会变成非常神秘的Python黑魔法.)请参阅文档.
但在这种情况下,我会说工厂功能更合适,比如说
def thingy(theirnumber):
if theirnumber > 10:
return ClassB.ClassB(theirnumber)
else:
return ClassA.ClassA(theirnumber)
Run Code Online (Sandbox Code Playgroud)
顺便说一下,请注意,如果你按照我__new__()上面所做的操作,如果ClassB返回a,则不会调用实例的__init__()方法!如果返回的对象是包含该方法的类的实例(此处),则Python仅调用.这是支持工厂功能方法的另一个论点.ClassB__init__()__new__()__new__()ClassA
Sam*_*lan 15
我建议使用工厂模式.例如:
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)
Run Code Online (Sandbox Code Playgroud)