Automatically print the next line variable for debugging purpose - python

When you are debugging complex code, you sometimes need to transform:
def myfunction(self):
...
self.foo.bar = self.baz.bla
into
def myfunction(self):
...
self.foo.bar = self.baz.bla
print("myfunction", "self.foo.bar", self.foo.bar) # add this for debugging purposes
Is there a way (with a decorator or context manager or anything else) to automatically print the variable name and the value of the next line of code's assignement (and maybe also the current function)?
Example:
def myfunction(self):
...
with debug:
self.foo.bar = self.baz.bla
would output:
"myfunction self.foo.bar 123"

You can use the inspect module:
from inspect import currentframe
def f():
a = 5
debug_print("a")
def debug_print(var):
locals = currentframe().f_back.f_locals
print(f"{var} = {locals[var]}")
f()
See also here: Access parent namespace in python
I admit, it's only part of what you asked, but maybe a good start.
Edit: Ok what about this:
from inspect import currentframe, getsourcelines
class A:
def f(self):
self.b = 5
debug_print()
self.a = A()
self.a.a = 4
debug_print()
#staticmethod
def g():
A.c = 5
debug_print()
def debug_print():
frame = currentframe().f_back
locals = frame.f_locals
globals = frame.f_globals
source, start = getsourcelines(currentframe().f_back.f_code)
var_name = source[frame.f_lineno - 1 - start].split("=")[0]
tokens = var_name.strip().split(".")
var = locals.get(tokens[0], globals.get(tokens[0], None))
for t in tokens[1:]:
var = getattr(var, t)
print(f"{var_name} = {var}")
a = A()
a.f()
a.g()
At least now, it works with member attributes (including self), even nested. Also assignment of global variables, such as static attributes to the class.

Related

python access self in dll callback function in class

i have a dll function of some api like this:
def dllcallback(items):
pass
i want to access self in class functions linked with dll callback.
class myobject(object):
def __init__(self):
self.a = 999
#dllcallback
def mycallback(self, items):
print (self.a)
self.a = 888
print (self.a)
i don't think dllcallback accepts self as argument. so this was fail.
i wish myobject.mycallback will trigger when dllcallback is called by api, and shows:
999
888
and i tried the below to make 'self' be accessible by inner functions, but this approach killed the Kernel...
class myobject(object):
def __init__(self):
self.a = 999
def callbacks(self):
#dllcallback
def mycallback(items):
print (self.a)
self.a = 888
print (self.a)
i am not sure the reason why the kernel died. thanks in advance for any suggestion.
UPDATED: 20180912 1436
Actually, the override method could be called without self as argument,
class myobject(object):
def __init__(self):
self.a = 999
#dllcallback
def mycallback(items):
global self
print (self.a)
self.a = 888
print (self.a)
NameError: name 'self' is not defined
I suppose 'self' cannot be obtained like this...any suggestions?
UPDATED: 20180913 1645
Got some progress in writing a class including ctypes dll callback functions
class myobject(object):
def __init__(self):
if u'32bit' in architecture(): # 32bit WinOS
self.spdll = windll.LoadLibrary('XXX.dll')
else: # 64bit WinOS
self.spdll = cdll.LoadLibrary('XXX.dll')
self.a = 999
def callbacksinit(self):
def mycallback(items):
print (self.a)
self.a = 888
print (self.a)
self.mycallbackaddr = WINFUNCTYPE(None, c_char_p)
def regcallbacks(self):
self.spdll.APICALLBACK(self.mycallbackaddr)
With this code, i can access self.a when mycallback is triggered by API.
And fortunately for me, self.a can be changed to 888 after mycallback is done without global declaration (e.g. global self) in mycallback.
I have no idea why this happens...why WINFUNCTYPE(None, c_char_p) works in this way and why self.a can be changed without global declaration. I leave this question open a while and maybe someone can clear my doubts.
Your update is a valid solution. You can update self because it is mutable. You don't need a global (or in this case, nonlocal) declaration to access it. You only need those to reassign the variable.
For example:
def func():
L = []
def inner():
#nonlocal L # Uncomment to work
L = [1,2,3] # Reassign L
inner() # Call the function and attempt to modify L
return L
def func2():
L = []
def inner():
L[:] = [1,2,3] # Mutate L
inner() # Call the function and attempt to modify L
return L
print(func())
print(func2())
Output:
[]
[1, 2, 3]
Here's a full working example of your approach...
test.c
#include <wchar.h>
#define API __declspec(dllexport)
typedef void (*CALLBACK)(const wchar_t*);
API void do_callback(CALLBACK cb)
{
cb(L"one");
cb(L"two");
cb(L"three");
}
test.py
from ctypes import *
CALLBACK = CFUNCTYPE(None,c_wchar_p)
class Test:
dll = CDLL('test')
dll.do_callback.argtypes = CALLBACK,
dll.do_callback.restype = None
def __init__(self):
self.count = 0
def get_callback(self):
#CALLBACK
def callback(s):
self.count += 1 # nonlocal, but mutable
print(self.count,s)
return callback
def do(self):
self.dll.do_callback(self.get_callback())
t = Test()
t.do()
Output:
1 one
2 two
3 three
Python has a magic way to find the method+instance in a callback. But when you're interfacing with another language, that's another story.
Not sure if you can do better than:
registering your object in a global (well, class-instance) dictionary
create a callback wrapping function that finds the id (that your caller has to know) and calls the method with the proper context
You can keep all static objects inside the class scope for a cleaner solution.
like this:
class myobject(object):
globdict = {}
id = 0
def __init__(self):
self.a = 999
self.id += 1 # this id will have to be passed to the foreign library
myobject.globdict[self.id] = self
def mycallback(self, items):
print (self.a)
#staticmethod
def real_callback(id,items):
# first parameter is the object, then the "items" argument
# using function-call style (not object)
# id may need to be converted back from `ctypes`
myobject.mycallback(myobject.globdict[id],items)

