Get locals from calling namespace in Python - python

I want to retrieve the local variables from Python from a called function. Is there any way to do this? I realize this isn't right for most programming, but I am basically building a debugger. For example:
def show_locals():
# put something in here that shows local_1.
local_1 = 123
show_locals() # I want this to show local_1.
What do I put in the body of show_locals? If I have to modify the calling statement, what is the minimal modification I can make?
Note: this must work when show_locals is in a different module to its caller.

If you're writing a debugger, you'll want to make heavy use of the inspect module:
def show_callers_locals():
"""Print the local variables in the caller's frame."""
import inspect
frame = inspect.currentframe()
try:
print(frame.f_back.f_locals)
finally:
del frame

Perhaps it is worth pointing out that the technique from the accepted answer that reads from the caller's stack frame:
import inspect
def read_from_caller(varname):
frame = inspect.currentframe().f_back
try:
v = frame.f_locals[varname]
return v
finally:
del frame
can also write into the caller's namespace:
import inspect
def write_in_caller(varname, v):
frame = inspect.currentframe().f_back
try:
frame.f_locals[varname] = v
finally:
del frame
If you put that in a module called "access_caller", then
import access_caller
access_caller.write_in_caller('y', x)
is an elaborate way of writing
y = x
(I am writing this as a fresh answer because I don't have enough reputation points to write a comment.)

You use the python builtin, dir() or vars():
vars(object)
For examples using dir(), see: this post
Examples using vars:
>>> class X:
... a=1
... def __init__(self):
... b=2
...
>>>
>>> vars(X)
{'a': 1, '__module__': '__main__', '__doc__': None, '__init__': <function __init__ at 0x100488848>}
>>>
>>> vars(X())
{}
A potentially problematic fact: New style classes not return the same result
>>> class X(object):
... a=1
... def __init__(self):
... b=2
...
>>>
>>> vars(X)
<dictproxy object at 0x1004a1910>
>>> vars(X())
{}
Also: for an instantiated class (new and old style), if you add a variable after instantiating, vars will return the object's dict like this:
>>> x = X()
>>> x.c = 1
>>> vars(x)
{'c': 1}
>>>
See: http://docs.python.org/library/functions.html#vars

Related

Can a function in python behave like a class?

In python a function is a first class object. A class can be called. So you can replace a function with a class. But can you make a function behave like a class? Can you add and remove attributes or call inner functions( then called methods) in a function?
I found a way to do this via code inspection.
import inspect
class AddOne(object):
"""class definition"""
def __init__(self, num):
self.num = num
def getResult(self):
"""
class method
"""
def addOneFunc(num):
"inner function"
return num + 1
return addOneFunc(self.num);
if __name__ == '__main__':
two = AddOne(1);
two_src = '\n'.join([line[4:] for line in inspect.getsource(AddOne.getResult).split('\n')])
one_src = '\n'.join([line[4:] for line in two_src.split('\n')
if line[:4] == ' ' and line[4:8] == ' ' or line[4:8] == 'def '])
one_co = compile(one_src, '<string>', 'exec')
exec one_co
print addOneFunc(5)
print addOneFunc.__doc__
But is there a way to access the local variables and functions defined in a class in a more direct way?
EDIT
The question is about how to access the inner structure of python to get a better understanding. Of course I wouldn't do this in normal programming. The question arose when we had a discussion about private variables in python. My opinion was this to be against the philosophy of the language. So someone came up with the example above. At the moment it seems he is right. You cannot access the function inside a function without the inspect module, rendering this function private. With co_varnames we are awfully close because we already have the name of the function. But where is the namespace dictionary to hold the name. If you try to use
getResult.__dict__
it is empty. What I like to have is an answer from python like
function addOneFunc at <0xXXXXXXXXX>
You can consider a function to be an instance of a class that only implements __call__, i.e.
def foo(bar):
return bar
is roughly equivalent to
class Foo(object):
def __call__(self, bar):
return bar
foo = Foo()
Function instances have a __dict__ attribute, so you can freely add new attributes to them.
Adding an attribute to a function can be used, for example, to implement a memoization decorator, which caches previous calls to a function:
def memo(f):
#functools.wraps(f)
def func(*args):
if args not in func.cache: # access attribute
func.cache[args] = f(*args)
return func.cache[args]
func.cache = {} # add attribute
return func
Note that this attribute can also be accessed inside the function, although it can't be defined until after the function.
You could therefore do something like:
>>> def foo(baz):
def multiply(x, n):
return x * n
return multiply(foo.bar(baz), foo.n)
>>> def bar(baz):
return baz
>>> foo.bar = bar
>>> foo.n = 2
>>> foo('baz')
'bazbaz'
>>> foo.bar = len
>>> foo('baz')
6
(although it's possible that nobody would thank you for it!)
Note, however, that multiply, which was not made an attribute of foo, is not accessible from outside the function:
>>> foo.multiply(1, 2)
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
foo.multiply(1, 2)
AttributeError: 'function' object has no attribute 'multiply'
The other question addresses exactly what you're trying to do:
>>> import inspect
>>> import new
>>> class AddOne(object):
"""Class definition."""
def __init__(self, num):
self.num = num
def getResult(self):
"""Class method."""
def addOneFunc(num):
"inner function"
return num + 1
return addOneFunc(self.num)
>>> two = AddOne(1)
>>> for c in two.getResult.func_code.co_consts:
if inspect.iscode(c):
print new.function(c, globals())
<function addOneFunc at 0x0321E930>
Not sure if the following is what you're thinking about, but you can do this:
>>> def f(x):
... print(x)
...
>>> f.a = 1
>>> f.a
1
>>> f(54)
54
>>> f.a = f
>>> f
<function f at 0x7fb03579b320>
>>> f.a
<function f at 0x7fb03579b320>
>>> f.a(2)
2
So you can assign attributes to a function, and those attributes can be variables or functions (note that f.a = f was chosen for simplicity; you can assign f.a to any function of course).
If you want to access the local variables inside the function, I think then it's more difficult, and you may indeed need to revert to introspection. The example below uses the func_code attribute:
>>> def f(x):
... a = 1
... return x * a
...
>>> f.func_code.co_nlocals
2
>>> f.func_code.co_varnames
('x', 'a')
>>> f.func_code.co_consts
(None, 1)

How to pass a dict to a python thread that can be changed from outside of thread without using queue

I would like to have a shared dict between my threads without using Queue. I did it before by making thread with an object in python but now I want to make thread with just one function of object not all of it. my simplified code is as follow:
#!/usr/bin/python
import threading
import time
class WebSocket(threading.Thread):
def __init__(self, server=1, sock=1, address=1):
self.s1=server
self.s2=sock
self.s3=address
print "salam"
def CheckThread(self):
self.a={'1':1, '2':2}
s=threading.Thread(target=self.SockFun, kwargs=self.a)
s.deamon=True
s.start()
while(1):
self.a['1']=self.a['1']+1
time.sleep(1)
def SockFun(self,**kwargs):
pass
class SimpleEcho(WebSocket):
def SockFun(self,**kwargs):
while(1):
print kwargs
time.sleep(1)
def handleMessage(self):
self.CheckThread()
s=SimpleEcho()
s.handleMessage()
my printed dict element '1' of kwargs does not increase as expected inside thread:
It's not a threading issue. self.a dictionary is not passed through via reference when you pass it in via kwargs, it gets copied in.
>>> mydict = {'foo': 'bar'}
>>> def func(**kwargs):
... kwargs['hi'] = 'mom'
...
>>> func(**mydict)
>>> print mydict
{'foo': 'bar'}
Using the kwargs mechanism causes the dict elements to be copied into SimpleEcho. After they are there, changing the original doesn't make a difference to what is printed. A quick way to see this is to change print kwargs to print self.a.
Alternatively you can change kwargs=self.a to kwargs={"argh":self.a}. This way, kwargs will still be copied, but that copy will contain a reference to the original self.a.
And shouldn't you be using some kind of locking?
The dictionnary is copied when you use the ** syntax, this is why you cannot do that.
>>> foo = {'bar': 'baz'}
>>> def spam(**kwargs):
... print(kwargs is foo)
...
>>> spam(**foo)
False
You would have to use a mutable type, like a list, as an item of the dictionnary (you can do that because the copy is a shallow copy: it copies only the dictionnary and not its content).
>>> import time
>>> import threading
>>> def spam(**kwargs):
... while True:
... time.sleep(10)
... print(kwargs['bar'][0])
...
>>> foo = {'bar': ['baz']}
>>> threading.Thread(target=spam, kwargs=foo).start()
>>> baz
>>> foo['bar'][0] = 'qux'
>>> qux
qux
qux

Finding All Defined Functions in Python Environment

Is there a method to find all functions that were defined in a python environment?
For instance, if I had
def test:
pass
some_command_here would return test
You can use inspect module:
import inspect
import sys
def test():
pass
functions = [name for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isfunction)]
print functions
prints:
['test']
You can use globals() to grab everything defined in the global scope of the file, and inspect to filter the objects you care about.
[ f for f in globals().values() if inspect.isfunction(f) ]
Use globals() and types.FunctionType
>>> from types import FunctionType
>>> functions = [x for x in globals().values() if isinstance( x, FunctionType)]
Demo:
from types import FunctionType
def func():pass
print [x for x in globals().values() if isinstance(x, FunctionType)]
#[<function func at 0xb74d795c>]
#to return just name
print [x for x in globals().keys() if isinstance(globals()[x], FunctionType)]
#['func']
>>> def test():
... pass
...
>>> [k for k, v in globals().items() if callable(v)]
['test']
First, we will create the test function we want to find.
def test():
pass
Next, we will create the some_command_here function that you want.
def some_command_here():
return filter(callable, globals().values())
Finally, we call the new function and convert the filter into a tuple for viewing.
tuple(some_command_here())
Note: This searches the current global namespace and returns anything callable (not just functions).
Example:
>>> def test():
pass
>>> def some_command_here():
return filter(callable, globals().values())
>>> tuple(some_command_here())
(<function test at 0x02F78660>,
<class '_frozen_importlib.BuiltinImporter'>,
<function some_command_here at 0x02FAFDF8>)
>>>

How to access a decorated method local variables ( locals() ) from inside a Python decorator?

Here's what I need:
Let's say I have this decorator:
def deco(func):
def decoret(*args, **kwargs):
print(func.__locals__) # I know __locals__ is not valid, but I need something like this
return decoret
#deco
def func():
test1 = 123
test2 = 456
func()
I want to fetch a list of all local variables (as if I was calling locals() inside the function), so I would be able to access a dictionary with test1 and test2 values inside the decorator's decoret function.
I know I can do this by using Python inspect module, but I wasn't able to trace the right frame to get the function.
Also, I'm using Python 3.2 CPython.
There are no locals in a function until it's executed. The only things available to you when it's decorated are what is there when it's defined.
d = 'd'
def a(d=d):
b = 'b'
c = 'c'
print a.__dict__
# {}
print a.b
# AttributeError: 'function' object has no attribute 'b'
print dir(a)
# Doesn't print anything
Actually, I found a way to circumvent and implement this using a trace from sys.
Take a look a this snippet:
def Property(function):
keys = 'fget', 'fset', 'fdel'
func_locals = {'doc':function.__doc__}
def probeFunc(frame, event, arg):
if event == 'return':
locals = frame.f_locals
func_locals.update(dict((k,locals.get(k)) for k in keys))
sys.settrace(None)
return probeFunc
sys.settrace(probeFunc)
function()
return property(**func_locals)
Took this from a snippet of code located at http://code.activestate.com/recipes/410698/
Also, take a look on this stackoverflow topic: Python: static variable decorator

Python: check if object exists in scope [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Python - checking variable existing
Is there an efficient, simple and pythonic way to check if an object exists in the scope?
In Python everything's an object (variables, functions, classes, class instances etc), so I'm looking for a generic existence test for an object, no matter what it is.
I half expected there to be an exists() built-in function, but I couldn't find any to fit the bill.
you could always:
try:
some_object
except NameError:
do_something()
else:
do_something_else()
You seem to be searching for hasattr(). You use it to see if, in the scope of the namespace of an object (and even imported modules are objects), a given attribute name exists.
So, I can do:
>>> import math
>>> hasattr(math, 'atan')
True
or something like:
>>> class MyClass(object):
... def __init__(self):
... self.hello = None
...
>>> myObj = MyClass()
>>> hasattr(myObj, 'hello')
True
>>> hasattr(myObj, 'goodbye')
False
I believe you're looking for something like locals. Here's how it works:
>>> foo = 1
>>> l = locals()
>>> print l
{'__builtins__': <module '__builtin__' (built-in)>, 'l': {...},
'__package__': None,'__name__':'__main__', 'foo': 1, '__doc__': None}
>>> print l['foo']
1
There will be a difference whether you are trying to determine if a local or a attribute of an object exists. For an object, hasattr(object, "attribute") will do the trick.
This also work on modules:
import math
hasattr(math,"pow") => True
But for what we can call the main scope, you will have to use locals(), as hasattr() need some sort of object to dig into. In this case there is none...
exists_mainscope = lambda name: locals().has_key(name)
exists_mainscope("test") => False
So, what you are looking for might be the following:
def exists(name,obj=None):
if obj is None: return locals().has_key(name)
else: return hasattr(obj,name)
enter code here
It's possible to write your own:
import __builtin__
import sys
def exists(name):
return (name in sys._getframe(1).f_locals # caller's locals
or name in sys._getframe(1).f_globals # caller's globals
or name in vars(__builtin__) # built-in
)
if __name__=='__main__':
def foobar():
local_var = 42
print 'exists("global_var"):', exists("global_var")
print 'exists("local_var"):', exists("local_var")
print 'exists("baz"):', exists("baz") # undefined
print 'exists("dict"):', exists("dict") # built-in
foobar() # global_var doesn't exist yet
global_var = 'I think, therefore I am'
print 'exists("global_var"):', exists("global_var")
foobar() # now global_var exists

Categories