gpt4 book ai didi

python - 从 .py 文件中获取包根和完整模块名称以进行导入

转载 作者:行者123 更新时间:2023-11-28 19:25:14 24 4
gpt4 key购买 nike

我正在寻找一种简单快速的方法来从 .py 文件的路径中找到包的根目录和完整的模块名称。

我希望用户选择一个 .py 并在不中断的情况下导入它。如果模块是包的一部分,则导入模块可能会中断。因此,我想自动将包根目录所在的目录附加到 sys.path(如果不在其中),然后使用完整的模块名称导入模块。

我没有从同一目录或该脚本的任何地方运行,所以我不能使用 __file__ 之类的东西。另外我还没有导入模块,所以我不能(据我所知)检查模块对象,因为没有。

这是一个工作版本,但我有兴趣找到更简单/更快的解决方案。

def splitPathFull(path):
folders=[]
while 1:
path,folder=os.path.split(path)

if folder!="":
folders.append(folder)
else:
if path!="":
folders.append(path)

break

folders.reverse()
return folders

def getPackageRootAndModuleNameFromFilePath(filePath):
"""
It recursively looks up until it finds a folder without __init__.py and uses that as the root of the package
the root of the package.
"""
folder = os.path.dirname(filePath)
if not os.path.exists( folder ):
raise RuntimeError( "Location does not exist: {0}".format(folder) )

if not filePath.endswith(".py"):
return None

moduleName = os.path.splitext( os.path.basename(filePath) )[0] # filename without extension

#
# If there's a __init__.py in the folder:
# Find the root module folder by recursively going up until there's no more __init__.py
# Else:
# It's a standalone module/python script.
#
foundScriptRoot = False
fullModuleName = None
rootPackagePath = None
if not os.path.exists( os.path.join(folder, "__init__.py" ) ):
rootPackagePath = folder
fullModuleName = moduleName
foundScriptRoot = True
# It's not in a Python package but a seperate ".py" script
# Thus append it's directory name to sys path (if not in there) and import the .py as a module
else:
startFolder = folder

moduleList = []
if moduleName != "__init__":
moduleList.append(moduleName)

amountUp = 0
while os.path.exists( folder ) and foundScriptRoot == False:

moduleList.append ( os.path.basename(folder) )
folder = os.path.dirname(folder)
amountUp += 1

if not os.path.exists( os.path.join(folder, "__init__.py" ) ):
foundScriptRoot = True
splitPath = splitPathFull(startFolder)
rootPackagePath = os.path.join( *splitPath[:-amountUp] )
moduleList.reverse()
fullModuleName = ".".join(moduleList)

if fullModuleName == None or rootPackagePath == None or foundScriptRoot == False:
raise RuntimeError( "Couldn't resolve python package root python path and full module name for: {0}".format(filePath) )

return [rootPackagePath, fullModuleName]

def importModuleFromFilepath(filePath, reloadModule=True):
"""
Imports a module by it's filePath.
It adds the root folder to sys.path if it's not already in there.
Then it imports the module with the full package/module name and returns the imported module as object.
"""

rootPythonPath, fullModuleName = getPackageRootAndModuleNameFromFilePath(filePath)

# Append rootPythonPath to sys.path if not in sys.path
if rootPythonPath not in sys.path:
sys.path.append(rootPythonPath)

# Import full (module.module.package) name
mod = __import__( fullModuleName, {}, {}, [fullModuleName] )
if reloadModule:
reload(mod)

return mod

最佳答案

由于 namespace packages 这是不可能的- 根本无法确定 baz.py 的正确包是 foo.bar 还是只是具有以下文件结构的 bar:

foo/
bar/
__init__.py
baz.py

关于python - 从 .py 文件中获取包根和完整模块名称以进行导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14835909/

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