Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"__init__" looks so ugly in Python. Is there another way to code this construct?

Tags:

I have used this in my code, but "underscore underscore init underscore underscore" looks so ugly in Python, because it is not clear at a glance as to whether these prefixes and suffixes are one, two or three characters. Is there another way to code this construct without the double underscore? For example:

class MyForm(forms.Form):
    foo = forms.CharField()
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.bar = bar(self)

Annoyingly this code does not work, so obviously the underscore plays an essential role:

class MyForm(forms.Form):
    foo = forms.CharField()
    def init(self, *args, **kwargs):
        super(MyForm, self).init(*args, **kwargs)
        self.bar = bar(self)

What is the purpose of this syntax?

like image 594
gornvix Avatar asked Nov 24 '17 23:11

gornvix


People also ask

Is __ init __ necessary in Python?

So, the parent class constructor is called first. But in Python, it is not compulsory that the parent class constructor will always be called first. The order in which the __init__ method is called for a parent or a child class can be modified.

What is the correct syntax for defining an __ Init__ method in Python?

Since Python will automatically call the __init__() method immediately after creating a new object, you can use the __init__() method to initialize the object's attributes. The following defines the Person class with the __init__() method: class Person: def __init__(self, name, age): self.name = name self.

What is __ module __ in Python?

A module in Python is a file (ending in .py ) that contains a set of definitions (variables and functions) that you can use when they are imported. Modules are considered as objects, just as everything else is in Python.

How do you shorten a line of code in Python?

Summary. If you have a very long line of code in Python and you'd like to break it up over over multiple lines, if you're inside parentheses, square brackets, or curly braces you can put line breaks wherever you'd like because Python allows for implicit line continuation.


2 Answers

Is there another way to code this construct without the double underscore?

No, that's part of the Python object model directly:

https://docs.python.org/3/reference/datamodel.html#object.__init__

You can not change this without recompiling your own Python interpreter.

What is the purpose of this syntax?

The double underscore "dunder" is there to indicate a method which has special meaning in the object model. In time you will get used to it and may even begin to like it. When reading code, it provides an easy way to visually distinguish the Python datamodel "hooks" in any 3rd-party code.

like image 181
wim Avatar answered Sep 23 '22 13:09

wim


Although I completely agree with @wim's answer, you can achieve what you want by using a decorator:

def custom_init(name='init'):
    def wrapper(callable):
        if not hasattr(callable, name):
            raise AttributeError('Attribute {} not found on {}'.format(name, callable))
        callable.__init__ = getattr(callable, name)
        return callable
    return wrapper

You would then just:

@custom_init(name='foo')
class SomeClass(object):
    def foo(self, some_value):
        self.value = some_value

c = SomeClass(42)
print(c.value) # Prints 42

Of course, for derived classes, you just need to remember to call __init__ on the base class:

@custom_init()
class MyForm(forms.Form):
    foo = forms.CharField()
    def init(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.bar = bar(self)
like image 35
Matias Cicero Avatar answered Sep 23 '22 13:09

Matias Cicero