Can we access class method variable using dot notation in python

Below is the code
import os
class ABC:
def test(self,name):
var = 5
var2 = 10
dic = {"Ada": "adada"}
print "asdfdsadv"
var1 = "Ada"
var2 = "asada"
obj = ABC()
print obj.test("Ada").var1
I am looking for something like this. Can I achieve this in python
I know this is var variable in local to class. Is there someway by using global or something else to acheive this
Accessing a variable from a class method is not possible, you have to set the variable at the class level like this:
import os
class ABC:
def test(self,name):
var = 5
var2 = 10
dic = {"Ada": "adada"}
print "asdfdsadv"
self.var1 = "Ada"
var2 = "asada"
obj = ABC()
obj.test('Ada')
print obj.var1
You could chain obj.test('Ada').var1 in the same line by returning self into your test method.
I think this would work. The init(self) behave like a constructor in other languages. So in effect I am constructing a class in a class, to make your last line work properly. But like other suggested that is not the way Python is supposed to be used.
import os
class ABC(object):
def __init__(self):
pass
class test(object):
def __init__(self,name):
self.var = 5
self.var2 = 10
self.dic = {"Ada": "adada"}
print ("asdfdsadv")
self.var1 = "Ada"
self.var2 = "asada"
if __name__ == "__main__":
obj = ABC()
print (obj.test("Ada").var1)
What you are looking for are the class variables, usually defined as self.variable. Here an example of your code:
import os
class ABC:
def __init__(self):
self.var = 5
self.var2 = 10
self.dic = {"Ada": "adada"}
self.var1 = "Ada"
def test(self,name):
print self.var
print self.var2
print self.var1 + " " + name
obj = ABC()
print obj.dic # {'Ada': 'adada'}
print obj.dic["Ada"] # adada
obj.test("wow") # 5, 10, Ada wow
obj.var1 = "Ede"
obj.test("wow") # 5, 10, Ede wow
but as suggested in other answers, you may want to take a step back and check what is the scope of python variables
Forget about classes and consider functions in general.
When you define a function, any variables within its scope are local and only accessible from within the execution of that function. Once execution has finished, that's it, they are gone. This is fundamental; the only way of getting data from a function is by returning it.
Although it is a hack, you could return locals() (a dictionary of local variables), but this is terrible practice.
import os
class ABC:
def test(self,name):
var = 5
var2 = 10
dic = {"Ada": "adada"}
print "asdfdsadv"
var1 = "Ada"
var2 = "asada"
return locals()
obj = ABC()
print obj.test("Ada")["var1"]
If you return the object itself from the function and the variables are not local but instance variables it works.
class ABC:
def test(self, name):
self.var1 = "My name is {}".format(name)
return self
obj = ABC()
print obj.test('Ada').var1

