gpt4 book ai didi

python:保存对 lambda 函数的引用的导入全局变量的状态

转载 作者:太空宇宙 更新时间:2023-11-03 10:48:08 25 4
gpt4 key购买 nike

背景故事 :
我试图实现一种处理 -v 参数的方法,以增加应用程序的详细程度。为此,我想使用一个最初指向空 lambda 函数的全局变量。如果给定 -v,则变量将更改并分配另一个 lambda 函数,该函数将其打印为输入。

MWE :
我注意到这在通过 from x import * 导入后从另一个模块调用 lambda 函数时没有按预期工作......

mwe.py:

from mod import *
import mod

def f():
vprint("test in f")

vprint("test before")
print("before: %d" % foo)
set_verbosity(1)
vprint("test after")
print("after: %d" % foo)
f()
mod.vprint("explicit: %d" % mod.foo)
modf()

模块.py:
vprint = lambda *a, **k: None
foo = 42

def set_verbosity(verbose):
global vprint, foo
if verbose > 0:
vprint = lambda *args, **kwargs: print(*args, **kwargs)
foo = 0

def modf():
vprint("modf: %d" % foo)

输出是
before: 42
after: 42
explicit: 0
modf: 0

其中“explicit”和“modf”输出是由于 mwe 末尾的 mod.vprintmodf 调用。 vprint 的所有其他调用(通过 vprint 的导入版本)显然没有使用更新的定义。同样, foo 的值似乎只导入一次。

问题 :
在我看来,好像 from x import * 类型的导入复制了导入模块的全局变量的状态。我对解决方法本身并不是很感兴趣,而是对这种行为的实际原因。这在文档中在哪里定义,理由是什么?

解决方法 :
作为旁注,无论如何实现这一点的一种方法是通过函数包装全局 lambda 变量并仅导出它们:
_vprint = lambda *a, **k: None

def vprint(*args, **kwargs):
_vprint(*args, **kwargs)

def set_verbosity(verbose):
global _vprint
if verbose > 0:
_vprint = lambda *args, **kwargs: print(*args, **kwargs)

这使得它可以使用 import-from 方式,允许其他模块简单地调用 vprint 而不是通过模块的名称显式延迟。

最佳答案

在黑暗中随机刺伤:

If you look at the docs for __import__ ,有一点:

On the other hand, the statement from spam.ham import eggs, sausage as saus results in

_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], 0)
eggs = _temp.eggs
saus = _temp.sausage


我认为这是关键。如果我们推断 from mod import * 结果如下:
_temp = __import__('mod', globals(), locals(), [], 0)
printv = _temp.printv
foo = _temp.foo

这说明问题是什么。 printv 是对旧版本 printv 的引用; mod.printv 在导入时指向什么。重新分配 printvmod 指向的内容不会影响 mwe 中的任何内容,因为 mweprintv 的引用仍在查看之前的 lambda。

它类似于这不会改变 b 的方式:
a = 1
b = a
a = 2
b 仍然指向 1 ,因为重新分配 a 不会影响 b 正在查看的内容。

另一方面, mod.printv 确实有效,因为我们现在在 mod 中使用对全局的直接引用,而不是在 printv 中使用指向 mod 的引用。

这是一个随机的刺伤,因为我想我知道基于我前一段时间做的一些随机阅读的答案。如果我不正确,请告诉我,我会删除它以避免混淆。

关于python:保存对 lambda 函数的引用的导入全局变量的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57293994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com