Вопрос

class A():
    ...

I want class A that is initialized with any object as parameter, but when __init__ goes with A type, it should leave/return old A object, dont create wrapper A(A()).

I guess that overwrite __new__ method is solution, but how there stop creating object creator and return given parameter as a result.

My workaround now is just recommendation:

def ToA(it):
    if type(it) == A:
        return it
    else: 
        return A(it)

But I need block somehow A to prevent direct use of A(A()).

Это было полезно?

Решение

I am not at all sure I understand what you want, but something like this may be it. You can't have an __init__ with this technique, because if you do, it will be called regardless of whether __new__ returned a new object.

class A(object):
    def __new__(cls, obj):
        if isinstance(obj, cls):
            return obj
        rv = object.__new__(cls)

        # everything you would normally put in __init__
        # goes here instead
        rv._obj = obj
        return rv

    # for instance:
    def __repr__(self):
        return "A({})".format(repr(self._obj))

>>> A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __new__() takes exactly 2 arguments (1 given)
>>> A(1)
A(1)
>>> A(A(1))
A(1)

Not being able to use __init__ is troublesome, particularly if you need to subclass A. Here's a way to work around that:

class A(object):
    def __new__(cls, obj):
        if isinstance(obj, cls):
            return obj
        rv = object.__new__(cls)
        rv._initialized = False
        return rv

    def __init__(self, obj):
        if self._initialized: return
        self._obj = obj
        self._initialized = True

class B(A):
    def __init__(self, obj):
        if self._initialized: return
        A.__init__(self, obj)
        self._otherthing = "foo"

You have to check self._initialized in every subclass's __init__ method, unfortunately.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top