Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何从模块动态导入所有方法和属性_Python_Python 2.7_Python Import_Python Importlib - Fatal编程技术网

Python:如何从模块动态导入所有方法和属性

Python:如何从模块动态导入所有方法和属性,python,python-2.7,python-import,python-importlib,Python,Python 2.7,Python Import,Python Importlib,我想动态加载一个模块,给定它的字符串名(来自环境变量)。我正在使用Python 2.7。我知道我可以做一些事情,比如: import os, importlib my_module = importlib.import_module(os.environ.get('SETTINGS_MODULE')) 这大致相当于 import my_settings from my_settings import * (其中SETTINGS\u模块='my\u SETTINGS')。问题是,我需要的东西

我想动态加载一个模块,给定它的字符串名(来自环境变量)。我正在使用Python 2.7。我知道我可以做一些事情,比如:

import os, importlib
my_module = importlib.import_module(os.environ.get('SETTINGS_MODULE'))
这大致相当于

import my_settings
from my_settings import *
(其中
SETTINGS\u模块='my\u SETTINGS'
)。问题是,我需要的东西相当于

import my_settings
from my_settings import *
因为我希望能够访问模块中的所有方法和变量。我试过了

import os, importlib
my_module = importlib.import_module(os.environ.get('SETTINGS_MODULE'))
from my_module import *

但是我在做这件事时犯了很多错误。在Python 2.7中,是否有一种方法可以动态导入模块的所有方法和属性?

如果您有模块对象,您可以模仿
导入*
使用的逻辑,如下所示:

module_dict = my_module.__dict__
try:
    to_import = my_module.__all__
except AttributeError:
    to_import = [name for name in module_dict if not name.startswith('_')]
globals().update({name: module_dict[name] for name in to_import})

然而,这几乎肯定是一个非常糟糕的主意。您将随意践踏任何具有相同名称的现有变量。通常,当您从blah import*执行
时,这已经够糟糕的了,但是当您动态执行时,对于哪些名称可能会发生冲突,存在更多的不确定性。您最好只导入
my_模块
,然后使用常规属性访问(例如
my_模块.someAttr
)从中访问所需内容,或者
getattr
如果你需要动态访问它的属性。

我的情况有点不同-想要动态导入每个
gameX中的constants.py名称。uuuu init_uuuuuuuy.py
模块(见下文),因为静态导入这些将永远留在sys.modules中(见:这是我从Beazley挑选的)

以下是我的文件夹结构:

game/
 __init__.py
 game1/
   __init__.py
   constants.py
   ...
 game2/
   __init__.py
   constants.py
   ...
每个
gameX.\uuuu init\uuuuuuuuupy
导出一个init()方法-因此我最初在所有
gameX.\uuuuu init\uuuuuuuuupy
中都有一个
from.constants import*
,我试图将其移到init()方法中

我的第一次尝试是:

@-275,2+274,6@@def init():
#调用而不是“重新加载”
+牦牛={}
+yak.update(locals())
+from.constants import*#在此失败
+yak={x:y代表x,y在局部变量中()如果x不在yak}
+globals().update(yak)
brec.ModReader.recHeader=记录头
失败的原因相当隐晦:

SyntaxError:函数“init”中不允许导入*,因为它包含带有自由变量的嵌套函数

我可以向您保证,其中没有嵌套函数。不管怎样,我进行了黑客攻击,最终得到了:

def init():
    # ...
    from .. import dynamic_import_hack
    dynamic_import_hack(__name__)
游戏中的何处。\uuuu init\uuuuuuuuuuupy

def dynamic\u import\u hack(包名称):
打印_name _#game.init
打印包_name#game.gameX.init
导入导入库
常量=importlib.import_模块('.constants',package=package_名称)
导入系统
对于dir中的k(常数):
如果k.startswith(“”“):继续
setattr(sys.modules[package_name],k,getattr(constants,k))
(有关setattr,请参阅,而关于getattr,我更喜欢使用它们,而不是直接访问
\uuuu dict\uuuu

这是可行的,它比公认答案中的方法更通用,因为它允许您在一个地方使用黑客,并从任何模块使用它。然而,我并不确定这是实施它的最佳方式——我打算问一个问题,但由于这将是一个重复的问题,我将其作为一个答案发布,并希望得到一些反馈。我的问题是:

  • 为什么在没有嵌套函数的情况下,函数“init”中不允许使用此“SyntaxError:import*
  • dir有很多警告——特别是它试图产生最相关的信息,而不是完整的信息——这让我有点担心
  • 是否没有内置的方法来执行
    导入*
    ?即使在Python3中

没有准确回答所述问题,但如果您希望将文件作为动态模块的代理,您可以使用在模块级别定义
\uuu getattr\uuu
的功能

import importlib
import os

module_name = os.environ.get('CONFIG_MODULE', 'configs.config_local')
mod = importlib.import_module(module_name)

def __getattr__(name):
    return getattr(mod, name)

您不能简单地使用
eval
?我决定只设置Django的Django_SETTINGS_模块环境变量,而不是将变量加载到default SETTINGS.py中。看起来这是正确的答案,所以谢谢你的帮助!我自由地编辑了与
import*
行为更匹配的代码。如果我出错或更改了意图,请随时恢复。此顶级代码是从文件结构的哪一部分运行的?正如在对原始问题的评论中所建议的,你能用
eval
来做这件事吗?@sundance:我知道了eval是什么,然后我忘记了:P-gameX init文件是动态导入的,然后我们保留了我们需要的文件-我们需要这样做以确保这些文件在那里并且工作,但是现在您提到它,我们最好避免这种情况——请参阅:(此代码还导入了所有其他代码——我在这里发布的代码仍然位于我的本地树上)