Storing Functions in Dictionary [Python]

爷,独闯天下 提交于 2021-02-08 12:46:48

问题


I'm currently building an application where I need to iterate over a series of steps that do largely the same thing, save a very small amount of code (~15 lines). The number of steps will vary depending on how the project is configured, so it seems kind of silly for me to create a separate function for each potential instance.

In JavaScript, I would do something like this:

var switches = [true, true, false, true];

var holder = {
    0: function() { /* do step0 */ }
    1: function() { /* do step1 */ }
    2: function() { /* do step2 */ }
    3: function() { /* do step3 */ }
    // ...etc...
}

for (var i = 0; i < switches.length; i++)
    if (switches[i])
        holder[i]();

Is there a way to do something similar to this in python? The only thing I can think of is something like this:

switches = [True, True, False, True]

class Holder(object):
    @staticmethod
    def do_0():
        # do step0

    @staticmethod
    def do_1():
        # do step 1

    # ...etc...

    def __repr__(self):
        return [self.do_0, self.do_1, ...]

for action in Holder:
    action()

This just seems terribly inefficient if I have any significant number of steps. Is there any better way to go about this?


回答1:


You can do this as follows:

# define your functions
def fun1():
    print("fun1")

def fun2():
    print("fun2")

def fun3():
    print("fun3")


switches = [True, False, True];

# put them in a list (list makes more sense than dict based on your example)
func_list = [fun1, fun2, fun3]

# iterate over switches and corresponding functions, and execute 
# functions when s is True    
for s,f in zip(switches, func_list):
    if s: f() 

This is one way only. There are many others. e.g. using lambdas, dict as you wanted, etc.

To use lambdas if your functions are one line only, you can do:

func_list = [lambda: print("lambda1"), 
             lambda: print("lambda2"), 
             lambda: print("lambda1")]



回答2:


It looks like there isn't a way to do this in Python, a design decision made intentionally since it was dismissed as un-Pythonic. Oh well, it looks like I'm stuck defining the methods and then manually adding them to a list to iterate through.

Source: https://softwareengineering.stackexchange.com/a/99245




回答3:


- Your functions don't need to be enveloped in a utility class.
- I don not see how the two blocks of code differ in efficiency.
- You can use enumerate and lambdas to simplify your code.

Simplified Code

d = {0: lambda: 'Performing Step 0',
     1: lambda: 'Performing Step 1',
     2: lambda: 'Performing Step 2',
     3: lambda: 'Performing Step 3',
     4: lambda: 'Performing Step 4'}

for index, switch in enumerate([1, 0, 1, 1, 0]):
    if switch == 1: d[index]() 



回答4:


I typically go about this like the following. I like this approach, because it adds a minimum of typing overhead to the code, and if you write an additional method later on, nothing needs to be modified elsewhere in the file.

def steptest0():
    code
def steptest1():
    code
def steptest2():
    code

...

tests = filter(lambda x: x.startswith('steptest'),
               dir())
for t in tests: eval(t + '()')

Every method is already put into a dictionary automatically in Python, and dir() lets us access that.

Disclaimer. There are multiple alarm bells starting to go off in the head of the average pedestrian zealot at the sight of "eval" and some may even have seizures. Let them guard themselves from eval by using a reflection mechanism instead (which might make it less readable, but still worth it, as they can't be accused of using "eval").



来源:https://stackoverflow.com/questions/29245004/storing-functions-in-dictionary-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!