0

I want to make following function:

 1)input is a number. 
 2)functions are indexed, return a function whose index matches given number

here's what I came up with:

def foo_selector(whatfoo):
    def foo1():
        return
    def foo2():
        return
    def foo3():
        return
    ...

    def foo999():
        return

    #something like return foo[whatfoo]

the problem is, how can I index the functions (foo#)? I can see functions foo1 to foo999 by dir(). however, dir() returns name of such functions, not the functions themselves. In the example, those foo-functions aren't doing anything. However in my program they perform different tasks and I can't automatically generate them. I write them myself, and have to return them by their name.

1
  • If you can use dir() to see your fooX() function names, you can use getattr() to get the function itself. Commented Dec 2, 2012 at 5:01

3 Answers 3

4

Use a decorator to accumulate a list of functions.

func_list = []

def listed_func(func):
    func_list.append(func)
    return func

@listed_func
def foo1():
   pass

@listed_func
def foo2():
   pass

Now you can easily access the functions by index in a list.

You could also create a dictionary if you want to access the functions by name:

func_dict = {}

def collected_func(func):
    func_dict[func.__name__] = func
    return func

Or extract the index from the name, and use that as the dict key (since dicts are not ordered, you'll want to sort the keys if you want to iterate over them in some order):

func_dict = {}

def collected_func(func):
    key = int("".join(c for c in func.__name__ if c.isdigit()))
    func_dict[key] = func
    return func

Or explicitly pass the index number to the decorator:

func_dict = {}

def collected_func(key):
    def decorator(func):
        func_dict[key] = func
        return func
    return decorator

@collected_func(12)
def foo():
    pass
Sign up to request clarification or add additional context in comments.

5 Comments

This depends of foo2 being later in the file than foo1. If this is a problem, then you could parse the function name to get the index.
Yes, I assume the names of the functions have nothing to do with their order in the list. They'll be added to the list in the order they are defined.
Added some alternatives for various possibilities.
this should work, thanks for your reply. Now I have one more question : How can I expand it to methods of a class?
What exactly do you want to do with it in a class? Do you want instance methods in the dictionary? That can't be done at class definition time because there is no instance then. I'd suggest posting another question with a better explanation of what you want to do.
0

You could simply place all of your functions into an array, something like:

def foo_selector(whatfoo):
    def foo1():
        return
    def foo2():
        return
    def foo3():
        return
    ...

    def foo999():
        return

    foo_list = [
        foo1,
        foo2,
        ...
        foo999
    ]

    return foo_list[whatfoo]

1 Comment

if there isn't any more elegant way, I think that is only option to which I can resort
0

Here are a couple other ways you could do it:

eval("foo{}()".format(whatfoo))

or

locals()['foo{}'.format(whatfoo)]

1 Comment

Your eval() version has the potential to be very dangerous. I would choose a method that doesn't dig so much into the internals.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.