1、没有使用global进行标记
python开发中有时候会发现全局变量修改无效,在当前py文件中是修改成功的,但是跳转到其他py文件中无效。此时要注意,修改全局变量的时候,需要加入一行代码global global_var,才表示修改的是全局变量。
def set_global_var(value: int):
global global_var
global_var = value
2、main方法中使用了全局变量,后续其他py文件中修改无效
如果main方法就在a.py的文件中,在import a.py之前,在main方法中使用了a.py的全局变量C,后续在b.py中修改了a.py的全局变量C的修改不会生效。
当你在a.py中定义了全局变量,并且在同一个文件(a.py)的if __name__ == "__main__":块中使用这个全局变量,然后在另一个文件(比如b.py)中修改这个全局变量,你的期望是在a.py中对这个全局变量的修改能够反映出来。但实际情况会有所不同,这里我们详细解释一下原因和可能的解决方案。
场景概述
- a.py:定义了全局变量
C,并且在if __name__ == "__main__":块中使用了C。 - b.py:导入
a.py并修改全局变量C。
为什么修改不会生效
当你运行a.py时,__name__变量被设置为"__main__",这意味着if __name__ == "__main__":块中的代码会被执行。如果在这个时候b.py尝试导入a.py,由于Python模块的导入机制设计为只导入一次以避免重复导入带来的性能损失,因此在b.py中对a.py的全局变量C的修改是在一个不同的上下文中进行的,这个修改只会影响后续的导入和使用,而不会反映到已经执行的if __name__ == "__main__":块中的使用。
示例说明
# a.py的代码
C = 10
def print_C():
print("a.py:", C)
if __name__ == "__main__":
print_C() # 第一次打印C的值
import b
print_C() # 第一次打印C的值
import a a.C = 20 # 试图修改a.py中的C a.print_C() # 检查C的值是否已经被修改
当你直接运行a.py,它会首先打印C的原始值(例如:a.py: 10),然后尽管b.py修改了C的值并且在b.py的上下文中这个修改是有效的(a.print_C()会打印出修改后的值),但是这个修改对a.py中if __name__ == "__main__":块的执行没有影响,因为那部分代码在b.py修改C之前就已经执行了。
执行结果:
a.py: 10 a.py: 20 a.py: 10 #main中打印时,a.C的值没有被修改过来
解决方案
这个问题的根源在于Python的模块导入机制和执行流程,理解这一点有助于更好地组织和设计你的代码结构。
- 如果你想要在
a.py运行结束后看到修改,你需要确保在修改全局变量C之后再进行依赖于C的操作。这可能意味着需要重新组织代码结构,或者通过其他机制(例如定义一个函数来专门修改和处理C,然后在适当的时候调用这个函数)。 - 如果目的是实现某种类型的配置或状态管理,考虑使用配置文件、环境变量或者专门的状态管理模块,而不是依赖于修改模块级别的全局变量。
- (👍推荐)把
main方法单独放到一个文件main.py中,这样main.py就只能明确写import a,此时后续的a.py模块都在同一个上下文环境,执行a.C的修改就统一了。
# main.py
import a
if __name__ == "__main__":
a.print_C() # 第一次打印C的值
import b
a.print_C()
3、使用poetry的时候,增加自定义pypi源
可以在pyproject.toml中,在[build-system]的前面,加入下面的代码(primary表示是主源,supplemental表示是补充源)
[[tool.poetry.source]] name = "tencent" url = "https://mirrors.cloud.tencent.com/pypi/simple/" priority = "primary" [[tool.poetry.source]] name = "aliyun" url = "http://mirrors.aliyun.com/pypi/simple/" priority = "supplemental" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"
沪公网安备 31011502001064号