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

时间:2016-01-31 10:50:50

标签: python-3.x immutability

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

下面的代码是原始代码的极端简化示例。但它重现了这个问题非常好。 while(p) { cout << p; p = strtok(NULL, " "); } test()的来电应为foo

我想我不知道Python中变量范围的一些特殊内容。这可能是一个非常好的问题,以了解更多相关信息。但我不知道我应该关注哪个Python主题来为我自己找到解决方案。

sieben

当然,我可以将#!/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作为保存不可变对象的可变对象。但这真的是优雅 pythonic 吗?

list()

1 个答案:

答案 0 :(得分:2)

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

def myhandler(): # you don't need to pass dat as argument
    global dat
    print('dat={}'.format(dat))
    dat = 'sieben'
    print('dat={}'.format(dat))

以下是the docs的相关部分:

  

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

     

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

编辑后,问题内容如下:“我如何改变不可变对象?”

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