我有一个包的结构如下:
/backends/
__init__.py
abc.py
def.py
ghi.py
xyz.py
common.py
模块abc.py
,def.py
,ghi.py
和xyz.py
包含一些常见功能,例如func0()
和func1()
。
在common.py
模块中,我从所有模块导入*,如下所示:
from abc import *
from def import *
from ghi import *
from xyz import *
我认为这不是 Pythonic 的方法。想想几十个这样的模块。
我想要的是一个单行语句,它从包中的所有模块导入*。像这样:
from backends import *
我试过了this link,却无法得到我想要的东西。我在__all__
中创建了一个变量__init__.py
,并为其分配了所有模块的列表。我把这个导入行放在common.py
模块中:
from . import *
然后我尝试访问包中的任何模块(func0()
和__init__.py
除外)中存在的函数common.py
。但它引发了一个错误,其中包含
ValueError: Attempted relative import in non-package
我需要一个详细的答案。
答案 0 :(得分:0)
这是我自己尝试的解决方案,它有效
我将假设您将使用common.py
作为主要模块,您将导入其中的其余模块,因此:
1 - 在__init__.py
文件中,添加:
import os
import glob
modules = glob.glob(os.path.dirname(__file__)+"/*.py")
__all__ = [ os.path.basename(f)[:-3] for f in modules if os.path.basename(f)[:-3] != 'common']
2 - 在common.py
添加:
import sys
from os import path
sys.path.append( path.dirname(path.dirname(path.abspath(__file__))))
#print sys.path #for debugging
import backends
#from backends import * #up to you, but previous is better
答案 1 :(得分:0)
瞧!找到了一个我完全满意的解决方案。 :-)
我没有触及__init__.py
模块。而是将以下代码放在common.py
模块的开头。
import os
pwd = os.path.dirname(os.path.realpath(__file__))
file_names = os.listdir(pwd)
for name in file_names:
if ".pyc" not in name and "__init__" not in name and "common" not in name and ".py" in name:
exec "from "+name[:-3]+" import *"
它有点像魅力。虽然我不知道这是否是最佳解决方案。我想在Python 3.x中,exec语句将如下:
exec("from "+name[:-3]+" import *")