通配符子集导入



我们都被告知使用from module import *是一个坏主意。但是,是否有一种方法可以使用通配符导入module内容的子集 ?

例如:

module.py:

MODULE_VAR1 = "hello"
MODULE_VAR2 = "world"
MODULE_VAR3 = "The"
MODULE_VAR4 = "quick"
MODULE_VAR5 = "brown"
...
MODULE_VAR10 = "lazy"
MODULE_VAR11 = "dog!"
MODULE_VAR12 = "Now"
MODULE_VAR13 = "is"
...
MODULE_VAR98 = "Thats"
MODULE_VAR99 = "all"
MODULE_VAR100 = "folks!"
def abs():
    print "Absolutely useful function: %s" % MODULE_VAR1

显然我们不想使用from module import *,因为我们会覆盖abs函数。但是假设我们确实希望所有的MODULE_VAR*变量都可以在本地访问。

简单地放from module import MODULE_VAR*行不通。有办法做到这一点吗?

我使用了100个变量作为例子,因为from module import MODULE_VAR1, MODULE_VAR2, MODULE_VAR3, ..., MODULE_VAR100显然是难以置信的笨拙,如果添加更多的变量(例如MODULE_VAR101)将无法工作。

您可以有一个辅助函数而且不用魔法也能做到:

import re
def matching_import(pattern, module, globals):
    for key, value in module.__dict__.items():
        if re.findall(pattern, key):
            globals[key] = value

现在,你可以这样做:

from utils import matching_import
import constants
matching_import("MODULE_VAR.*", constants, globals())

以这种方式显式地使用globals()避免了通常被认为有害的框架自省魔法。

在使用import *语法时,可以使用__all__变量导入特定的变量。

mymodule.py

__all__ = [
  'MODULE_VAR1',
  'MODULE_VAR2',
  'MODULE_VAR3',
  'MODULE_VAR4',
  'MODULE_VAR5',
]
MODULE_VAR1 = "hello"
MODULE_VAR2 = "world"
MODULE_VAR3 = "The"
MODULE_VAR4 = "quick"
MODULE_VAR5 = "brown"
def abs():
  print "Absolutely useful function: %s" % MODULE_VAR1

那么我们可以这样使用它:

from mymodule import *
print MODULE_VAR1 # hello
print abs # <built-in function abs>

当使用*导入模块时,Python会检查模块中是否存在__all__变量,该变量可以覆盖模块中正常的"公共"变量(即不以下划线开头的变量),并允许您显式定义哪些变量为"公共"。看看这个问题

最新更新