如何用另一个对象替换__init __()中的实例? [英] How to replace an instance in __init__() with a different object?

查看:73
本文介绍了如何用另一个对象替换__init __()中的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在ClassA中调用构造函数,并且如果满足特定条件,则希望使结果对象属于不同的类(ClassB).我尝试将第一个参数替换为__init __()(在下面的示例中为'self'),在 __init __()之内,但它似乎并没有满足我的要求.

I am calling a constructor in ClassA and want to have the resulting object be of a different class (ClassB) if a certain condition is met. I've tried replacing the first argument to __init__() ('self' in the example below) within __init__() but it doesn't seem to do what I want.

主要:

import ClassA

my_obj = ClassA.ClassA(500)
# unfortunately, my_obj is a ClassA, but I want a ClassB!

在ClassA/__ init__.py中:

in 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中:

in ClassB/__init__.py:

class ClassB:
    pass

推荐答案

为此您需要__new__(). (并且您还需要通过子类化object使其成为一种新型类,假设您使用的是Python 2.)

You need __new__() for that. (And you also need to make it a new-style class, assuming you're using Python 2, by subclassing 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黑魔法.)请参见文档.

__new__() runs as part of the class instantiation process before __init__(). Basically __new__() is what actually creates the new instance, and __init__() is then called to initialize its properties. That's why you can use __new__() but not __init__() to alter the type of object created: once __init__() starts, the object has already been created and it's too late to change its type. (Well... not really, but that gets into very arcane Python black magic.) See the documentation.

在这种情况下,我想说一个工厂函数更合适,例如

In this case, though, I'd say a factory function is more appropriate, something like

def thingy(theirnumber):
    if theirnumber > 10:
        return ClassB.ClassB(theirnumber)
    else:
        return ClassA.ClassA(theirnumber)

顺便说一句,请注意,如果您执行上述__new__()的操作,则返回ClassB时,ClassB实例的__init__()方法将 not 为叫!如果从__new__()返回的对象是其中包含__new__()方法(此处为ClassA)的类的实例,则Python仅调用__init__().这是支持工厂函数方法的另一个论点.

By the way, note that if you do what I did with __new__() above, if a ClassB is returned, the __init__() method of the ClassB instance will not be called! Python only calls __init__() if the object returned from __new__() is an instance of the class in which the __new__() method is contained (here ClassA). That's another argument in favor of the factory function approach.

这篇关于如何用另一个对象替换__init __()中的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