如何在 Python 中获取/设置函数的局部变量(从外部)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1360721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get/set local variables of a function (from outside) in Python?
提问by mshsayem
If I have a function (in Python 2.5.2) like:
如果我有一个函数(在 Python 2.5.2 中),例如:
def sample_func():
a = 78
b = range(5)
#c = a + b[2] - x
My questions are:
我的问题是:
- How to get the local variables (a,b) of the function from outside withoutusing locals()inside the function? (kind of reflection)
- Is it possible to set a local variable (say x) from outside so that the commented line works? (I know it sounds weird).
- 如何在不使用函数内部的locals() 的情况下从外部获取函数的局部变量 (a,b) ?(一种反思)
- 是否可以从外部设置一个局部变量(比如x)以便注释行起作用?(我知道这听起来很奇怪)。
Thanks in advance.
提前致谢。
EDIT:
编辑:
Everyone is asking for a use-case. But it is a weird situation. (Don't blame me, I did not create it). Here is the scenario:
每个人都在要求一个用例。但这是一个奇怪的情况。(不要怪我,我没有创造它)。这是场景:
- I have an encrypted python source file containing a python function.
- A C extension module decrypts it and builds that function in-memory.
- A main python program first calls the C extension with that encrypted file location.
- Then the main program calls the function that has been built in-memory (by the C extension)
- But main program needs to know the local variables of that function (Dont ask me why, it was not me)
- For some (damn) reason, main program needs to set a variable too (weirdest of all)
- 我有一个包含 python 函数的加密 python 源文件。
- AC 扩展模块对其进行解密并在内存中构建该函数。
- 一个主要的 python 程序首先调用带有加密文件位置的 C 扩展。
- 然后主程序调用已经内置在内存中的函数(通过C扩展)
- 但是主程序需要知道那个函数的局部变量(别问我为什么,不是我)
- 由于某些(该死的)原因,主程序也需要设置一个变量(最奇怪的)
回答by Glenn Maynard
No. A function that isn't being run doesn't have locals; it's just a function. Asking how to modify a function's locals when it's not running is like asking how to modify a program's heap when it's not running.
不。没有运行的函数没有局部变量;这只是一个函数。在函数未运行时询问如何修改函数的局部变量就像在程序未运行时询问如何修改程序的堆。
You can modify constants, though, if you really want to.
但是,如果您真的愿意,您可以修改常量。
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()
It's a hack, because there's no way to know which constant in co.co_consts is which; this uses a sentinel value to figure it out. Depending on whether you can constrain your use cases enough, that might be enough.
这是一个黑客,因为没有办法知道 co.co_consts 中的哪个常量是哪个;这使用一个哨兵值来解决它。取决于您是否可以充分限制您的用例,这可能就足够了。
回答by John Fouhy
I'm not sure what your use-case is, but this may work better as a class. You can define the __call__
method to make a class behave like a function.
我不确定您的用例是什么,但这作为一个类可能会更好。您可以定义该__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
(this is based on your toy example, so the code doesn't make much sense. If you give more details, we may be able to provide better advice)
(这是基于您的玩具示例,因此代码没有多大意义。如果您提供更多详细信息,我们可能会提供更好的建议)
回答by orip
The function's locals change whenever the function is run, so there's little meaning to access them while the function isn't running.
每当函数运行时,函数的局部变量就会发生变化,因此在函数未运行时访问它们几乎没有意义。
回答by Titusz
Not sure if this is what you mean, but as functions are objects in Python you can bind variables to a function object and access them from 'outside':
不确定这是否是您的意思,但由于函数是 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()
Please excuse me if I am terribly wrong... I′m a Python and programming beginner myself...
如果我错了,请原谅......我自己是Python和编程初学者......
回答by hevans66
Expecting a variable in a function to be set by an outside function BEFORE that function is called is such bad design that the only real answer I can recommend is changing the design. A function that expects its internal variables to be set before it is run is useless.
期望函数中的变量在调用该函数之前由外部函数设置是非常糟糕的设计,我可以推荐的唯一真正的答案是更改设计。期望在运行之前设置其内部变量的函数是无用的。
So the real question you have to ask is why does that function expect x to be defined outside the function? Does the original program that function use to belong to set a global variable that function would have had access to? If so, then it might be as easy as suggesting to the original authors of that function that they instead allow x to be passed in as an argument. A simple change in your sample function would make the code work in both situations:
所以你要问的真正问题是为什么该函数期望 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
This will allow the function to accept a parameter from your main function the way you want to use it, but it will not break the other program as it will still use the globally defined x if the function is not given any arguments.
这将允许函数以您想要使用的方式接受来自主函数的参数,但它不会破坏其他程序,因为如果函数没有给出任何参数,它仍将使用全局定义的 x。