2011-01-21 101 views
7

说,外部范围,我有一些范围与变量,一个名为在此范围内的功能要改变一些不可改变的变量:访问在Python 2.6

 
def outer(): 
    s = 'qwerty' 
    n = 123 
    modify() 

def modify(): 
    s = 'abcd' 
    n = 456 

是否有可能以某种方式来访问外部范围?类似于Py3k中的nonlocal变量。

当然,在这种情况下,我可以做s,n = modify(s,n),但是如果我需要一些通用的“注入”,它在那里执行并且必须能够重新分配给任意变量呢?

我心目中的表现,因此,如果可能的话,eval &堆栈帧检查不欢迎:)


UPD:这是不可能的。期。但是,如何在外部范围访问变量还有一些选项:

  1. 使用全局变量。顺便说一句,func.__globals__是一个可变的字典;)在一个字典/类实例
  2. 存储变量/任何其他可变容器
  3. 给变量作为自变量&让他们回来为一个元组:a,b,c = innerfunc(a,b,c)
  4. 进样等功能的字节码。这可以通过byteplay python模块来实现。
+1

这不是如何范围的作品。您要求访问另一个堆栈中的作用域。如果范围设定允许你在这里尝试,那么将会非常令人困惑,将尾递归重写为循环。所以,代码优化突然会改变程序的意义,这永远不会发生。 – Tino 2011-10-30 23:01:41

回答

3

这是如何nonlocal作品。它不提供动态范围(这只是一个巨大的PITA等待发生,甚至比平均的“邪恶”功能更少有用)。它只是修复了词汇范围。

无论如何,你不能做你想到的(我会说这是一件好事)。甚至没有一个肮脏但容易的黑客攻击(虽然我们在这里:这样的黑客并不气馁,因为他们通常表现更差一些!)。只要把它忘掉,妥善解决真正的问题(你没有说出来,所以我们不能说这个)。

最接近你可以得到的是定义一些对象,它携带你想要共享的所有东西并明确地传递它(例如,创建一个类并使用self,正如另一个答案中所建议的那样)。但是到处都比较麻烦,并且仍然存在嘲弄(尽管比动态范围更好,因为“显式比隐式更好”)。

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

用`xor`替换`和`以使其工作。从头开始重新编写好的建议。 – delnan 2011-01-21 21:31:11

+0

@delnan,对不起,但??? – orlp 2011-01-21 21:32:38

+0

他的意思是“在外面定义它们,或者使用`global`,但不是两个”。 – gotgenes 2011-01-21 21:34:04

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 
7

有时我碰到这样的代码。嵌套函数修改可变对象,而不是分配给一个nonlocal

def outer(): 
    s = [4] 
    def inner(): 
     s[0] = 5 
    inner() 
1

您可以也可能做到这一点(不是说这是正确的);

定义返回与行,像这样

["a = qwerty","n = 123"] 

然后在范围做一个数组的函数,你需要的增值经销商

for row in array: 
    eval(row) 

这是相当不错的哈克虽然。