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

14

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

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

我的问题如下:

  1. 如何在外部获取函数的本地变量(a,b),而不使用函数内部的locals()?(类似反射)
  2. 是否可以从外部设置一个本地变量(比如x),使得注释行起作用?(我知道听起来很奇怪)

提前感谢。

编辑:

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

  1. 我有一个包含Python函数的加密源代码文件。
  2. C扩展模块对其进行解密并在内存中构建该函数。
  3. 主Python程序首先使用该加密文件位置调用C扩展程序。
  4. 然后主程序调用已在内存中构建的函数(由C扩展程序构建)
  5. 但主程序需要知道该函数的本地变量(不要问我为什么,不是我)
  6. 由于某种(可恶)原因,主程序还需要设置一个变量(最奇怪的是)
5个回答

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

这是一个hack,因为没有办法知道co.co_consts中的哪个常量是哪个;这使用一个标记值来确定它。取决于您是否能够足够限制您的用例,这可能就足够了。


3
е°Ҹжӣҙж–°пјҢPython3дёӯзҡ„func_codeе·Із»Ҹжӣҙж–°дёә__code__гҖӮ - Jacqueline P.

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

这基于您的示例,因此代码并没有太多意义。如果您提供更多详细信息,我们可能能够提供更好的建议。


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和编程的初学者……

2

该函数的本地变量在每次运行函数时都会更改,因此在函数未运行时访问它们几乎没有意义。


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。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接