嵌套函数中修改全局变量并同步更新引用该变量的全局字典问题
解决Python全局变量与字典字段同步更新的问题
你遇到的核心问题是Python字典存储的是值,而非变量的引用。当你初始化requ = {"Host": codomain}时,Python会把codomain当时的字符串值"line.me"复制到字典的Host字段里,而不是保存对codomain变量的引用。所以之后哪怕你修改了codomain变量的值,字典里的Host字段依然是最初的拷贝,不会自动更新。
下面给你几种可行的解决方案,从简单到优雅:
方案1:直接同步更新字典的Host字段
这是最直观的方法,当你修改codomain后,手动更新requ字典的Host字段。修改你的text函数即可:
def text(): print("1. Insert Target Domain") print("2. Leave it as default") print("") ansi=input(" Choose Option : ") global codomain # 声明使用全局变量 if str(ansi)=="1": codomain=input(" Domain : ") requ["Host"] = codomain # 关键:同步更新字典的Host字段 print(f"{codomain} Selected as Domain") else: pass print(" Outside " + f"{codomain}") print(" Check " + f"{requ}") r=requests.get("http://linecorp.com",headers=requ)
这样修改后,当用户输入新域名时,既更新了全局变量codomain,也同步修改了requ字典的Host字段,后续请求就会使用新的域名。
方案2:用可变对象包装codomain(进阶技巧)
如果希望字典能自动跟随变量变化,可以把codomain放在一个可变对象里(比如列表)。因为列表是引用类型,字典存储的是对这个列表的引用,修改列表内容时字典会自动感知:
import requests codomain = ['line.me'] # 用列表包装字符串值 requ = { "Host": codomain, # 这里存储的是列表的引用 "DNT": "1", "Accept-Language": "*", "Accept": "*/*", "Accept-Encoding": "*", "Connection": "keep-alive", "Upgrade-Insecure-Requests": "1" } def text(): print("1. Insert Target Domain") print("2. Leave it as default") print("") ansi=input(" Choose Option : ") if str(ansi)=="1": new_domain = input(" Domain : ") codomain[0] = new_domain # 修改列表中的元素 print(f"{new_domain} Selected as Domain") else: pass print(" Outside " + f"{codomain[0]}") print(" Check " + f"{requ}") # 请求时需要把列表转换成字符串 headers = {k: v[0] if k == "Host" else v for k, v in requ.items()} r=requests.get("http://linecorp.com", headers=headers)
这个方法利用了Python中可变对象的引用特性,不过需要注意发送请求时要把Host对应的列表元素转换成字符串。
方案3:动态生成请求头(推荐)
最优雅且不易出错的方式是每次需要请求头时,根据当前的codomain动态生成,彻底避免同步问题:
import requests codomain = 'line.me' def get_request_headers(): # 每次调用都基于当前最新的codomain生成请求头 return { "Host": codomain, "DNT": "1", "Accept-Language": "*", "Accept": "*/*", "Accept-Encoding": "*", "Connection": "keep-alive", "Upgrade-Insecure-Requests": "1" } def menu(): ans=input(" Choose : ") if str(ans)=="1": opti=input(" Choose Option : ") if str(opti)=="1": def text(): print("1. Insert Target Domain") print("2. Leave it as default") print("") ansi=input(" Choose Option : ") global codomain if str(ansi)=="1": codomain=input(" Domain : ") print(f"{codomain} Selected as Domain") else: pass print(" Outside " + f"{codomain}") requ = get_request_headers() # 动态生成最新的请求头 print(" Check " + f"{requ}") r=requests.get("http://linecorp.com", headers=requ) text() menu()
这个方法的优势在于,每次需要请求头时都会重新生成,确保使用的是codomain的最新值,代码逻辑清晰,也不用额外维护变量和字典的同步关系。
内容的提问来源于stack exchange,提问作者MC874
相关产品推荐
相关产品推荐

