我试图创建一个auto_import函数,它是库的一部分:这样做的目的是避免在from .x import y
文件中多次列出__init__
,只做这个事情{{1这将在import lib; lib.auto_import(__file__)
所在的文件夹中搜索python文件,并通过exec语句导入所有内容(即__init__
)。
我的问题是,不知何故来自'来自'语句总是尝试从lib目录导入.x,即使我将cwd更改为放置实际exec('from .x import abc')
文件的目录...我该如何解决这个问题?我应该如何更改__init__
语句的搜索目录?
结构:
from .
例如:$ ls -R
.:
app.py lib x
./lib:
__init__.py auto_import.py
./x:
__init__.py y
./x/y:
__init__.py y.py
包含./x/y/__init__.py
auto_import正在检查import lib; lib.auto_import(__file__)
目录中的文件并用__file__
导入它们(但是来自。的文件夹总是lib文件夹而不是exec('from .{} import *')
的目录,这是我的问题,如何将其更改为__file__
的目录
当然整个东西都是在app.py中导入的,如:
__file__
由于
EDIT1:final auto_import(globals()/ gns无法避免)
import x
print(x.y)
答案 0 :(得分:1)
您的方法问题是auto_import
中定义了lib/auto_import.py
,因此exec('from .x import *')
的上下文始终为lib/
。即使您设法修复路径问题,lib.auto_import(__file__)
也不会将任何内容导入lib.x.y
的命名空间,因为该函数位于另一个模块中。
__import__
这是auto_import脚本:
myimporter.py
# myimporter.py
def __import_siblings__(gns, lns={}):
for name in find_sibling_names(gns['__file__']):
gns.update((k,v) for k,v in __import__(name, gns,lns).__dict__.items() if not k.startswith('_'))
import re,os
def find_sibling_names(filename):
pyfp = re.compile(r'([a-zA-Z]\w*)\.py$')
files = (pyfp.match(f) for f in os.listdir(os.path.dirname(filename)))
return set(f.group(1) for f in files if f)
在lib/x/y/__init__.py
#lib/x/y/__init__.py
from myimporter import __import_siblings__
__import_siblings__(globals())
假设您有一个需要导入y
的虚拟模块:
#lib/x/y/dummy.py
def hello():
print 'hello'
测试它:
import x.y
x.y.hello()
请注意,由于名称空间污染,from lib import *
通常为bad habit。请谨慎使用。
答案 1 :(得分:0)
使用sys
模块
使用此文件夹结构:
RootDir
|-- module.py
|--ChildDir
|-- main.py
现在在main.py
你可以做
import sys
sys.path.appned('..')
import module
相信还有其他黑客,但这是我所知道的,并且符合我的目的。我不确定,是否最好选择某种auto_import
的东西。