List of all functions used in python program as string - python

How can we find all the functions in a python program??? for eg.
Input
def func1:
#doing something
def func2:
#doing something
def func3:
#doing something
Output
{'func1' , 'func2' , 'func3'}

If you want all functions in the global scope, you can use globals() with inspect.isfunction():
>>> def foo():
... pass
...
>>> def bar():
... pass
...
>>> import inspect
>>> [member.__name__ for member in globals().values() \
... if inspect.isfunction(member)]
['bar', 'foo']

Guessing you want only the methods in your current context:
import inspect
d = locals()
funcs = [f for f in d if inspect.isfunction(d[f])]

Related

How to loop over all functions of another class using a list of function type elements?

I am trying to get a list of all the functions in a class and then looping over them so they are all executed without having to type each one out. For example:
class Foo:
def foo(self):
print('foo')
def bar(self):
print('bar')
Then in another file
import Foo
import inspect
newfoo = Foo()
functions = [f for f in inspect.getmembers(Foo, predicate=inspect.isfunction)]
for f in functions:
newfoo.f[1]()
I am hoping to get:
foo
bar
But this gives the error
AttributeError: 'Foo' object has no attribute 'f'
Any ideas on how to execute this? Thanks in advance.
You can use getattr to call class method by name.
code:
import inspect
class Foo:
def foo(self):
print('foo')
def bar(self):
print('bar')
newfoo = Foo()
functions = [f for f in inspect.getmembers(Foo, predicate=inspect.isfunction)]
for f in functions:
getattr(newfoo, f[0])()
result:
bar
foo
You could even use it without the inspect module:
class Foo:
def foo():
print('foo')
def bar():
print('bar')
object_methods = [method_name for method_name in dir(Foo)
if not method_name.startswith("__") and
callable(getattr(Foo, method_name))]
print(object_methods)
This yields
['bar', 'foo']
Your code is almost correct. just change newfoo.f[1]() to f[1]() and it will work properly.
for f in functions:
f[1]()

Functions in dictionaries in python

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.

What is more pythonic: trivial lambda or None?

When a function accepts a function argument (or a class has a function slot), there is a choice between two approaches:
def foo(..., my_func=None, ...):
...
if my_func:
my_func(...)
...
and
def foo(..., my_func=(lambda ...: None), ...):
...
my_func(...)
...
What is more Pythonic/clear/readable?
What is faster - an extra boolean check or a trivial function call?
When using this:
>>> def bar():
... print("Goodbye, World!")
...
I find this very readable:
>>> def foo(my_func = lambda : None):
... my_func()
...
>>> foo()
>>> foo(bar)
Goodbye, World!
I find this pointlessly annoying
>>> def baz(my_func = None):
... if my_func is not None:
... my_func()
...
>>> baz()
>>> baz(bar)
Goodbye, World!
Try to keep None checks out of your life. Use None when you want it to do what it does well: blow up in your face. Don't ask it to be quiet. One way or another it's going to create annoying noise if you use it.
What is faster - an extra boolean check or a trivial function call?
Why, in Gods name, do you care?
For the record, I find this readable but overly permissive:
>>> def buz(my_func = lambda **k:None):
... my_func()
...
>>> buz(bar)
Goodbye, World!

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

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

Categories