简体   繁体   English

从python包中的所有模块导入*

[英]Import * from all modules in a package in python

I have a package whose structure is like this: 我有一个结构如下的包:

/backends/
    __init__.py
    abc.py
    def.py
    ghi.py
    xyz.py
    common.py

The modules abc.py , def.py , ghi.py and xyz.py contain some common functions eg func0() and func1() . 模块abc.pydef.pyghi.pyxyz.py包含一些常用功能,例如func0()func1()

In the common.py module I am importing * from all modules like this: common.py模块中,我从所有这样的模块中导入*:

from abc import *
from def import *
from ghi import *
from xyz import *

I don't think this is a Pythonic way to do this. 我认为这不是Python的方法。 Think about a few tens of such modules. 考虑几十个这样的模块。

What I want is to have a single line statement which imports * from all the modules in the package. 我想要的是一条单行语句,该语句从包中的所有模块导入*。 Something like this: 像这样:

from backends import *

I tried this link , but couldn't get what I wanted. 我尝试了此链接 ,但无法获得想要的东西。 I created a variable __all__ in the __init__.py and assigned the list of all modules to it. 我在__init__.py创建了一个变量__all__ ,并为其分配了所有模块的列表。 The I put this import line in the common.py module: 我把这个导入行放在common.py模块中:

from . import *

And then I tried to access the function func0() which is present in any module (except in __init__.py and common.py ) in the package. 然后,我尝试访问该程序包中任何模块( __init__.pycommon.py除外func0()中存在的func0()函数。 But it raised an error which reads 但它引发了一个错误,内容为

ValueError: Attempted relative import in non-package

I need a detailed answer. 我需要详细的答案。

Here is a solution I tried myself and it worked, 这是我尝试过的解决方案,它确实有效,
I'll presume that you will be working with common.py as your main module where you'll be importing the rest modules in it, so: 我假设您将使用common.py作为您的主要模块,在其中您将导入其余模块,因此:

1 - In the __init__.py file, add: 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 - In common.py add: 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

Voila! 瞧! Found a solution which I am completely satisfied with. 找到了我完全满意的解决方案。 :-) :-)

I left the __init__.py module untouched. 我没有__init__.py模块。 And instead put the following codes in the beginning of the common.py module. 而是将以下代码放在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 *"

It worked like charm. 它像魅力一样运作。 Though I don't know whether this is the best solution. 虽然我不知道这是否是最佳解决方案。 I guess in Python 3.x, exec statement will be like following: 我猜在Python 3.x中,exec语句将如下所示:

exec("from "+name[:-3]+" import *")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM