简体   繁体   中英

Python package import own files, without knowing the package name at compile time

 - app.py
 - Datatypes/
    - string/
       - __init__.py
       - SomeModule.py

My python application loads packages dynamically, loading each package within the Datatypes directory, if the string module ( init .py) wants to import SomeModule.py it must do so using its path from app.py (the file being executed) eg.

import Datatypes.string.SomeModule

I would rather have a way to import relative modules, without having to know the name of the package (directory name) eg.

import __self__.SomeModule

Is this possible? If so how would I achieve this

If you don't know the path, find it using os.listdir() .

If you know the path, use __import__ :

>>> math.factorial(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>> mod='math'
>>> math=__import__(mod)
>>> math.factorial(10)
3628800

Of course, you need to keep a reference either to the module (variable math in my example) or to the element in the module you want to use later.

If the files are in the same directory then you can use the normal

import module_name

If absolute imports have been turned on, then you can still import relative paths with

from . import module_name

I created a similar structure in a temporary directory:

.
./main.py
./package
./package/__init__.py
./package/sub_module.py

The main.py simply imports all the package's variables into its own namespace and prints the contents of the namespace:

from package import *
from pprint import pprint
print(dir())

The package/__init__.py file runs when the package is imported. It uses relative module references to specify that the required module can be found in the same directory:

from .sub_module import *

The package/sub_module.py module is imported by the __init__.py of the package. It simply sets three variables:

x = y = z = 0

When the program is run ...

airhead:tmp sholden$ python main.py
['__builtins__',
 '__doc__',
 '__file__',
 '__name__',
 '__package__',
 'pprint',
 'sub_package',
 'x',
 'y',
 'z']

you can see, the names from package\\sub_module.py are imported into the main module's namespace via the package namespace.

Because packages can have a recursive structure you can use two dots to represent the package above the containing package, three dots to indicate the package containing that package, and so on. Though if you need more than three dots you might want to consider refactoring :-).

This system was devised and documented in PEP 328 .

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