Search code examples
pythonpython-3.xmethodsalias

How to alias a Python constructor?


I read here and here that Python methods can be aliased using =.

However, when I try it on the __init__ method, it doesn't seem to work.

class MyClass:
    def __init__(self):
        print("Hi mum!")
    
    new_name = __init__

a = MyClass()
b = MyClass.new_name()

The b = MyClass.new_name() causes this error:

TypeError: __init__() missing 1 required positional argument: 'self'

Why does this not work? And how should I alias __init__ correctly?


Solution

  • __init__ is not a constructor. __new__ is. __init__ is an instance method that performs initialization on an instance after it is constructed by the static method __new__. The reason why both __new__ and __init__ are called when you call the class with MyClass() is because it is what the __call__ method of the type, or metaclass, of MyClass, does.

    So if you want to properly alias the constructor of a class you can alias the __call__ method of its metaclass:

    class AliasedConstructor(type):
        new_name = type.__call__
    
    class MyClass(metaclass=AliasedConstructor):
        def __init__(self):
            print("Hi mum!")
    
    MyClass.new_name()
    

    Alternatively, you can make the alias a classmethod descriptor that binds type.__call__ to the current class:

    class MyClass:
        def __init__(self):
            print("Hi mum!")
    
        new_name = classmethod(type.__call__)
    

    Both approaches would output:

    Hi mum!