Uncommon Uses of Python in Commonly Used Libraries
eugeneyan.com
eugeneyan.com
Yes, they make reading imports across your entire project rather difficult: Suddenly there are multiple ways of referring to the same module. If you ever have to do a project-wide search & replace during a refactoring (because your favorite refactoring tool failed you), this will be hell.
Moreover, in each file you'll end up with a weird blend of absolute and relative imports, depending on what was shorter or looked nicer to the author at the time. Not nice to look at at all.
> This led me to dig into why we might add to __init__.py
…or why we might rather not. Init files are one of the main reasons imports in Python often behave in unexpected ways. As a library user I do not want to study the library's init files first, but unfortunately I often have to in order to understand what is going on. (Case in point: Tensorflow 1/2. To this day, I can't claim I understand how exactly their init magic works and time and again I get bitten by failed imports.)
> Moreover, in each file you'll end up with a weird blend of absolute and relative imports, depending on what was shorter or looked nicer to the author at the time. Not nice to look at at all.
it sounds like your project had inconsistent import styles leading to this issue. IMO imports should always be relative and always be one imported symbol per line, they should be sorted and linted [1] that they follow this exact form. you will have no issues with imports, merges, search and replaces, etc. after that.
[1] I use https://pypi.org/project/flake8-import-order/ along with an in-house import rendering tool.
If you’re not maintaining one of the libraries listed in the article, and try to pull any of this “clever” stuff you’ll be bitten on the ankle by a pythonic snake. No exceptions.
The piece doesn't present the correct way to use multiple inheritance in python, so this section is a bit of a strawman. Namely, it is the responsibility of the inheritor to call init on all subclasses with the arguments it wants to pass on. Maybe the python 3 addition of super() has muddled this responsibility somewhat.
If we use the solution in the piece then we lose the ability to pass non-identity expressions in the arguments we received on to the base classes, and also the ability to have same named arguments but with different values.
If a class wants to pass non-identity expressions, and the underlying base classes use the piece's methodology, then you get a bug.
I'm honestly tired of explaining to people that this line of Python zen does not mean that there shouldn't be more than one ways to do something. On a very literal level, it states that there should be one obvious way to do it -- and in no way defines how many non-obvious ways there should be.
What you're calling "clever" stuff is just regular Python functionalities, even if many of them are non-obvious. The only thing before something being "simple" and "clever" is how much is an individual familiar with something.
I know I'm guilty of doing dynamic library imports and monkey patching things.
For example, shared a blog post I found few days ago on injecting custom Python syntax/functions into local code; obviously problematic, but something Python doesn’t even attempt to prevent, in part because it is open source:
Strongly disagree. It is perfectly possible to do that without adding anything into __init__. I prefer explicit imports and any other logic declared directly into the module(s) that are the places where one would expect to find those.
I see code in __init__ as a convenient hack, but a hack nonetheless.
Yes, in fact I started my first message with a clear "As a personal opinion...".
Apart from that, the comparison with metaclasses does not make sense. Metaclasses are an OOP concept.
https://www.programcreek.com/python/index/module/list
https://stackoverflow.com/questions/tagged/python?tab=Votes
Anyone know of any others or large collections of Python source code that are easy to download?
Direct link to the chart, see “133.7” Python version (elite version) in the top right:
https://github.com/hugovk/pypi-tools/blob/main/images/all.pn...
Which is from:
Even more rare is overriding bitwise shift operations: __rshift__, __lshift__ etc. This is unfortunate, as these methods are only natively implemented in integers, so they’re basically freebies.
Those are the bitwise operators (a & b, a | b). You can’t override the behavior of the boolean operators (a and b, a or b), you can only define the truthiness of your object with __bool__.
No thanks, I'll suffer through reading a few additional lines of:
class SomeBusinessyThing:
def __init__(self, util, other_util):
self._util = util
self._other_util = other_util
@classmethod
def create(cls):
return cls(util_module.Util(), other_module.Other())
def calculate(self):
source = self_other_util.get_source()
return self._util.get_stuff(source)
vsclass SomeBusinessyThing(Utils, Other):
def __init__(self, \*kwargs):
# What does this do? No one knows
super().__init__(self, \*kwargs)
def calculate(self):
source = self.get_source()
return self.get_stuff(source)Wish there was a way to visualize or rate how average code is - especially two separate versions covering same concept; hence my other comments on resources to quantify usage patterns.
I would think that Inwoukd hate the above code but actually I appreciate it and prefer it. It's great.
I suspect it is a hard pre-commit check but you would want to only inherit from classes with no conflict- then if there are it is down to this approach (!)
SomeBusinessyThing.__mro__
https://docs.python.org/3/library/stdtypes.html#class.__mro_...Using multiple inheritance to implement certain common functionality, using mixin classes, is possible in Python; it's another powerful tool in the arsenal, but doesn't mean that you have to use it.
Inheritance works best to denote "is-a" relationships, i.e. for defining subtypes, especially when using type annotations and checks. Sometimes - albeit very rarely - you need a class that belongs to two separate type hierarchies; multiple inheritance comes very handy in those cases.
(Btw that's the only way to implement inheritance in Rust, even single inheritance.)
In which way? MRO is very well defined.
> manually delegating to distinct member variables
Again, this is composition, which has nothing to do with inheritance. If you need to define a subtype, inheritance is most straightforward.
I guess I'd probably use a decorator in Python but this was R and I was on an S4 buzz back then so I took the approach above.
Conflicts are determined by the MRO. If some classes don't call super(), then they won't call super --> classes further down the MRO won't be called and won't be initialized.
The choice isn't: multiple inheritance or a couple lines. In the right situation, multiple inheritance could save hundreds of lines and condense a complicated mechanism into a simplistic one. Used flippantly, they can be a nightmare -- but that's true of all programming paradigms.
Also, guessing that Google was likely one of the first systems widely used that was implemented in part using Python.
https://stackoverflow.com/questions/17654103/running-bram-co...