I want to do something like this:
def a():
# do stuff
return stuff
def b():
# do stuff
return different_stuff
def c():
# do one last thing
return 200
for func in this_file:
print func_name
print func_return_value
I essentially want to mimic this flask app, without the flask parts:
app = Flask(__name__)
app.register_blueprint(my_bp, url_prefix='/test')
my_bp.data = fake_data
def tests():
with app.test_client() as c:
for rule in app.url_map.iter_rules():
if len(rule.arguments) == 0 and 'GET' in rule.methods:
resp = c.get(rule.rule)
log.debug(resp)
log.debug(resp.data)
is this possible?
Like this:
import sys
# some functions...
def a():
return 'a'
def b():
return 'b'
def c():
return 'c'
# get the module object for this file
module = sys.modules[__name__]
# get a list of the names that are in this module
for name in dir(module):
# get the Python object from this module with the given name
obj = getattr(module, name)
# ...and if it's callable (a function), call it.
if callable(obj):
print obj()
running this gives:
bgporter#varese ~/temp:python moduleTest.py
a
b
c
Note that the functions will not necessarily be called in the order of definition as they are here.
Use this code to create the python module get_module_attrs.py
import sys
module = __import__(sys.argv[1])
for name in dir(module):
obj = getattr(module, name)
if callable(obj):
print obj.__name__
Then you can call it as $python get_module_attrs.py <name_of_module>
Enjoy it!!
Maybe:
def a(): return 1
def b(): return 2
def c(): return 3
for f in globals ().values ():
if callable (f): continue
print f.__name__
print f ()
Related
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.
I can store functions in dictionaries by saying
MyDict = {}
def func():
print("Hello, world!")
MyDict["func"] = func
I was wondering if there was a cleaner/neater way to write this - something along the lines of
MyDict = {}
def MyDict["func"]():
print("Hello, world!")
However this code throws a syntax error
You can (ab)use a decorator.
MyDict = {}
def store(d, name):
def _(f):
d[name] = f
return f
return _
#store(MyDict, "func")
def func():
print("Hello, world!")
#store(MyDict, "foo")
def some_other_func():
print("Goodbye")
You can simplify this if you just want to use the defined name as the key and hard-code the dictionary to update:
def store(f):
MyDict[f.__name__] = f
return f
#store
def func():
print("Hello, world!")
For your example you can do this:
d = {}
d['func'] = lambda: print('Hello, world!')
d['func']()
>>> 'Hello, world!'
If you want to use a class:
class MyClass:
def func(self):
print('Hello, world!')
c = MyClass()
c.func()
>>> 'Hello, world!'
This is wrong:
def MyDict["func"]():
print("Hello, world!")
because after def you need to use some word that contains only allowed characters. That's why you got Syntax error.
What you can use is:
1) Lambda functions (as suggested by #bphi)
MyDict = {}
MyDict['func'] = lambda: print("123")
MyDict['func']()
2) Python class to dynamically create methods (inside the class) which are stored in MyDict, using setattr built-in function:
def func1():
print(1)
def func2():
print(2)
MyDict = {}
MyDict['func1'] = func1
MyDict['func2'] = func2
class MyClass3:
def __init__(self):
for name, obj in MyDict.items():
setattr(self, name, obj)
obj = MyClass3()
obj.func1()
obj.func2()
or via lambda:
MyDict = {}
MyDict['func1'] = lambda : print(1)
MyDict['func2'] = lambda : print(2)
class MyClass3:
def __init__(self):
for name, obj in MyDict.items():
setattr(self, name, obj)
obj = MyClass3()
obj.func1()
obj.func2()
or
class MyClass3:
MyDict = {}
MyDict['func1'] = lambda: print(1)
MyDict['func2'] = lambda: print(2)
def __init__(self):
for name, obj in self.MyDict.items():
setattr(self, name, obj)
obj = MyClass3()
obj.func1()
obj.func2()
If you can express all your functions as one-liners, use lambdas as suggested in #bphi's answer.
If you don't want to be rescricted by using the lambda calculus, another way is to use a class and its static methods. Static methods are methods of a class, not an instance of a class, so they don't have access to the inner state of an object and can be called on the class, not an instance.
However, by reading through this answer you might see why this is not a very elegant (or recommended) approach, even though the result is exactly what you asked for.
class MyClass:
#staticmethod # this decorator is optional here, but suggested for code clarity
def func():
print("Hello, world!")
def func2():
print("Hey there, I am another function.")
MyClass.func()
>>> 'Hello, world!'
MyClass.func()
>>> 'Hey there, I am another function.'
If you want to use the syntax of dictionaries as proposed in your question, you can use __dict__ on the class:
MyDict = dict(MyClass.__dict__)
MyDict["func"]()
>>> 'Hello, world!'
MyDict["func2"]()
>>> 'Hey there, I am another function.'
And you can also add other functions to that dictionary:
MyDict["func3"] = lambda: print("Hi, I am yet another function.")
def func4:
print("And I am the last function for today.")
MyDict["func4"] = func4
MyDict["func"]()
>>> 'Hi, I am yet another function.'
MyDict["func2"]()
>>> 'And I am the last function for today.'
But as this dictionary is just a representation of the class MyClass, it also contains some items related to that class, like __weakref__. But you can extract your own functions:
MyCleanDict = {}
for key, value in MyDict:
if not key.startswith("_"):
MyCleanDict[key] = value
The result is exactly what you asked for, but I doubt the complexity of the approach is worth the result. I recommend a) using lambda-functions, b) staying at your first approach (define the functions first and then put them in a dict) or c) rethink your actual problem as you may find another solution besides storing functions in a dictionary.
I am trying to mock an import during testing
Test.py looks like
# Store original __import__
orig_import = __import__
b_mock = mock.Mock()
def import_mock(name, *args):
if name == 'B':
return b_mock
return orig_import(name, *args)
with mock.patch('__builtin__.__import__', side_effect=import_mock):
import A
A.py looks like
import B
def a():
return B.func()
Now
b_mock.func.return_value = 'spam'
Therefore, A.a() should return 'spam'
However, A.a() returns the entire mock object b_mock like this: < Mock name='mock.B.func()' id='139854736039632' >
Everytime B.func() is called, how do I get the return value which I have set(i.e 'spam') instead of getting the entire mock object?
Is there a way to limit a function to be called by specific function(s)?
def a():
private() # okay
def b():
private() # raises error
def private():
print "private"
import inspect
def private():
cframe = inspect.currentframe()
func = inspect.getframeinfo(cframe.f_back).function
if func != 'a':
print 'not allowed from ', func
print "private"
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