calculate how many times of the functions or variables be invoked

I want to get the invoked times of each function or variable from existing codes which is writing in python.
What i thought is override the object's getattribute function, such as below:
acc = {}
class object(object):
def __getattribute__(self, p):
acc.update({str(self) + p: acc.get(str(self) + p, 0) + 1})
return supe(object, self).__getattribute__(p)
class A(object):
def a(self):
pass
class B(A):
def b(self):
pass
def main():
a = A()
a.a()
b = B()
b.b()
b.a = 'a'
b.a
print acc
if __name__ == '__main__':
main()
But, it only can calculate functions and variable in object, how can i calculate the normal functions or variable, such as:
def fun1():
pass
fun1()
fun1()
I want to get the result as 2, is there any tool or method to do it?
I am sorry my pool english, What i really need is the invoked times not the run time.
such as above, we said, fun1() is invoked two times.
Use a decorator.
>>> def timestamp(container, get_timestamp):
... def timestamp_decorator(func):
... def decorated(*args, **kwargs):
... container[func.func_name] = get_timestamp()
... return func(*args, **kwargs)
... return decorated
... return timestamp_decorator
...
And you use it like this:
>>> import datetime
>>> def get_timestamp():
... return datetime.datetime.now()
...
>>> timestamps = {}
>>> #timestamp(timestamps, get_timestamp)
... def foo(a):
... return a * 2
...
>>> x = foo(2)
>>> print x, timestamps
4 {'foo': datetime.datetime(2012, 2, 14, 9, 55, 15, 789893)}
There would be a way to create a counter decorator to a function (nbot a timestamp decorator) -and to automatically wrap all functions in a given module with this decorator -
so, if the module where you want to count the function calls in is named "mymodule" you can write:
class function_counter(object):
def __init__(self, func):
self.counter = 0
self.func = func
def __call__(self, *args, **kw):
self.counter += 1
return self.func(*args, **kw)
And:
>>> #function_counter
... def bla():
... pass
...
>>>
>>> bla()
>>> bla()
>>> bla()
>>> bla.counter
3
To apply this to all the functions in a module, you can write something like:
import mymodule
from types import FunctionType, BuiltinFunctionType
# define the "function_counter" class as above here (or import it)
for key, value in mymodule.__dict__.items():
if isinstance(value, (FunctionType, BuiltinFunctionType)):
mymodule.__dict__[key] = function_counter(value)
That would do for counting function usage.
If you want to count module level variable usage though, it is not that easy - as
you can't just override the mechanism attribute retrieving from a module object as you did for a class in your example.
The way to go there, is to substitute your module for a class - that implements the attribute counting scheme as you do in your example - after you import your module - and have all module attributes to be assigned to instance attributes in this class.
This is not a tested example (unlike the above), but try something along:
import mymodule
from types import FunctionType
class Counter(object):
# counter __getattribute__ just as you did above
c = Counter()
for key, value in mymodule.__dict__.items():
setattr(c, key, staticmethod(value) if isinstance(value, FunctionType) else value)
mymodule = c

How do I pass variables between class instances or get the caller?

