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?
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.
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.
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.
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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With