如何在Python中获取/设置函数的局部变量(从外部)?
如果我有一个这样的函数(在Python 2.5.2中):
def sample_func():
a = 78
b = range(5)
#c = a + b[2] - x
我的问题是:
- 如何在外部获取这个函数的局部变量(a, b),而不使用函数内部的locals()?(有点像反射)
- 有没有办法从外部设置一个局部变量(比如x
提前谢谢大家。
编辑:
大家都在问用例,但这是个奇怪的情况。(别怪我,我不是创造这个的)。以下是场景:
- 我有一个加密的Python源文件,里面包含一个Python函数。
- 一个C扩展模块解密这个文件,并在内存中构建那个函数。
- 一个主Python程序首先调用C扩展,传入那个加密文件的位置。
- 然后主程序调用在内存中构建的函数(由C扩展构建)
- 但是主程序需要知道那个函数的局部变量(别问我为什么,这不是我做的)
- 出于某种(真是)奇怪的原因,主程序还需要设置一个变量(这是最奇怪的)。
5 个回答
3
我不太确定这是不是你想要的意思,但在Python中,函数也是一种对象,你可以把变量绑定到一个函数对象上,然后从“外部”访问这些变量:
def fa():
print 'x value of fa() when entering fa(): %s' % fa.x
print 'y value of fb() when entering fa(): %s' % fb.y
fa.x += fb.y
print 'x value of fa() after calculation in fa(): %s' % fa.x
print 'y value of fb() after calculation in fa(): %s' % fb.y
fa.count +=1
def fb():
print 'y value of fb() when entering fb(): %s' % fb.y
print 'x value of fa() when entering fa(): %s' % fa.x
fb.y += fa.x
print 'y value of fb() after calculation in fb(): %s' % fb.y
print 'x value of fa() after calculation in fb(): %s' % fa.x
print 'From fb() is see fa() has been called %s times' % fa.count
fa.x,fb.y,fa.count = 1,1,1
for i in range(10):
fa()
fb()
如果我说错了,请多多包涵……我自己也是Python和编程的初学者……
9
我不太清楚你具体想做什么,但把它做成一个类可能会更好。你可以定义一个叫做 __call__
的方法,这样这个类就可以像函数一样使用。
比如:
>>> class sample_func(object):
... def __init__(self):
... self.a = 78
... self.b = range(5)
... def __call__(self):
... print self.a, self.b, self.x
...
>>> f = sample_func()
>>> print f.a
78
>>> f.x = 3
>>> f()
78 [0, 1, 2, 3, 4] 3
(这个例子是基于你给的简单示例,所以代码可能不是很有意义。如果你能提供更多细节,我们可能能给出更好的建议。)
19
不可以。一个没有被执行的函数是没有局部变量的,它只是一个函数。问如何修改一个没有运行的函数的局部变量,就像问如何在程序没有运行时修改它的堆内存一样。
不过,如果你真的想的话,可以修改常量。
def func():
a = 10
print a
co = func.func_code
modified_consts = list(co.co_consts)
for idx, val in enumerate(modified_consts):
if modified_consts[idx] == 10: modified_consts[idx] = 15
modified_consts = tuple(modified_consts)
import types
modified_code = types.CodeType(co.co_argcount, co.co_nlocals, co.co_stacksize, co.co_flags, co.co_code, modified_consts, co.co_names, co.co_varnames, co.co_filename, co.co_name, co.co_firstlineno, co.co_lnotab)
modified_func = types.FunctionType(modified_code, func.func_globals)
# 15:
modified_func()
这是一种技巧,因为我们无法知道co.co_consts中的每个常量具体是什么;这个方法使用了一个特殊值来帮助识别。根据你的使用情况是否足够限制,这种方法可能就足够了。