gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 18:31:09 24 4
gpt4 key购买 nike

我正在尝试创建一个 auto_import 函数,它是库的一部分:这样做的目的是避免在 __init__ 文件中多次列出 from .x import y , 只做这个 import lib; lib.auto_import(__file__) <- 这将在存在 __init__ 的文件夹中搜索 python 文件,并通过 exec 语句导入所有内容(即 exec('from .x 导入 abc')).

我的问题是,即使我将 cwd 更改为放置实际 __init__ 文件的目录,'from' 语句总是尝试从 lib 目录导入 .x...我应该如何解决这个问题?我应该如何更改 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 包含import lib; lib.auto_import(__file__)auto_import 正在检查 __file__ 目录中的文件,并使用 exec('from .{} import *') 导入它们(但这来自 . 始终是 lib 文件夹,而不是__file__ 的目录,这是我的问题,如何将其更改为 __file__ 的目录当然,所有的东西都导入到 app.py 中,例如:

import x
print(x.y)

谢谢

EDIT1: final auto_import (globals()/gns 无法避免)

import os, sys, inspect

def auto_import(gns):
current_frame = inspect.currentframe()
caller_frame = inspect.getouterframes(current_frame)[1]
src_file = caller_frame[1]
for item in os.listdir(os.path.dirname(src_file)):
item = item.split('.py')[0]

if item in ['__init__', '__pycache__']:
continue

gns.update(__import__(item, gns, locals(), ['*'], 1).__dict__)

最佳答案

您的方法的问题是 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因为 namespace 污染。谨慎使用。

引用资料: 1 2

关于python - 如何更改相对导入搜索路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37219260/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com