简体   繁体   中英

__init__.py :: make a sub module routines available at top level import

Assume the following structure...

root/test.py
root/myapp/__init__.py
root/myapp/myapp.py       # contains My_App_Class()
root/myapp/SomeObject.py  # contains My_Obj_Class()

If my __init__.py contains the following structure:

from myapp import *
import SomeObject

__all__ = ['SomeObject']

I want to be able to call myapp and have the routines pre-extracted from myapp/myapp.py so that I can do the following in test.py :

import myapp

if 'My_App_Class' in myapp.__dict__.keys():
    print 'success'
else:
    print 'fail'

if 'My_Obj_Class' in myapp.SomeObject.__dict__.keys():
    print 'success'
else:
    print 'fail'

so that I can effectively collapse from myapp.myapp import * into from myapp import *

In [1]: %run test.py
fail
success

The __all__ attribute in yur __init__.py file is what is preventing other names (imported from myapp/myapp.py) from being visible when using the myapp package.

Just don't use the all - and maybe, to avoid ambiguity, change the import written as:

from myapp import *

to

from .myapp import *

In other words, your __init__.py file should be simply:

from .myapp import *
import SomeObject

and no other line.

Your test.py on the other hand if further incorrect - if it starts with import myapp , all of myapp/myapp.py's names will be in the myapp namespace. You should change that first line to be from myapp import * as you put further down in the question.

Mandatory note: You should avoid doing import * and variantes in Python projects that import names from packages. Python programs and projects should always import individual names from packages/modules - with the name written explicitly, anyone reading your code will know exactly from were each function or class you use came from. Moreover, IDE's and other programming tools will be able to check for non-existing or inconsistent names and warn you.

However, note it is ok to use from module import * inside a package's __init__.py to get the names exposed (in the __all__ export) in each of the package's modules into the package namespace itself - which is what you want.

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