【问题标题】:Python: wildcard subset importPython:通配符子集导入
【发布时间】:2013-06-18 01:29:57
【问题描述】:

我们都被告知使用from module import * 是一个坏主意。但是,有没有办法使用通配符导入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)将无法工作。

【问题讨论】:

    标签: python import wildcard


    【解决方案1】:

    您可以为此设置一个辅助函数 - 而且不用魔法就可以做到:

    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() 可以避免帧内省魔法,这通常被认为是有害的。

    【讨论】:

      【解决方案2】:

      在使用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__ 变量,该变量可以覆盖模块中原本被视为普通“公共”变量的变量(即不会启动的变量)带下划线)并允许您明确定义哪些变量是“公共的”。 Check out this question

      【讨论】:

      • 这太棒了!但是如果你对模块的源代码没有控制权,有没有什么办法可以达到同样的效果呢?
      • 对不起,我误会了。我不知道从另一个模块本地导入特定变量的任何方法。但作为一个非常简单的解决方案,您可以创建一个助手来导入模块并迭代模块的属性以提取您想要的变量。在您的示例中,这将防止 abs 变量被覆盖,您不是导入模块变量而是导入模块本身。或者,您可以在函数范围内导入模块变量,防止内置abs 函数被覆盖。我认为@jsbueno 有一个完美的例子。
      • 我不知道你是否误会了——我不是问这个问题的人,我只是好奇。谢谢!
      • 哦,好点。我错过了!哈哈。但看起来我仍然可能误解了,OP 正在寻找更多@jsbueno 的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      • 2013-05-30
      • 2023-03-20
      • 2013-06-03
      • 1970-01-01
      相关资源
      最近更新 更多