class foo():
def __init__(self)
self.var1 = 1
class bar():
def __init__(self):
print "foo var1"
f = foo()
b = bar()
In foo, I am doing something that produces "var1" being set to 1
In bar, I would like to access the contents of var1
How can I access var1 in the class instance f of foo from within the instance b of bar
Basically these classes are different wxframes. So for example in one window the user may be putting in input data, in the second window, it uses that input data to produce an output. In C++, I would have a pointer to the caller but I dont know how to access the caller in python.
As a general way for different pages in wxPython to access and edit the same information consider creating an instance of info class in your MainFrame (or whatever you've called it) class and then passing that instance onto any other pages it creates. For example:
class info():
def __init__(self):
self.info1 = 1
self.info2 = 'time'
print 'initialised'
class MainFrame():
def __init__(self):
a=info()
print a.info1
b=page1(a)
c=page2(a)
print a.info1
class page1():
def __init__(self, information):
self.info=information
self.info.info1=3
class page2():
def __init__(self, information):
self.info=information
print self.info.info1
t=MainFrame()
Output is:
initialised
1
3
3
info is only initialised once proving there is only one instance but page1 has changed the info1 varible to 3 and page2 has registered that change.
No one has provided a code example showing a way to do this without changing the init arguments. You could simply use a variable in the outer scope that defines the two classes. This won't work if one class is defined in a separate source file from the other however.
var1 = None
class foo():
def __init__(self)
self.var1 = var1 = 1
class bar():
def __init__(self):
print var1
f = foo()
b = bar()
Same as in any language.
class Foo(object):
def __init__(self):
self.x = 42
class Bar(object):
def __init__(self, foo):
print foo.x
a = Foo()
b = Bar(a)
Alternatively you could have a common base class from which both derived classes inherit the class variable var1. This way all instances of derived classes can have access to the variable.
Something like:
class foo():
def __init__(self)
self.var1 = 1
class bar():
def __init__(self, foo):
print foo.var1
f = foo()
b = bar(foo)
You should be able to pass around objects in Python just like you pass around pointers in c++.
Perhaps this was added to the language since this question was asked...
The global keyword will help.
x = 5
class Foo():
def foo_func(self):
global x # try commenting this out. that would mean foo_func()
# is creating its own x variable and assigning it a
# value of 3 instead of changing the value of global x
x = 3
class Bar():
def bar_func(self):
print(x)
def run():
bar = Bar() # create instance of Bar and call its
bar.bar_func() # function that will print the current value of x
foo = Foo() # init Foo class and call its function
foo.foo_func() # which will add 3 to the global x variable
bar.bar_func() # call Bar's function again confirming the global
# x variable was changed
if __name__ == '__main__':
run()

How to get the caller's method name in the called method?

Python: How to get the caller's method name in the called method?
Assume I have 2 methods:
def method1(self):
...
a = A.method2()
def method2(self):
...
If I don't want to do any change for method1, how to get the name of the caller (in this example, the name is method1) in method2?
inspect.getframeinfo and other related functions in inspect can help:
>>> import inspect
>>> def f1(): f2()
...
>>> def f2():
... curframe = inspect.currentframe()
... calframe = inspect.getouterframes(curframe, 2)
... print('caller name:', calframe[1][3])
...
>>> f1()
caller name: f1
this introspection is intended to help debugging and development; it's not advisable to rely on it for production-functionality purposes.
Shorter version:
import inspect
def f1(): f2()
def f2():
print 'caller name:', inspect.stack()[1][3]
f1()
(with thanks to #Alex, and Stefaan Lippen)
This seems to work just fine:
import sys
print sys._getframe().f_back.f_code.co_name
I would use inspect.currentframe().f_back.f_code.co_name. Its use hasn't been covered in any of the prior answers which are mainly of one of three types:
Some prior answers use inspect.stack but it's known to be too slow.
Some prior answers use sys._getframe which is an internal private function given its leading underscore, and so its use is implicitly discouraged.
One prior answer uses inspect.getouterframes(inspect.currentframe(), 2)[1][3] but it's entirely unclear what [1][3] is accessing.
import inspect
from types import FrameType
from typing import cast
def demo_the_caller_name() -> str:
"""Return the calling function's name."""
# Ref: https://stackoverflow.com/a/57712700/
return cast(FrameType, cast(FrameType, inspect.currentframe()).f_back).f_code.co_name
if __name__ == '__main__':
def _test_caller_name() -> None:
assert demo_the_caller_name() == '_test_caller_name'
_test_caller_name()
Note that cast(FrameType, frame) is used to satisfy mypy.
Acknowlegement: comment by 1313e for an answer.
I've come up with a slightly longer version that tries to build a full method name including module and class.
https://gist.github.com/2151727 (rev 9cccbf)
# Public Domain, i.e. feel free to copy/paste
# Considered a hack in Python 2
import inspect
def caller_name(skip=2):
"""Get a name of a caller in the format module.class.method
`skip` specifies how many levels of stack to skip while getting caller
name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.
An empty string is returned if skipped levels exceed stack height
"""
stack = inspect.stack()
start = 0 + skip
if len(stack) < start + 1:
return ''
parentframe = stack[start][0]
name = []
module = inspect.getmodule(parentframe)
# `modname` can be None when frame is executed directly in console
# TODO(techtonik): consider using __main__
if module:
name.append(module.__name__)
# detect classname
if 'self' in parentframe.f_locals:
# I don't know any way to detect call from the object method
# XXX: there seems to be no way to detect static method call - it will
# be just a function call
name.append(parentframe.f_locals['self'].__class__.__name__)
codename = parentframe.f_code.co_name
if codename != '<module>': # top level usually
name.append( codename ) # function or a method
## Avoid circular refs and frame leaks
# https://docs.python.org/2.7/library/inspect.html#the-interpreter-stack
del parentframe, stack
return ".".join(name)
Bit of an amalgamation of the stuff above. But here's my crack at it.
def print_caller_name(stack_size=3):
def wrapper(fn):
def inner(*args, **kwargs):
import inspect
stack = inspect.stack()
modules = [(index, inspect.getmodule(stack[index][0]))
for index in reversed(range(1, stack_size))]
module_name_lengths = [len(module.__name__)
for _, module in modules]
s = '{index:>5} : {module:^%i} : {name}' % (max(module_name_lengths) + 4)
callers = ['',
s.format(index='level', module='module', name='name'),
'-' * 50]
for index, module in modules:
callers.append(s.format(index=index,
module=module.__name__,
name=stack[index][3]))
callers.append(s.format(index=0,
module=fn.__module__,
name=fn.__name__))
callers.append('')
print('\n'.join(callers))
fn(*args, **kwargs)
return inner
return wrapper
Use:
#print_caller_name(4)
def foo():
return 'foobar'
def bar():
return foo()
def baz():
return bar()
def fizz():
return baz()
fizz()
output is
level : module : name
--------------------------------------------------
3 : None : fizz
2 : None : baz
1 : None : bar
0 : __main__ : foo
You can use decorators, and do not have to use stacktrace
If you want to decorate a method inside a class
import functools
# outside ur class
def printOuterFunctionName(func):
#functools.wraps(func)
def wrapper(self):
print(f'Function Name is: {func.__name__}')
func(self)
return wrapper
class A:
#printOuterFunctionName
def foo():
pass
you may remove functools, self if it is procedural
An alternative to sys._getframe() is used by Python's Logging library to find caller information. Here's the idea:
raise an Exception
immediately catch it in an Except clause
use sys.exc_info to get Traceback frame (tb_frame).
from tb_frame get last caller's frame using f_back.
from last caller's frame get the code object that was being executed in that frame.
In our sample code it would be method1 (not method2) being executed.
From code object obtained, get the object's name -- this is caller method's name in our sample.
Here's the sample code to solve example in the question:
def method1():
method2()
def method2():
try:
raise Exception
except Exception:
frame = sys.exc_info()[2].tb_frame.f_back
print("method2 invoked by: ", frame.f_code.co_name)
# Invoking method1
method1()
Output:
method2 invoked by: method1
Frame has all sorts of details, including line number, file name, argument counts, argument type and so on. The solution works across classes and modules too.
Code:
#!/usr/bin/env python
import inspect
called=lambda: inspect.stack()[1][3]
def caller1():
print "inside: ",called()
def caller2():
print "inside: ",called()
if __name__=='__main__':
caller1()
caller2()
Output:
shahid#shahid-VirtualBox:~/Documents$ python test_func.py
inside: caller1
inside: caller2
shahid#shahid-VirtualBox:~/Documents$
I found a way if you're going across classes and want the class the method belongs to AND the method. It takes a bit of extraction work but it makes its point. This works in Python 2.7.13.
import inspect, os
class ClassOne:
def method1(self):
classtwoObj.method2()
class ClassTwo:
def method2(self):
curframe = inspect.currentframe()
calframe = inspect.getouterframes(curframe, 4)
print '\nI was called from', calframe[1][3], \
'in', calframe[1][4][0][6: -2]
# create objects to access class methods
classoneObj = ClassOne()
classtwoObj = ClassTwo()
# start the program
os.system('cls')
classoneObj.method1()
Hey mate I once made 3 methods without plugins for my app and maybe that can help you, It worked for me so maybe gonna work for you too.
def method_1(a=""):
if a == "method_2":
print("method_2")
if a == "method_3":
print("method_3")
def method_2():
method_1("method_2")
def method_3():
method_1("method_3")
method_2()

Categories