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

How to get/set local variables of a function (from outside) in Python?

如果我有一个函数(在Python2.5.2中),比如:

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

我的问题是:

  • 如何从外部获取函数的局部变量(a,b),而不在函数内部使用locals()?(某种反射)
  • 是否可以从外部设置局部变量(比如x),以便注释行工作?(我知道这听起来很奇怪)。
  • 事先谢谢。

    编辑:

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

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

  • 不,没有运行的函数没有局部变量,它只是一个函数。询问如何在函数不运行时修改其局部变量,就像询问如何在程序不运行时修改其堆一样。

    不过,如果您真的想修改常量的话,也可以修改常量。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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中的常数是哪个;这使用一个sentinel值来计算它。取决于您是否能够足够地约束您的用例,这可能就足够了。


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

    例如。:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >>> 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

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


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

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

    1
    2
    3
    4
    5
    6
    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。


    不确定这是否是您的意思,但是由于函数是Python中的对象,您可以将变量绑定到函数对象,并从"外部"访问它们:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    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和编程初学者…


    每当函数运行时,函数的局部变量都会发生变化,因此在函数不运行时访问这些局部变量几乎没有意义。