【问题标题】:Different import behaviour for different modules不同模块的不同导入行为
【发布时间】:2017-05-15 17:54:55
【问题描述】:

我有三个模块 a.py、b.py 和 c.py。 a.py 模块是基础模块。我想要实现的是在 b.py 导入 a.py 和 c.py 导入 a.py 时具有不同的行为。例如:

a.py

def ab():
  return 5

def ac():
  return 6

if __nameoftheimportmodule__ == 'b':
  x = ab() 
elif __nameoftheimportmodule == 'c':
  x = ac() 
else:
  pass

因此,像这样调用 b.py

b.py

import a
print(a.x)

将返回 5(对于 c.py,它将返回 6)。

我的问题是这样的设计是否可能(例如,是否存在这样一个行为类似于上述导入模块名称的函数)?

【问题讨论】:

    标签: python import module


    【解决方案1】:

    我能找到的最接近该行为的解决方案是使用inspect module's stack function

    import inspect
    
    def ab():
        return 5
    
    def ac():
        return 6
    
    if inspect.stack()[1][1]  == 'b.py':
        x = ab() 
    elif inspect.stack()[1][1]  == 'c.py':
        x = ac() 
    else:
        pass
    

    inspect.stack()

    返回调用者堆栈的帧记录列表。第一个条目 返回列表中代表调用者;最后一个条目代表 堆栈上最外层的调用。

    inspect.stack()a.py调用时,我们得到

    [(<frame object at 0x102c25dd0>, '/Users/home/43985900/a.py', 3, '<module>', ['print inspect.stack()\n'], 0), (<frame object at 0x102c25c20>, 'c.py', 1, '<module>', ['print(a.x)\n'], -1)]
    

    我们对“最后一个条目表示堆栈上的最外层调用”感兴趣,因此我们将 stack 索引为 stack[1][1] 以获取 'c.py',并将其与调用模块的文件名进行比较。

    现在,当我们测试运行模块时,我们会得到预期的输出:

    $ python c.py
    6
    $ python b.py
    5
    

    改编自这个问题的答案:Get name of calling function's module in Python

    【讨论】:

      【解决方案2】:

      要做到这一点,您必须非常费力地使用导入系统,尤其是因为通常情况下,当第二个模块导入该模块的代码时,它甚至不会再次运行。 Python 只会重用在第一次导入时创建的相同模块对象,并存储相同的 x 值。

      您可以通过替换 __import__ 来做到这一点,或者使用导入系统提供的较少大锤的钩子之一,但这根本不值得,而且它不会导致程序易于理解或原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-05
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        相关资源
        最近更新 更多