In Python 3, if a value is returned that is not an instance cls, the method is __init__never called. Therefore, I can, for example, do this:
class Foo:
@staticmethod
def bar(n):
return n * 5
def __new__(cls, n):
return Foo.bar(n)
print(Foo(3))
I got the impression that the order was __call__(if it is an instance) → __new__→ __init__.
However, in Python 2, this seems to boost TypeError: this constructor takes no argumentsdue to a lack __init__. I can fix this by inheriting from object. So by running this:
class Foo:
def __new__(cls, *args, **kwargs):
print("new called")
def __init__(self, *args, **kwargs):
print("init called")
Foo()
"""
Python2: "init called"
Python3: "new called"
"""
In Python 2, I even messed up with metaclasses.
Meta = type("Meta", (type,), dict(__call__=lambda self, x: x * 5))
class Foo(object):
__metaclass__ = Meta
print(Foo(4))
But this does not work in Python3 because the init / new methods seem to be canceled.
Is there a compatible Python2 / 3 way?
Decision:
So I did it. I don't like this, but it works:
class Foo(object):
@staticmethod
def __call__(i):
return i * 5
def __new__(cls, i):
return Foo.__call__(i)
Of course, there is a more pythonic way to do this.