如何在Python中获取/设置函数的局部变量(从外部)?

时间:2009-09-01 05:50:42

标签: python

如果我有一个函数(在Python 2.5.2中),如:

def sample_func():
    a = 78
    b = range(5)
    #c = a + b[2] - x

我的问题是:

  1. 如何在函数内使用 locals()外部获取函数的局部变量(a,b)? (反思的种类)
  2. 是否可以从外部设置局部变量(例如 x ),以便注释行有效? (我知道这听起来很奇怪)。
  3. 提前致谢。

    修改

    每个人都在要求用例。但这是一个奇怪的情况。 (别怪我,我没有创造它)。这是场景:

    1. 我有一个包含python函数的加密python源文件。
    2. C扩展模块对其进行解密并在内存中构建该函数。
    3. 主要python程序首先使用该加密文件位置调用C扩展名。
    4. 然后主程序调用已在内存中构建的函数(通过C扩展名)
    5. 但主程序需要知道该函数的局部变量(不要问我原因,不是我)
    6. 对于某些(该死的)原因,主程序也需要设置一个变量(最奇怪的是)

5 个答案:

答案 0 :(得分:15)

没有。未运行的函数没有本地函数;它只是一个功能。询问如何在函数未运行时修改函数的本地函数,就像在不运行时询问如何修改程序的堆。

但是,如果你真的想要,你可以修改常量。

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中哪个常量是哪个;这使用了一个标记值来计算出来。根据您是否可以充分约束您的用例,这可能就足够了。

答案 1 :(得分:8)

我不确定你的用例是什么,但这可能会更好地作为一个班级。您可以定义__call__方法,使类的行为类似于函数。

e.g:

>>> 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

(这是基于您的玩具示例,因此代码没有多大意义。如果您提供更多详细信息,我们可能会提供更好的建议)

答案 2 :(得分:1)

函数运行时函数的局部变化,因此在函数未运行时访问函数的意义不大。

答案 3 :(得分:1)

不确定这是不是您的意思,但由于函数是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和编程初学者......

答案 4 :(得分:1)

期望函数中的变量由外部函数设置在调用该函数之前是如此糟糕的设计,我可以推荐的唯一真正的答案是改变设计。期望在运行之前设置其内部变量的函数是无用的。

所以你要问的真正问题是为什么这个函数期望x被定义在函数之外?函数使用的原始程序是否设置了一个函数可以访问的全局变量?如果是这样,那么它可能就像向该函数的原始作者建议他们改为允许x作为参数传递一样容易。样本函数的简单更改将使代码在两种情况下都起作用:

def sample_func(x_local=None):
  if not x_local:
    x_local = x
  a = 78
  b = range(5)
  c = a + b[2] - x_local

这将允许函数以您希望的方式接受主函数中的参数,但它不会破坏其他程序,因为如果函数没有给出任何参数,它仍将使用全局定义的x。