简体   繁体   中英

Python how to have a module I can execute and import from

I have a Python package mypackage which contains a bunch of modules / classes with this directory structure:

├── interface.py
├── mypackage/
|   └── __init__.py
|   └── classA.py
|   └── classB.py
|   └── ...

The current use case is to use interface.py with a bunch of argparse flags:

python interface.py --foo --bar 

Inside interface.py it instantiates a bunch of the classes with mypackage and runs their methods. Something like:

from classA import ClassA

def interfaceMethod(foo, bar):
    a = ClassA(foo, ...)
    print(a.classMethod(bar, ...)

if args.foo: interfaceMethod(args.foo, args.bar)

This works well when getting non-python / programmers to use my code. But I'd like to also be able to import my package within their Python code and run the same methods in interface.py . Something like:

import mypackage
print(mypackage.interfaceMethod(foo, bar)

Question

  • Is there a standard/best way to do this?
  • Note : I don't think users need to see my class structure so I'd rather there be one user facing class which implements all of the methods in interface.py

Solution 1 (I don't think this is the preferred solution):

Add methods from interface.py into __init__.py :

# in __init__.py
from classA import ClassA

def interfaceMethod():
    a = ClassA(foo)
    print(a.classMethod(bar))

Then users can do the following in their own code (it would look very similar in interface.py as well):

import mypackage
mypackage.interfaceMethod()

Solution 2 :

Create a mypackage class:

class MyPackage():
    self.classA = ClassA(...)
    self.classB = ClassB(...)

    def interfaceMethod():
        a = self.classA()

If I create this class should I worry about the package and class having the same name? Do I change the hierarchy of the package structure to reflect that MyPackage is the forward facing class?

A good way would to use a setup.py and use console_scripts

Put you interface.py inside you package and this to your setup.py :

setup(
    # other arguments here...
    entry_points={
        'console_scripts': [
            'script_name = my_package.interface:interfaceMethod',
        ],
    }
)

Change your interface.py to:

from classA import ClassA

def interfaceMethod(foo, bar):
    a = ClassA(foo, ...)
    print(a.classMethod(bar, ...)

if __name__ == '__main__':
    interfaceMethod(args.foo, args.bar)

Once you install with Python setup.py install , you can call your program from the command line:

script_name --foo --bar 

For details see the full documentation .

You can still import it with:

from mypackage import interface
interface.interfaceMethod()

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