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

前端 未结 5 1353
误落风尘
误落风尘 2020-11-28 10:08

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:

相关标签:
5条回答
  • 2020-11-28 10:37

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

    0 讨论(0)
  • 2020-11-28 10:42

    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)

    0 讨论(0)
  • 2020-11-28 10:42

    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.

    0 讨论(0)
  • 2020-11-28 10:48

    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.

    0 讨论(0)
  • 2020-11-28 10:53

    The function's locals change whenever the function is run, so there's little meaning to access them while the function isn't running.

    0 讨论(0)
提交回复
热议问题