python 中怎么动态 import 模块?

2016-03-14 00:32:12 +08:00
 dsp2138
需要根据不同的条件导入不同的模块该怎么做?
现在用__import__()可以导入,但怎么导入某个包下的模块
A 文件夹下 fun.py需要导入子目录 A1 中的 a.py,b,py,c.py 其中 a.py 有 class Auser,b.py 中有 class Buser,c.py 中有 class Cuser,
用 if 判断不同的条件导入分别导入 a.py,b.py.c.py
我怎么该怎么做?

谢谢
我这里是 python3.4
7626 次点击
所在节点    Python
27 条回复
fy
2016-03-14 02:03:16 +08:00
楼主你问之前不妨先试一下:

if True: import re
else: import json

In [51]: re
Out[51]: <module 're' from 'd:\\python34\\lib\\re.py'>

In [52]: json
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-52-832ed6b85533> in <module>()
----> 1 json

NameError: name 'json' is not defined
ericls
2016-03-14 02:17:21 +08:00
if a:
import A
if b:
import B
if c:
import C
gx
2016-03-14 03:15:07 +08:00
看一下 import_module 实现,当然, 3.x 直接用了。

"""Backport of importlib.import_module from 3.x."""
# While not critical (and in no way guaranteed!), it would be nice to keep this
# code compatible with Python 2.3.
import sys

def _resolve_name(name, package, level):
"""Return the absolute name of the module to be imported."""
if not hasattr(package, 'rindex'):
raise ValueError("'package' not set to a string")
dot = len(package)
for x in xrange(level, 1, -1):
try:
dot = package.rindex('.', 0, dot)
except ValueError:
raise ValueError("attempted relative import beyond top-level "
"package")
return "%s.%s" % (package[:dot], name)


def import_module(name, package=None):
"""Import a module.

The 'package' argument is required when performing a relative import. It
specifies the package to use as the anchor point from which to resolve the
relative import to an absolute import.

"""
if name.startswith('.'):
if not package:
raise TypeError("relative imports require the 'package' argument")
level = 0
for character in name:
if character != '.':
break
level += 1
name = _resolve_name(name[level:], package, level)
__import__(name)
return sys.modules[name]
gx
2016-03-14 03:18:20 +08:00
2.x 的朋友移步 /PATH_TO_YOUR_PYTHON_LIB_FOLDER/importlib/__init__.py
restran
2016-03-14 08:46:47 +08:00
还可以根据字符串动态导入包

```py
def import_string(dotted_path):
"""
Import a dotted module path and return the attribute/class designated by the
last name in the path. Raise ImportError if the import failed.
"""
try:
module_path, class_name = dotted_path.rsplit('.', 1)
except ValueError:
msg = "%s doesn't look like a module path" % dotted_path
raise ImportError(msg)

module = import_module(module_path)

try:
return getattr(module, class_name)
except AttributeError:
msg = 'Module "%s" does not define a "%s" attribute/class' % (
module_path, class_name)
raise ImportError(msg)
```

使用方法

`import_string('a.b.c')`
knightdf
2016-03-14 08:52:29 +08:00
if else.....
import 几乎可以写在任何位置。。。写函数里也行,用的时候再 import
jimzhong
2016-03-14 08:54:13 +08:00
import 本来就是动态的哦
Anthony117
2016-03-14 08:57:30 +08:00
mengzhuo
2016-03-14 09:16:26 +08:00
标题党… ifelse 这叫动态 import ?
我还以为说的是生成动态 class 和模块呢……
我实现过这个,很好玩,感兴趣的同学可以联系我
ksc010
2016-03-14 09:23:22 +08:00
应该是根据变量来导入不同的模块

原来也遇到这样的问题,需要实现一个插件机制
解决的办法有点笨: 现在一个目录(plugs/)的__init__.py 导入所有的需要的插件模块
然后 在里面定义一个 函数 下面是简化代码

def getPlug(plugname):
glb=globals()

return glb[plugname]

其它地方要引用的话
直接
from plugs import getPlug

plug=getPlug('plugA')
ksc010
2016-03-14 09:25:01 +08:00
@ksc010 这个仅仅是在调用层看着比较“优雅”
实际上还是把所有的模块预先导入进来了
thinker3
2016-03-14 10:21:04 +08:00
@mengzhuo 你是说会写程序的程序?
nevin47
2016-03-14 10:41:02 +08:00
我在猜 LZ 是不是想说在 ABC 文件都还不确定的情况下去 import ?

我赞同 @restran 的方法,前几天做了一个自动适配的模块就用了这种方法,根据传参来动态 Import 模块
leyle
2016-03-14 11:29:33 +08:00
from importlib import import_module
dsp2138
2016-03-14 11:39:56 +08:00
@mengzhuo 请教,应该怎么做,或许我没有把需求说明白
自定义的模块如果有数十个
用 if else 这样当然可以导入,但这代码肯定是惨不忍睹!
请教,该怎么做
dsp2138
2016-03-14 11:42:50 +08:00
@ksc010 考虑预先导入是不是会占用内存,所以想需要是导入用完回收!我这里理解可否对?
Phant0m
2016-03-14 11:47:47 +08:00
mengzhuo
2016-03-14 12:07:39 +08:00
@thinker3
是的呢,这才有意思嘛~
代码、类啊、常量、函数啊都完全是按数据生成的,
然而上层完全不知道,还是按传统方法 import 和使用~

@dsp2138
如果只是你这样需要时调用而已,那直接全部 import 也不是事。
预先导入肯定占内存的,但是比起数据来说都是小菜一碟。
thinker3
2016-03-14 13:11:57 +08:00
@mengzhuo 我发现我已经特别关注你了。
loading
2016-03-14 13:25:06 +08:00
@dsp2138 一堆 if else 就感觉不优雅?你没写过复杂的的业务吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/263256

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX