Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the values of the locals of a function after it has been executed?

Tags:

python

Suppose I have a function like f(a, b, c=None). The aim is to call the function like f(*args, **kwargs), and then construct a new set of args and kwargs such that:

  1. If the function had default values, I should be able to acquire their values. For example, if I call it like f(1, 2), I should be able to get the tuple (1, 2, None) and/or the dictionary {'c': None}.
  2. If the value of any of the arguments was modified inside the function, get the new value. For example, if I call it like f(1, 100000, 3) and the function does if b > 500: b = 5 modifying the local variable, I should be able to get the the tuple (1, 5, 3).

The aim here is to create a a decorator that finishes the job of a function. The original function acts as a preamble setting up the data for the actual execution, and the decorator finishes the job.

Edit: I'm adding an example of what I'm trying to do. It's a module for making proxies for other classes.


class Spam(object):
    """A fictional class that we'll make a proxy for"""
    def eggs(self, start, stop, step):
        """A fictional method"""
        return range(start, stop, step)

class ProxyForSpam(clsproxy.Proxy): proxy_for = Spam @clsproxy.signature_preamble def eggs(self, start, stop, step=1): start = max(0, start) stop = min(100, stop)

And then, we'll have that:

ProxyForSpam().eggs(-10, 200) -> Spam().eggs(0, 100, 1)

ProxyForSpam().eggs(3, 4) -> Spam().eggs(3, 4, 1)

like image 610
Rosh Oxymoron Avatar asked Nov 18 '10 12:11

Rosh Oxymoron


People also ask

What happens to a function's local variables after it completes it execution?

When the execution of the function terminates (returns), the local variables are destroyed. Codelens helps you visualize this because the local variables disappear after the function returns.

What is locals () in Python?

Python locals() Function The locals() function returns the local symbol table as a dictionary. A symbol table contains necessary information about the current program.

How do you return multiple values from a function in Python?

In Python, you can return multiple values by simply return them separated by commas. In Python, comma-separated values are considered tuples without parentheses, except where required by syntax. For this reason, the function in the above example returns a tuple with each value as an element.

How do you take the value out of a function in Python?

The return statement in Python is used to return some value from a function in Python. Since we cannot access the variable defined within the function from the outside, we can return it using the return statement to get variable from function in Python. We can also return multiple variables.


1 Answers

I've stumbled upon this very need today and wanted to share my solution.

import sys

def call_function_get_frame(func, *args, **kwargs):
  """
  Calls the function *func* with the specified arguments and keyword
  arguments and snatches its local frame before it actually executes.
  """

  frame = None
  trace = sys.gettrace()
  def snatch_locals(_frame, name, arg):
    nonlocal frame
    if frame is None and name == 'call':
      frame = _frame
      sys.settrace(trace)
    return trace
  sys.settrace(snatch_locals)
  try:
    result = func(*args, **kwargs)
  finally:
    sys.settrace(trace)
  return frame, result

The idea is to use sys.trace() to catch the frame of the next 'call'. Tested on CPython 3.6.

Example usage

import types

def namespace_decorator(func):
  frame, result = call_function_get_frame(func)
  try:
    module = types.ModuleType(func.__name__)
    module.__dict__.update(frame.f_locals)
    return module
  finally:
    del frame

@namespace_decorator
def mynamespace():
  eggs = 'spam'
  class Bar:
    def hello(self):
      print("Hello, World!")

assert mynamespace.eggs == 'spam'
mynamespace.Bar().hello()
like image 107
Niklas R Avatar answered Oct 28 '22 08:10

Niklas R