简体   繁体   中英

Making a python3 package both importable and runnable

I'm transitioning over some old scripts from python v2.7 to v3.6, and one of the things I want to do is have a package that can (a) be imported to expose inner workings to other scripts, but also (b) be runnable from the command line to run in typical ways.

In python2 this was not difficult -- I used both an __init__.py file (for importing) and a __main__.py file (for running). But in python3, this doesn't seem to work -- for example, take the minimal package:

minimal/
  __init.py__
  __main.py__
  func.py
  func2.py

__init__.py

from .func import f
from .func2 import add2

__main__.py

from func import f
f(1)

func.py

from .func2 import add2
def f(x):
  print(add2(x))

func2.py

def add2(x):
  return x + 2

If I open python and type import minimal this works just fine, but if from the command line I type python minimal/ I get the error:

ImportError: attempted relative import with no known parent package

This arises at line 1 of func.py, at the import of func2. If I instead remove the period from that line so it is instead from func2 import add2 , then I can run python minimal/ from the command line just fine. But when I try to open python and run import minimal , at that same line I get the error:

ModuleNotFoundError: No module named 'func2'

I understand that the period is required for intra-package importing, but is there any way to make this work within the main script as well? Or another package structure that would allow both imports and running?

Change your project structure to:

minimal_cmd/
├── __main__.py
└── minimal
    ├── __init__.py
    ├── func.py
    └── func2.py

and do a fully qualified import in __main__.py :

if __name__ == '__main__':

    from minimal.func import f

    f(1)

Calling from the command line:

$ python minimal_cmd
3

and importing when minimal is the the current working directory or if the package is on the PYTHONPATH:

>>> import minimal
>>> minimal.f(2)
4

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