【问题标题】:Using a dictionary to control the flow of methods使用字典控制方法流
【发布时间】:2013-08-05 05:32:25
【问题描述】:

我有一个包含多个方法的类 Population。

根据输入,我希望以给定的顺序在 Population 类的实例上运行该方法。

在我想要达到的目标上更准确一点,与使用类似的东西完全一样:

stuff = input(" enter stuff ")

dico = {'stuff1':functionA, 'stuff2':functionC, 'stuff3':functionB, 'stuff4':functionD}

dico[stuff]()

除了functionA、functionB等...是方法而不是函数:

order_type = 'a'
class Population (object):
    def __init__(self,a):
        self.a = a

    def method1 (self):
        self.a = self.a*2
        return self

    def method2 (self):
        self.a += 2
        return self

    def method3 (self,b):
        self.a = self.a + b
        return self

if order_type=='a':
    order = {1:method1, 2:method2, 3:method3}
elif order_type=='b':
    order = {1:method2, 2:method1, 3:method3}
else :
    order = {1:method3, 2:method2, 3:method1}

my_pop = Population(3)

while iteration < 100:
    iteration +=1
    for i in range(len(order)):
        method_to_use = order[i]
        my_pop.method_to_use() # But obviously it doesn't work!

希望我的问题已经足够清楚了! 请注意,我的一种方法需要两个参数

【问题讨论】:

  • @Keyser 是的,你是对的,我也可以使用列表,但它不会对我遇到的问题有太大的改变
  • 感谢您的所有回答。但我现在意识到你的解决方案的第二个问题。如果我只需要为这三种方法之一添加第二个参数怎么办?我更新了我的帖子以举例说明我的问题。
  • 我可以用 if else 语句来做到这一点!

标签: python methods dictionary


【解决方案1】:

使用getattr:

order = {1:'method1', 2:'method2', 3:'method3'} #values are strings
...
method_to_use = order[i]
getattr(mypop, method_to_use)()

【讨论】:

    【解决方案2】:

    将实例作为第一个参数显式传递:

    method_to_use = order[i]
    method_to_use(my_pop)
    

    完整的工作代码:

    order_type = 'a'
    class Population (object):
        def __init__(self,a):
            self.a = a
    
        def method1 (self):
            self.a = self.a*2
            return self
    
        def method2 (self):
            self.a += 2
            return self
    
        def method3 (self):
            self.a = 0
            return self
    
    if order_type=='a':
        order = [Population.method1, Population.method2, Population.method3]
    elif order_type=='b':
        order = [Population.method2, Population.method1, Population.method3]
    else :
        order = [Population.method3, Population.method2, Population.method1]
    
    my_pop = Population(3)
    
    while iteration < 100:
        iteration +=1
        for method_to_use in order:
            method_to_use(my_pop)
    

    如果您想传递多个参数,只需使用*args 语法:

    if order_type=='a':
        order = [Population.method1, Population.method2, Population.method3]
        arguments = [(), (), (the_argument,)]
    elif order_type=='b':
        order = [Population.method2, Population.method1, Population.method3]
        arguments = [(), (), (the_argument,)]
    else :
        order = [Population.method3, Population.method2, Population.method1]
        arguments = [(the_argument, ), (), ()]
    
    my_pop = Population(3)
    
    while iteration < 100:
        iteration +=1
        for method_to_use, args in zip(order, arguments):
            method_to_use(my_pop, *args)
    

    () 是一个空元组,因此*args 将扩展为没有其他参数,而(the_argument,) 是一个单元素元组,会将参数传递给方法。

    【讨论】:

    • 感谢大家的帮助!如果我需要为方法 3(而不是其他方法)传递第二个参数怎么办?
    【解决方案3】:

    你可以使用operator.methodcaller:

    from operator import methodcaller
    method_to_use = methodcaller('method' + str(i))
    method_to_use(my_pop)
    

    【讨论】:

      猜你喜欢
      • 2017-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多