5 ms·
While this repo is great for education, it doesn't cover the deep problems with Python that you only discover when you try to do something "unapproved" or sligh
by tgbugs 6y ago
While this repo is great for education, it doesn't cover the deep problems with Python that you only discover when you try to do something "unapproved" or slightly off the happy path. Depending on the domain you are working in you may never encounter such a situation, but if you do, be prepared to lose your sanity one omnipresent design flaw at a time.
Over the years I've been collecting a series of cases that are somewhat more nihilistic and depressing under the general category of LOL PYTHON. The little inconsistencies, the boilerplate that is required if you don't want to use only the approved, not performant, and breaks all sorts of other hidden assumptions so you can't actually use the code outside very narrow settings approach, eventually just evoke a nihilistic chuckle and a note to never start a new Python project again.
- einpoklum 6y agoI think you forgot the link to your collection?
- tgbugs 6y agoThere are some that you can find in [0], but they are often de-contextualized (and sometimes aren't really Python's problem, because there was a trade off that had to be made, and the LOL is just frustration as a result of the bad ergonomics that it creates), those and some others will eventually go in an longer post when I finally get that set up. To give one concrete example of an LOL PYTHON consider the @property decorator. While it seems like a really cool and handy idea that could let you save some typing in some cases, it is actually a trap that you should almost never use because when you inevitably discover that there is some parametrization that you need to pass to the ... attribute, you are suddenly faced with a massive refactoring. Also if you ever make the mistake of having boolean properties such as isDir or isUrl and somewhere else you have a predicate that is a function instead of a property then isFile will always return True when you meant isFile(). The only safe solution is to never use properties/attributes as predicates. These are nasty footguns that seem obscure and unlikely to affect you until you have the misfortune to already be in the briar patch. 0. https://github.com/search?q=%22LOL+PYTHON%22+user%3Atgbugs&type=code https://github.com/search?q=%22LOL+PYTHON%22+user%3Atgbugs&t...
- silvester23 6y agoIf I understand correctly, I think the problem with your second example is that you should avoid checking for `True` with something like `if isFile` but instead `if isFile is True`. That would solve this specific problem (and is also slightly more efficient because no implicit boolean conversion is performed).
- roywiggins 6y agoYou can do that, but loose checking for truthiness is pretty pythonic. It's weird to put "true" in there if you think you're checking a boolean property. If you know you're not, then you realize you need to call the function and then you can remove the "is".
- tgbugs 6y agoThis one is a bit more subtle. Assume there are two classes on that uses @property and one that does not. class Here: @property def booleanPredicate(self): return random_bool() class There: def anotherBooleanPredicate(self): return random_bool() here = Here() there = There() What happens in the following cases? here.booleanPredicate # as expected here.booleanPredicate() # loud failure here.anotherBooleanPredicate # silently always True here.anotherBooleanPredicate() # as expected So you might think that you should _always_ use @property for boolean predicates, except that there are libraries that use the anotherBooleanPredicate version so you are now at risk for silent always True behavior (creeping sanity destroying evil behavior). To prevent the silent failure you should always start by calling the predicate so that it can fail loudly. Worse if someone does a refactor and misses going from @property form to function form then the silent failure literally cannot be detected by running the program (!).
- at_a_remove 6y agoI am not trying to be edgy here when I say that I have viewed a lot of the "syntactic sugar" business with a great deal of skepticism. Piggybacking off of your example, upon reflection I believe that me looking askance at decorators is partially a learned fear (I escaped Perl), and partially because decorators seem a little like "bad magic," where you have cast a handy but seemingly innocuous spell only to find that it has deeper consequences later.
- FridgeSeal 6y agoI would be so keen to read this if you ever document them somewhere!
- TeMPOraL 6y agoThat's the flip side of "There should be one— and preferably only one —obvious way to do it." Engineering is the art of trade-offs. Same problem with different requirements needs a different solution.
- fire7000 6y agoThere is, its called C /s
- tgbugs 6y agoTrue, but the problem is that in pursuit of that mantra the language has wound up disempowering engineers and has forced even more decisions about trade-offs onto them: do you want readability, performance, or maintainability? You usually can't have all of them because of some lurking performance tar pit. An example here is the conflict between needing top level imports for sanity and static analysis (there was an instagram blog on this a while ago) while also wanting fast startup time. If you import requests at the top level then you cannot have fast startup time, so you wind up importing it outside the top level so that code paths that don't use requests don't have to pay the time cost of loading it, but then you have imports that aren't at the top level! edit: oh, and don't even get me started on pkg_resources [0], which isn't just a tarpit, it is a full blown blackhole beartrap waiting for the unsuspecting. 0. https://github.com/pypa/setuptools/issues/510 https://github.com/pypa/setuptools/issues/510
- michaelcampbell 6y agoEnter Django.