首页 > 编程问答 >为什么当我们返回主程序时,这个全局不会保持更新,除非我向程序添加一个新的入口点?

为什么当我们返回主程序时,这个全局不会保持更新,除非我向程序添加一个新的入口点?

时间:2024-08-01 08:37:55浏览次数:18  
标签:python python-3.9

m1 是collect_finetuning.py 中的全局变量:

m1: list = []

当我通过以下方式运行collect_finetuning.py 时:

if __name__ == "__main__":
    main()

我们看到这种行为,其中collect_finetuning 中的函数更新了m1,并且它丢失了main() 中的更新值:|| |我能够在第二张图片(主)中获得相同的函数,以包含 m1 的现已更新版本,按预期,只需运行此脚本而不是直接运行collect_finetuning.py:

enter image description here

enter image description here

如果我不这样做这,当我返回到 main 时,在 invoke() 之后,我得到:

from scripts.collect_finetuning import main

main()

我很困惑为什么它会起作用(m1 保持更新,当我们返回到 main() 时我可以继续使用它的更新值,以及为什么直接运行collect_finetuning.py不会保留m1的更新值,请帮助我理解为什么这有效,谢谢! print("m1 was:", m1) []

I am so confused as to why this worked (m1 stays updated and I can continue to use its updated value when we return back to main(), and why running collect_finetuning.py directly doesn't retain the updated value of m1. Please help me understand why this worked, thank you!


这个问题的关键在于你如何运行代码以及 Python 如何处理模块作用域。

行为差异的原因

  • 直接运行 collect_finetuning.py : 当你直接运行 collect_finetuning.py 时,它被视为 主模块 。这意味着它的 __name__ 属性会被设置为 "__main__" 。因此, if __name__ == "__main__": 块内的代码会被执行,包括调用 main() 函数。任何对 m1 的修改都发生在这个主模块的作用域内。

  • 导入并调用 main() : 当你从另一个脚本导入 collect_finetuning 并调用 main() 时, collect_finetuning.py 被视为一个 模块 。它的 __name__ 属性会被设置为模块的名称(即 "collect_finetuning")。因此, if __name__ == "__main__": 块内的代码 不会被自动执行 。你只是导入了模块,并调用了其中的 main() 函数。在这个情况下,对 m1 的修改仍然发生在 collect_finetuning 模块的作用域内,而不是调用脚本的作用域内。

为什么添加入口点有效

当你添加一个新的入口点脚本并从中调用 collect_finetuning.main() 时,你实际上是在创建一个新的执行环境。这个新的环境会导入 collect_finetuning 模块,并执行它的 main() 函数。在这个新的环境中, collect_finetuning.m1 被修改,并且这个修改在新的环境中是可见的。

解决方法

为了避免这种混淆,最好 不要依赖全局变量在模块之间共享状态 。以下是一些替代方法:

  • 函数参数和返回值 : 将 m1 作为参数传递给需要它的函数,并在函数完成时返回更新后的值。
  • : 使用类来封装数据( m1 )和操作它的方法。这样可以更清晰地管理状态。

示例

# collect_finetuning.py
def collect_data():
  m1 = []
  # ... 修改 m1 ...
  return m1

def main():
  m1 = collect_data()
  print("m1 in main:", m1)

# main_script.py
from scripts.collect_finetuning import main

if __name__ == "__main__":
  main()

在这个例子中, collect_data 函数负责修改 m1 ,并将更新后的值返回给 main 函数。这种方式更清晰地表达了数据流,避免了全局变量带来的问题。

标签:python,python-3.9
From: 78817930

相关文章

  • 跟踪 VScode 中的 python 警告
    我想知道哪一行代码导致我的代码中引发警告。可以在VScode中实现吗?例如,我在终端中看到警告:目前,我只能看到在python终端中引发警告的导入模块,但我无法将其跟踪到代码的确切行,只能跟踪到该行导入模块的。也许,可以在警告上添加断点或更改某些设置,或使用扩展?以下......
  • ffmpeg python 导致死锁
    我在使用ffmpegpython处理相机帧时遇到问题。我使用process.communicate()的第一种方法效果很好,但存在延迟问题。process=(ffmpeg.input('pipe:',format='rawvideo',pix_fmt='rgb24',s='{}x{}'.format(width,height))......
  • 将 HTTP 分块编码数据流代码片段从 Node.js 转换为 Python
    我有一个Node.js客户端代码,它将请求发送到HTTP服务器,然后连续接收分块编码数据。这是带有一些流量数据输出的Node.js代码。consthttp=require('http');constoptions={hostname:'...',path:'...',port:...,...};constreq=http.request(......
  • 如何从python读取matlab持续时间对象
    我创建一个matlab持续时间对象并将其保存到.mat文件:timeend=seconds(123);save('time.mat',timeend,'-v7.3');然后我从python读取它:withh5py.File('time.mat','r')asf:var=f['timeend'][:]print(list(var))......
  • 通过 python 连接到 Snowflake 时出错“UnpicklingError: invalid load key, '\x00'
    我在使用snowflake.connector.connect通过python连接到snowflake时遇到以下错误importsnowflake.connector#pipinstallsnowflake-connector-python#iamgettingtheenvfrom.envfileistoredlocallycnx=snowflake.connector.connect(user=os.getenv('USER'),pass......
  • Python Selenium 单击 webdriverwait 与 find_element
    我无法理解这两个代码块之间的区别。发送点击在webdriverwait和find_elements中都有效。代码1fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.suppo......
  • 使用Python时如何避免`setattr`(和`getattr`)?以及是否有必要避免
    如果我想向协议缓冲区中的字段添加一个在编译时未知的值,我目前正在做setattr我通常不喜欢使用setattr,因为它看起来不太安全。但是当我知道该对象是protobuf时,我认为这很好,因为我设置它的值必须是protobuf允许的类型。所以也许它并不是真的不安全?让我举......
  • Java sshtools 生成的 EDDSA 签名与 Python 的 pycryptome 生成的签名不匹配
    我有一个python库,它使用pycryptodomelibrary使用openssh格式的ED25519私钥使用Ed25519算法对数据进行签名。然后需要使用sshtools库和相应的公钥在Java应用程序中验证签名。但是签名验证失败。约束:从文件中读取私钥/公钥很重要。我无法......