简体   繁体   中英

Is this a python antipattern? 'import foo.foo as foo' shadows the rest of the foo package

Say I start off with package pack that contains a module foo.py .

pack/
pack/__init__.py
pack/foo.py        # Defines class Foo

But for reasons, I decide I need to move foo.py to a subpackage. Perhaps my foo is very strong and I need more functionality to manage it. Since the subpackage is all about foo, I name it foo as well, so now we have

pack/
pack/__init__.py
pack/foo
pack/foo/__init__.py
pack/foo/foo.py        # Defines class Foo

"Ah", I say, "I can make things backward compatible and avoid inflicting on calling code the excessive foo-ness of pack.foo.foo.Foo() with the following import in pack/__init__.py ...

$ cat pack/__init__.py
import foo.foo as foo

...so that I can use pack.foo.Foo() to initialize a Foo ."

Unfortunately, this means the module foo.py shadows the rest of the foo package, so that only the contents of pack/foo/foo.py are visible.

That's all expected behavior, my question is, would this rise to the level of an antipattern? It seems like at each step the decisions make a certain sense, so it's sort of an easy road to wander down (I have a couple of times) until all that additional functionality that motivated the subpackage says "hey what about us?"

Is there a pythonic way to turn a module into a subpackage like this, taking into account naming and backwards compatibility? The foo.foo.Foo in particular is irksome ( datetime.datetime notwithstanding) but maybe the answer is "just deal with it" and eat the backwards incompatibility. I toyed with putting a from foo import * somewhere, but that seems wrong. Or am I missing some simple solution?

Despite my comment that the real solution is to avoid such deeply nested namespaces, I think the best approach to solving the issue once you are in it is probably to move the contents of pack/foo/foo.py into the pack/foo/__init__.py file. That way you can still have other modules within the pack.foo package, but also access the Foo class and whatever else was in foo.py from the same place as before ( pack.foo ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM