如何更改相对导入搜索路径

时间:2016-05-13 21:01:10

标签: python import relative

我试图创建一个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) 

2 个答案:

答案 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 2

答案 1 :(得分:0)

使用sys模块 使用此文件夹结构:

RootDir
    |-- module.py
    |--ChildDir
        |-- main.py

现在在main.py你可以做

import sys
sys.path.appned('..')
import module

相信还有其他黑客,但这是我所知道的,并且符合我的目的。我不确定,是否最好选择某种auto_import的东西。