覆盖从 python 中的模块导入的变量

override variable imported from module in python

a.py:

import sys

h = 'this is h from a.py'

for i in sys.argv:
    if i in ['-h']:
        print(h)

b.py:

import sys
from a import h


h='this is h from b.py'
for i in sys.argv:
    if i in ['-h']:
        print(h)

然后我得到:

>$  python b.py -h
 this is h from a.py
 this is h from b.py

'h' 不应该被覆盖吗?还是 a.py 访问 '-h' 给 b.py 的参数?

谢谢

当你导入 a 时,a.py 中的所有代码都会被执行,因此你将始终得到打印输出:

this is h from a.py

要避免它,您可以将 a.py 更改为:

import sys

h = 'this is h from a.py'

if __name__ == '__main__':
    for i in sys.argv:
        if i in ['-h']:
            print(h)

这样,if子句中的代码只会在你调用python a.py -h时执行,而不会在你调用python b.py -h时执行。

主要问题

您可以使用以下代码覆盖 b.py 中的变量:

import a
a.h = 'actually replaced value'

注意:实际将其添加到 a.py 仍会得到以下结果:

>$  python b.py -h
 this is h from a.py
 this is h from b.py


创造想要的行为

首先请注意,您可以使用以下代码验证 h 的值是否已更改:

a.py:

import sys

h = 'this is h from a.py'

for i in sys.argv:
    if i in ['-h']:
        print(h)


def what_is_h():
    print('h:', h)

b.py:

import sys
from a import h, what_is_h
import a

what_is_h()
a.h = h = 'this is h from b.py'
what_is_h()

for i in sys.argv:
    if i in ['-h']:
        print(h)

结果如下:

this is h from a.py
h: this is h from a.py
h: this is h from b.py
this is h from b.py

第一个 what_is_h 调用显示原始 h 值,第二个显示修改后的值。问题是 a.pyb.py 似乎有不同版本的变量 h 这就是所谓的作用域。当您使用 import 语句时,python 会解析您的文件并 运行 生成代码。防止代码自动 运行ning 的方法是将它放在一个函数中,导入它并从 b.py 中 运行ning 最好将 h 作为参数传递(因为全局状态在 python 中通常是不好的做法)。

"What if I want to run a function from a.py too but only if I run it directly?"

现在,如果你想在 运行 a.pyb.py 时执行一个函数,但 运行 a.py 中的函数仅当它是 运行 你可以直接在脚本文件的底部添加以下内容:

if __name__ == '__main__':
    my_function()

只有当您执行 $> python a.py 时,才会 运行 函数 my_function。 请注意,当导入 a.py 时,它不会 运行 my_function 除非 运行 否则。

这是如何工作的? __name__ 是一个内置的全局变量,用于存储 python 解释器提供给 python 脚本的 "name"。 运行 的文件被赋予 __name__ '__main__'。现在,当从 a.py 导入某些内容时,__name__ 将等于 'a'my_function 将不会 运行.

更多样式说明和代码提示

  • 平等:

而不是

if i in ['-h']:
  # ... your code

if i == '-h':
  # ... your code

如果你想稍后检查多个标志,你可以更改它。

  • 检查某物是否在列表或类似序列的对象中:

如果你只想检查 -h 是否在 sys.args 中,你可以这样做:

if '-h' in sys.args:
  # ... your code

而不是

for i in sys.args:
  if i == '-h':
    # ... your code
  • 解析、处理和处理命令行参数

如果你打算用参数做更复杂的事情,那么每个 python 的安装默认都应该包含一个库,即 argparse 库。

希望我能帮到你。