说,我有一些变量范围,并且在这个范围内调用的函数想要更改一些不可变变量:
def outer(): s = 'qwerty' n = 123 modify() def modify(): s = 'abcd' n = 456
是否有可能以某种方式访问外部范围?类似Py3k的nonlocal
变量。
当然,在这种情况下我可以做s,n = modify(s,n)
,但如果我需要一些在那里执行的通用“注入”并且必须能够重新分配给任意变量呢?
我考虑到了绩效,如果可能的话,eval
&不欢迎堆栈框架检查:)
UPD :这是不可能的。期。但是,如何访问外部作用域中的变量有一些选项:
func.__globals__
是一个可变的字典;)a,b,c = innerfunc(a,b,c)
byteplay
python模块实现。答案 0 :(得分:7)
定义函数之外的变量并使用global
关键字。
s, n = "", 0
def outer():
global n, s
n = 123
s = 'qwerty'
modify()
def modify():
global n, s
s = 'abcd'
n = 456
答案 1 :(得分:7)
有时候我会遇到像这样的代码。嵌套函数修改可变对象,而不是分配给nonlocal
:
def outer():
s = [4]
def inner():
s[0] = 5
inner()
答案 2 :(得分:3)
不 nonlocal
如何运作。它不提供动态范围(这只是一个巨大的PITA等待发生,甚至比普通的“邪恶”特征更有用)。它只是修复了词法范围。
无论如何,你不能做你想到的事情(我会说这是一件好事)。甚至没有一个肮脏但容易破解的黑客(当我们处于它的时候:这样的黑客不会气馁,因为它们通常表现得更差!)。忘记它并正确解决真正的问题(你没有说出来,所以我们不能就此发表任何意见)。
你可以得到的最接近的是定义一个对象,它包含你想要分享的所有内容并明确地传递它(例如,如另一个答案所示,创建一个类并使用self
)。但到处都是相对麻烦,而且仍然是hackery(虽然比动态范围更好,因为“显式优于隐式”)。
答案 3 :(得分:3)
您的选择是使用global变量,
s = None
n = None
def outer(self):
global s
global n
s = 'qwerty'
n = 123
modify()
def modify(self):
global s
global n
s = 'abcd'
n = 456
或将它们定义为方法并使用类或实例变量。
class Foo(object):
def __init__(self):
self.s = None
self.n = None
def outer(self):
self.s = 'qwerty'
self.n = 123
self.modify()
def modify(self):
self.s = 'abcd'
self.n = 456
答案 4 :(得分:1)
你也可以这样做(不是说它是对的);
定义一个返回数组的函数,其中包含类似
的行["a = qwerty","n = 123"]
然后在你需要vars的范围内做
for row in array:
eval(row)
但是,这非常讨厌。
答案 5 :(得分:0)
def a():
i = 1
def b():
# i = 2
def c():
nonlocal i
i = 3
c()
print('b:', i)
b()
print('a:', i)
a()
nonlocal
将在较高级别的范围内进行搜索,如果未找到则向上移
> python3 t.py
b: 3
a: 1
评论i = 2
> python3 t.py
b: 3
a: 3