If I have a function (in Python 2.5.2) like:
def sample_func():
a = 78
b = range(5)
#c = a + b[2] - x
My questions are:
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':
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...
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.
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)
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:
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.
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.
The function's locals change whenever the function is run, so there's little meaning to access them while the function isn't running.