views:

108

answers:

4

I defined a .py file in this format:

foo.py

def foo1(): pass
def foo2(): pass
def foo3(): pass

I import it from another file:

main.py

from foo import * 
# or
import foo

Is it possible list all functions name, e.g. ["foo1", "foo2", "foo3"]?


Thanks for your help, I made a class for what I want, pls comment if you have suggestion

class GetFuncViaStr(object):
    def __init__(self):
        d = {}
        import foo
        for y in [getattr(foo, x) for x in dir(foo)]:
            if callable(y):
               d[y.__name__] = y
    def __getattr__(self, val) :
        if not val in self.d :
           raise NotImplementedError
        else:
           return d[val] 
+5  A: 

you can use dir to explore a namespace.

import foo
print dir(foo)

Example: loading your foo in shell

>>> import foo
>>> dir(foo)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'foo1', 'foo2', 'foo3']
>>> 
>>> getattr(foo, 'foo1')
<function foo1 at 0x100430410>
>>> k = getattr(foo, 'foo1')
>>> k.__name__
'foo1'
>>> callable(k)
True
>>> 

You can use getattr to get the associated attribute in foo and find out if it callable.

Check the documentation : http://docs.python.org/tutorial/modules.html#the-dir-function

and if you do - "from foo import *" then the names are included in the namespace where you call this.

>>> from foo import *
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'atexit', 'foo1', 'foo2', 'foo3']
>>> 

The following brief on introspection in python might help you :

pyfunc
Take a look at inspect also: http://docs.python.org/library/inspect.html
Epeli
+1  A: 

For a wild import

from foo import * 
print dir()

you can use dir() without a parameter to show objects in the current module's namespace. This will most probably include more than just the content of foo.

In case of an absolute import (which you should prefer by the way) you can pass the module to dir():

import foo
print dir(foo)

Also check the documentation of dir. As you only wanted functions, you might want to think about using inspect.isfunction. Hope you don't use that list for non-debugging purposes.

AndiDog
thanks,is it means I may have to filter the result of dir() in order to get all functions?
user478514
@user478514: Just edited to answer that ;) You can use `inspect.isfunction`.
AndiDog
+10  A: 

The cleanest way to do these things is to use the inspect module. It has a getmembers function that takes a predicate as the second argument. You can use isfunction as the predicate.

 import inspect

 all_functions = inspect.getmembers(module, inspect.isfunction)

Now, all_functions will be a list of tuples where the first element is the name of the function and the second element is the function itself.

aaronasterling
+1 for inspect.getmembers !
Tumbleweed
@aaronasterling, I have no python env right now to test, is the func item in list do not need an "import" for invoking anymore just all_functions[0][1](para)?
user478514
@user478514 You have to import it initially to call `getmembers` on it but after that, the second element of each tuple is a function with it's globals bound to the globals of the module that it is defined in. No further reference need be made to that module.
aaronasterling
+1  A: 

Try using inspect module like below for exmaple if module --> temp.py

In [26]: import inspect

In [27]: import temp

In [28]: l1 = [x.__name__ for x in temp.__dict__.values() if inspect.isfunction(x)]

In [29]: print l1
['foo', 'coo']
Tumbleweed