Python Namespace Packages in Python3

前端 未结 2 1282
余生分开走
余生分开走 2021-02-11 16:47

The topic of namespace packages seems a bit confusing for the uninitiated, and it doesn\'t help that prior versions of Python have implemented it in a few different ways or that

2条回答
  •  野性不改
    2021-02-11 17:00

    This is a tough subject. All the -'s, _'s, and __init__.py's everywhere don't exactly make it easy on us.

    First, I'll answer your questions:

    With the __init__.py, which of these should I be using (if any)?

    • __init__.py can be completely empty, it just needs to be in the correct place. Namely (pun) they should be in any subpackage containing python code (excluding setup.py.) Follow those rules and you should be fine.

    With setup.py, do I still need to add the namespace_modules parameter, and if so, would I use namespace_modules=['org.common'], or namespace_modules=['org', 'common']?

    • Nope! Only name= and packages=. However, note the format of the packages= arg compared against the directory structure.
    • Here's the format of the package= arg:
    • Here's the corresponding directory structure:

    Could I forgo all of the above by just implementing this differently somehow? Perhaps something simpler or more "pythonic"?

    • If you want to be able to install multiple features individually, but under the same top-level namespace, you're on the right track.

    I'll spend the rest of this answer re-implementing your namespace package in native format:

    I'll put all helpful documentation I've been able to find at the bottom of the post.

    K so I'm going to assume you want native namespace packages. First let's look at the current structure of your 2 repos:

    org_client_client1_mod1/
      setup.py
      mod1/
        __init__.py
        somefile.py
    

    &

    org_common_config/
      setup.py
      config/
        __init__.py
        someotherfile.py
    

    This^ would be too easy!!!

    To get what you want:

    My brain isn't elastic enough to know if we can go 3-levels deep with namespace packages, but to do what you want, here's what I'm pretty sure you'd want to do:

    org-client/
      setup.py
      org/
        client/
          client1/
            __init__.py
            mod1/
              __init__.py
              somefile.py
    

    &

    org-common-but-also-note-this-name-doesnt-matter/
      setup.py
      org/
        common/
          __init__.py
          config/
            __init__.py
            someotherfile.py
    

    Basically then the key is going to be specifying the correct name= & packages= args to stuptools.setup() inside of each setup.py.

    These are going to be:

    name='org_client',
    ...
    packages=['org.client']
    

    &

    name='org_common'
    ...
    packages['org.common']
    

    respectively.

    Then just install each one with pip install . inside each top-level dir.

    Installing the first one will give you access to the somefile.py module, and installing the second will give you access to someotherfile.py. It also won't get confused about you trying to install 2 packages named org in the same environment.

    K so the most helpful section of the docs: https://packaging.python.org/guides/packaging-namespace-packages/#packaging-namespace-packages

    And then here's how I actually came to understand this: https://github.com/pypa/sample-namespace-packages/tree/master/native

提交回复
热议问题