7 ms·
Now that I have a chance to ask: I've always found the def __init__ method with 4 (!) underscores one of the ugliest things I've seen in a programming language.
by iagooar 10y ago
Now that I have a chance to ask: I've always found the def __init__ method with 4 (!) underscores one of the ugliest things I've seen in a programming language.
Don't get me wrong: I like Python and know it's truly good, but __why__??
- MerreM 10y agoI believe it's part of the language design, a phrase you'll find quite a lot in Python language discussions, especially is more esoteric features is; "We're all consenting adults". There are certain areas of the language which may not behave exactly the way you'd be expecting, if you're new to it. These usually have an unusual syntax, which will cause you to find out more. They're basically the mini-roundabouts of python. https://en.wikipedia.org/wiki/Roundabout#Mini-roundabouts https://en.wikipedia.org/wiki/Roundabout#Mini-roundabouts If you know what you're doing you cruise straight over, but if for any reason you're unsure, you're forced to find out more before continuing. It's not designed to stop you, because "We're all consenting adults", but that doesn't mean it's going to encourage you to do something that might be harmful.
- icc97 10y agoUnless of course you're in Belgium where all junctions are by default preference from the right (so like a mini-roundabout but with no markings), which are opposite preference from roundabouts here which are preference from the left. But some junctions are labelled, some aren't depending on whether the local council could be bothered, some people will forcefully use their preference and risk a crash but 90% will ignore it. Driving in Belgium - the scripting equivalent of batch files
- liaukovv 10y agoSo people don't call it directly Defense mechanism of sorts
- masklinn 10y agoAlso limits chances of conflict with user-defined code.
- deleted 10y ago[deleted]
- rdtsc 10y agoIt is a convention for protocols. There are others you see __len__, __eq__, __new__, __str__ and so on. It did seem odd at first (I learned, C, Java, C++) first. But then after a while saw how it fits in a consistent way in the language. Make many things simpler, fits with duck-typing, fits with how classes are constructed, and so on. Visually it stands out right away, you so you know by looking these are special methods (say instead of being called "init", "eq" or "new") Felt the same way about "self" argument. But then now I really like it and see it as a very nice idea.
- deleted 10y ago[deleted]
- kozhevnikov 10y ago"The use of double underscores to indicate "magic" words goes at least as far back as the C preprocessor, which used that convention starting in the 1970s (e.g., __FILE__, __LINE__). It did so because there were no symbols that were off-limits to the preprocessor, so a rarely-used naming pattern (multiple underscores and upper case words) virtually ensured a lack of conflicts." http://programmers.stackexchange.com/a/228340/84451 http://programmers.stackexchange.com/a/228340/84451
- pmelendez 10y agoThere was a technical reason for C though, the preprocessor is just a bit more than an automatic text replace, in Python it seems it was just a design decision. Also in C those where not words embedded in the language, in python case it is.
- zubspace 10y agoCall me ignorant, but I agree. Having something like __init__ and __new__ is very confusing for a beginner, along with stuff like "__init__.py". It doesn't stop there: Take something like __str__ and __repr__ combined with str(), repr(), vars(), dir(), print(), pprint.pprint()... I have no idea how anyone ever thought it was a good idea to have that many ways to output the content of a variable. Even after all the time I used python I never managed to find a consistent way to output variable values. I generally like python as a scripting language. But stuff like this made me constantly lookup obscure details in the documentation which made it very hard for me to completely embrace the language. It also prevented me from diving into more arcane stuff like meta-programming...
- dismantlethesun 10y ago> combined with str(), repr(), vars(), dir(), print(), pprint.pprint() Very true! Though since in practice, most people simply use a graphical debugger or pick one of the above as their champion (pprint.pprint is my personal favourite), then I doubt this situation will ever be changed.
- amyjess 10y agoThe dunder functions are there to provide an interface to global functions and operators. If you want to affect how str(x) behaves, you override x's __str__() method. Operators behave this way too: for example, if you want to overload the == operator for a class, you override __eq__() in that class (for any Java developers reading: Python == works like Java equals(); the Python version of Java == is the is operator, which cannot be overloaded). Yes, that means x == y is just syntactic sugar for x.__eq__(y). The dunders are there so you have the freedom to name your methods what you want without having to worry that you'll accidentally clobber a method that affects a global or an operator, as most people won't just up and decide to both begin and end a method's name with __.
- pmontra 10y agoAgreed. That, the explicit self argument (which no other major OO language needed) and the : at the end of lines where you would need a { in other languages. If you google you find that there are good reasons for all of those choices but IMHO they are wrong solutions to the problem they solve and make Python look ugly. At least in 2016 they could make the colon optional. The colon is so ironic for a language that takes pride in replacing braces with indentation. It's there because of readability, see https://docs.python.org/3/faq/design.html#why-are-colons-required-for-the-if-while-def-class-statements https://docs.python.org/3/faq/design.html#why-are-colons-req... but so, how about an almost Erlang-like full stop? if condition: statement statement. That would make semantic indentation optional, IDEs and editors know how to reindent code, spare us with bugs introduced by careless copy and paste. Nevertheless, Python has been widely successful and it's here to stay for a long while. I hope designers will look at those bizarre features and think of better solutions for future languages. Remember that Python has its roots in the 80s. By the standards of the time it was very good. Compare it with the order of magnitudes worse design of PHP, from middle 90s, and there is a lot to forgive to Python. Maybe Guido Van Rossum would make different choices if he were to design his language now, under the influence of the languages of the last 20 years.
- guitarbill 10y ago> how about an almost Erlang-like full stop? This is just brackets/braces in disguise, at which point you might as well follow convention and use {}. This is obviously a very personal issue, but for me, the whitespace has less cognitive load. E.g.: in languages with brackets, people usually still indent the code for readability. I've also found that when teaching people to program, consistency works well. I think this is one of the reasons Python is easy to pick up, just because Python code consistently looks like Python.
- pmontra 10y agoFor those languages is not people who reindent code but it's the editor or the IDE. There is usually a key to force reindentation. That is possible because {} or even the end in Ruby are easy markers for the block (there are multiple markers for a block start in Ruby). Is there any automatical indentation function in some editor for Python? If not, it's Python the unfortunate language where people has to indent code to feed the compiler. I always hated doing the compiler's job. I'm asking because I'm using Python little and only for short scripts, so I didn't bother investigating much. Still I've been bitten a couple of times by bugs introduced by moving code around and not noticing that a line was not indented correctly. That in Python and in Haml (http://haml.info/ http://haml.info/) If somebody knows about those tools I will appreciate and it will make my life easier. BTW, I'm fixing somebody's else Python scripts right now :-)
- perlgeek 10y agoThe second annoyance is that you need to write __init__ methods quite often. Correct me if I'm wrong, but there doesn't seem to be built-in support in Python for having attributes initialized by the the constructor. For example in Perl 6, I can write class Point { has $.x; has $.y; } ... and I get a constructor Pair.new(x => 1, y => 42) for free, no need to write custom initializers.
- squeaky-clean 10y agoNothing built in, and generally not recommended, but you can do it! If you want to be really flexible and just allow any attribute, you can do this: class Foo: def __init__(self, *args, **kwargs): self.__dict__.update(**kwargs) And it will automatically assign any keyword arguments you use as attributes to the object. For example `foo = Foo(name='Bob', age=99)` If you still want to keep a strict list of allowed attributes, you can define them as parameters, and use a shortcut to assign all local variables to attributes. class Foo: def __init__(self, name, age): self.__dict__.update(locals()) del self.self So `foo = Foo(name='Bob', age=99)` will still work as will `foo = Foo('Bob', 99)`. But `foo = Foo('Bob', 99, True)` will throw an error, as will `foo = Foo(name='Bob', age=99, likes_cake=True)`. You can add kwargs back to the parameter list if you want to allow assigning any attribute. This isn't recommended though. So for all practical purposes, Python does require a bit of boilerplate in the constructor. Edit: Realized a cleaner way to do the second example.
- amyjess 10y agoI believe you could also accomplish this with a metaclass, as well.
- mmariani 10y agoJust import attrs [0] and don't worry about those annoying dunder methods. [0] https://pypi.python.org/pypi/attrs/16.0.0 https://pypi.python.org/pypi/attrs/16.0.0