gpt4 book ai didi

python - 使用类作为局部变量的容器对象替代Python中的 'nonlocal'

转载 作者:太空宇宙 更新时间:2023-11-04 09:52:47 25 4
gpt4 key购买 nike

问题

在 Python 中,如果我有一个带有局部变量和嵌套函数的函数,我可以在 nonlocal 的帮助下在嵌套函数中分配这些变量:

def f():
x = 0
def _g():
nonlocal x
x = 1
def _h():
x = 2
_g()
_h()
print(x)
f() # 1

我对这个解决方案的问题是,如果我在 f() 中有很多局部变量,那么 nonlocal 的使用会很冗长,更令人不安的是,很容易忘记变量的 nonlocal,并在嵌套函数而没有注意到它(例如,我在上面的 h() 函数中的真正意思是什么?)。

我已经看到并使用了替代方案:

def f():
class state:
x = 0
def _g():
state.x = 1
def _h():
x = 2
_g()
_h()
print(state.x)
f() # 1

如果使用 Python 中的类实际上也是一个对象这一事实。以这种方式使用“类”实际上是为局部值创建可变容器的最不冗长的方式(我相信)。

我认为这个模式有两个值得怀疑的方面:

  • “class”关键字的这种特殊用法可能会被视为 hack。
  • 由于容器有点人为化,有时很难为它找到一个好名字(我什至测试过为它使用“self”这个名字,但这似乎更像是一个 hack)。

这是一个好的模式吗?您通常使用哪些替代方案?

如果 StackOverflow 不是解决这个问题的正确论坛,请在您认为更合适的其他论坛上提出建议(我确实阅读了常见问题解答,但对于这个问题正确的论坛对我来说不是很明显)。

提前致谢。

附言

为了完整起见,至少还有一个替代方案,感觉更像是 hack:

class f:
def __init__(self):
self.x = 0
self._g()
self._h()
print(self.x)
def _g(self):
self.x = 1
def _h(self):
x = 2
f() # 1

这是可行的,因为在 Python 中,类实例化与函数调用具有相同的语法。

回答

请参阅下面接受的答案。有关函数需要返回值时的解决方案的讨论,请参阅 there .

最佳答案

您的“最后手段”替代方案当然更简洁 - 如果您可以使用共享状态的扁平化方法来执行此操作,那么与执行相同工作的嵌套函数相比,代码可读性更高。 “平面优于嵌套”。

除此之外,您正在创建一个具有命名空间的类。你可以简单地创建一个对象作为命名空间,它会作为一个命名空间——这更常见。唯一的问题是,如果你只是简单地创建一个object本身的实例,它不能作为命名空间,因为它没有__dict__,所以你不能随意为此的属性对象。

这就是为什么在 stdlib 的 types 模块中有一个名为 SimpleNamespace 的类正是用于此用例。

只是做:

from types import SimpleNamespace

def f():
state = SimpleNamespace()
state.x = 0
...

(但前提是您不改变主意并选择基于类的解决方案,它无论如何都更干净)。

关于python - 使用类作为局部变量的容器对象替代Python中的 'nonlocal',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47064953/

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