11 ms·
I love Python for a lot of things but I’ve come to realize how complex it can really be. I regularly see others write Python code that I have to fix to add rob
by makecheck 8y ago
I love Python for a lot of things but I’ve come to realize how complex it can really be.
I regularly see others write Python code that I have to fix to add robustness. I also run "pylint" or equivalent tools before committing major changes to scripts because it is quite easy to make mistakes that won’t otherwise be found right away.
Some of my least favorite pitfalls:
- If you call a function that happens to refer to a variable that only exists in the calling code, it will work (and yes, since the same function can be called from more than one place, “caller” is not always the same so the effect is not always the same). Bonus points if it only matches the caller because of a typo. Any convenience afforded by this behavior is not worth the potential for head-scratching and painful debugging.
- Python has things that “seem” like the obvious/right thing to do when they are not. One great example is "except:", which to this day I have to keep correcting in various scripts to prevent important errors from being completely lost. Another one is expecting to write the entire script at column 0, when people are supposed to know 'if __name__ == "__main__"'. Also, a type’s apparent shared/unique status is not always clear so novices can get a long way with sort-of working code until they are completely confused by the broken cases (e.g. you can simply list and “initialize” class fields with trivial string and number values until one day you add something like a "dict()" and everything breaks for that one field because all your class instances are mysteriously sharing it; suddenly you need to define a whole new "__init__()" to fix things when it wasn’t apparently needed previously).
- It is not always obvious to maintainers of functions that keyword arguments are extremely fragile and that they can overlap with other arguments. If an argument is renamed or relocated for example, stuff elsewhere can break in stupid ways. Tiny code changes can create big headaches.
- duckerude 8y ago>If you call a function that happens to refer to a variable that only exists in the calling code, it will work This is not true. This code gives a NameError instead of printing "1": def f1(): print(var) def f2(): var = 1 f1() f2() If it can't find a name in the local scope, it will look in enclosing functions, then the module scope, then the builtins. But it will never look inside the caller's scope unless the function is defined in the caller's scope. Python's implicit scoping can be confusing, but it's not quite that bad.
- kbp 8y ago> If you call a function that happens to refer to a variable that only exists in the calling code, it will work Could you give an example of what you mean by this?
- Cu3PO42 8y agoNot the OP, but I think what they are referring to is the following: def foo(): return bar if ...: bar = 42 print(foo()) else: print(foo()) If ... evaluates to a truthy value, bar will be defined and foo() will return 42, if it is falsy, bar will not be defined and the code will throw a NameError. I would agree that this is extremely confusing behaviour. Of course people wouldn't write code like this (hopefully), but a similar situation might occur in a much more obscure situation.