Python 3.x 如何以优雅的方式修改Python3函数中作为**参数传递的不可变对象?

Python 3.x 如何以优雅的方式修改Python3函数中作为**参数传递的不可变对象?,python-3.x,immutability,Python 3.x,Immutability,我不确定这里的问题是什么,所以我真的不知道该如何称呼这个问题的主题。如果你知道,请提供一个更好的主题 下面的代码是原始代码的极端简化示例。但它很好地再现了这个问题。调用test()foo后,应该是sieben 我想我不知道Python中变量作用域的一些特殊情况。这可能是一个非常好的问题来了解更多关于这一点。但我不知道我应该把重点放在哪一个Python主题上,以找到自己的解决方案 #!/usr/bin/env python3 def test(handlerFunction, **handlerA

我不确定这里的问题是什么,所以我真的不知道该如何称呼这个问题的主题。如果你知道,请提供一个更好的主题

下面的代码是原始代码的极端简化示例。但它很好地再现了这个问题。调用
test()
foo
后,应该是
sieben

我想我不知道Python中变量作用域的一些特殊情况。这可能是一个非常好的问题来了解更多关于这一点。但我不知道我应该把重点放在哪一个Python主题上,以找到自己的解决方案

#!/usr/bin/env python3
def test(handlerFunction, **handlerArgs):
    handlerFunction(**handlerArgs)

def myhandler(dat):
    print('dat={}'.format(dat))
    dat = 'sieben'
    print('dat={}'.format(dat))

foo = 'foo'
test(myhandler, dat=foo)
print('foo={}'.format(foo))
当然,我可以使
foo
成为
global
变量。但这不是目标。我们的目标是在不同级别的子函数中携带此变量并返回结果。在原始代码中,我使用了一些更为复杂的数据结构和
**handlerArgs

一个解决方案可以是使用
list()
作为持有不可变对象的可变对象。但这真的是优雅的还是蟒蛇式的


**
语法与此无关
dat
是myhandler的本地变量,分配它不会更改同名的全局变量。如果要从函数内部更改模块变量,请在函数体开头将变量声明为
global

def myhandler(): # you don't need to pass dat as argument
    global dat
    print('dat={}'.format(dat))
    dat = 'sieben'
    print('dat={}'.format(dat))
以下是以下相关部分:

如果名称绑定操作发生在代码块内的任何位置,则块内名称的所有使用都将被视为对当前块的引用。在绑定块之前在块内使用名称时,这可能会导致错误。这条规则很微妙。Python缺少声明,并且允许名称绑定操作发生在代码块中的任何位置。代码块的局部变量可以通过扫描块的整个文本进行名称绑定操作来确定

如果
global
语句出现在一个块中,则该语句中指定的名称的所有用法都引用该名称在顶级命名空间中的绑定。通过搜索全局名称空间(即包含代码块的模块名称空间)和内置名称空间(模块
内置名称空间
),在顶级名称空间中解析名称。首先搜索全局名称空间。如果在那里找不到名称,则搜索内置名称空间。
global
语句必须位于名称的所有使用之前


编辑后,问题是:“如何变异不可变对象?”


嗯,我想你已经猜到了:你没有。以这种方式使用可变对象对我来说似乎是合理的。

语法与此无关
dat
是myhandler的本地变量,分配它不会更改同名的全局变量。如果要从函数内部更改模块变量,请在函数体开头将变量声明为
global

def myhandler(): # you don't need to pass dat as argument
    global dat
    print('dat={}'.format(dat))
    dat = 'sieben'
    print('dat={}'.format(dat))
以下是以下相关部分:

如果名称绑定操作发生在代码块内的任何位置,则块内名称的所有使用都将被视为对当前块的引用。在绑定块之前在块内使用名称时,这可能会导致错误。这条规则很微妙。Python缺少声明,并且允许名称绑定操作发生在代码块中的任何位置。代码块的局部变量可以通过扫描块的整个文本进行名称绑定操作来确定

如果
global
语句出现在一个块中,则该语句中指定的名称的所有用法都引用该名称在顶级命名空间中的绑定。通过搜索全局名称空间(即包含代码块的模块名称空间)和内置名称空间(模块
内置名称空间
),在顶级名称空间中解析名称。首先搜索全局名称空间。如果在那里找不到名称,则搜索内置名称空间。
global
语句必须位于名称的所有使用之前


编辑后,问题是:“如何变异不可变对象?”


嗯,我想你已经猜到了:你没有。以这种方式使用可变对象对我来说似乎是合理的。

请反对票的投票人对反对票发表评论。我愿意学习。这就是我问的原因。请落选的选民对落选做出评论。我愿意学习。这就是我问的原因。