动态创建方法的更好方法

时间:2012-05-29 21:44:13

标签: python dynamic methods

所以我需要根据对__init__的输入改变对象初始化的方法(对于那些感兴趣的人,我在测试框架中根据哪种类型的自动机正在改变navigate_to方法实例化(Selenium,移动设备automator等))。我在__init__中使用有条件创建的闭包来提出解决方案,但似乎应该有更优雅和优化的方法来执行此操作。作为该方法的一个例子:

class Foo(object):
    def __init__(self, x):
        self.x = x
        if x % 2:
            def odd_or_even():
                return '%d odd' % self.x
        else:
            def odd_or_even():
                return '%d even' % self.x
        self.odd_or_even = odd_or_even

导致:

>>> foo1 = Foo(1)
>>> foo2 = Foo(2)
>>> foo1.odd_or_even()
'1 odd'
>>> foo2.odd_or_even()
'2 even'

这有效,但我觉得应该有更好的方法来做到这一点。建议?

2 个答案:

答案 0 :(得分:3)

我建议委托这个 - 比如

class Automator(object):
    def navigate_to(self, url):
        pass

class SeleniumAutomator(Automator):
    def navigate_to(self, url):
        # do it the Selenium way
        pass

class MobileAutomator(Automator):
    def navigate_to(self, url):
        # do it the mobile-browser way
        pass

class Foo(object):
    def __init__(self, x, automator):
        self.x = x
        self.automator = automator

    def navigate_to(self, url):
        return self.automator.navigate_to(url)

f = Foo(3, SeleniumAutomator())
f.navigate_to('http://www.someplace.org/')

...你可以用函数做到这一点,但我认为有一堆依赖于接口的方法,并且将它们分组在一个类中似乎最干净。

编辑:哦 - 那么你想要的不是Foo,它是一个自动机工厂 - 类似

def makeAutomator(type, *args, **kwargs):
    return {
        "selenium": SeleniumAutomator,
        "mobile":   MobileAutomator
    }[type](*args, **kwargs)

myauto = makeAutomator("selenium")

答案 1 :(得分:1)

我会为每种类型的automator创建一个不同的方法,然后使用self状态的通用方法来确定要调用哪些特定方法。

为什么你需要创建一个包含决定的闭包,何时可以在self中记录决定?