Runner方法作为方法链的替代方法?

时间:2016-02-19 17:05:28

标签: python python-3.x

我有一个用于数据分析的课程。通常我需要创建该类的几个实例,然后在每个实例上运行一系列方法。我需要运行的方法因实例而异。

今天我的代码(使用该类)通常看起来像这样:

object_alpha = MyClass()
object_alpha.method1()
object_alpha.method2()
object_alpha.method3(arg1)
object_alpha.method4()

object_bravo = MyClass()
object_bravo.method1()
object_bravo.method3(arg1)
object_bravo.method4()
object_bravo.method5()

我知道上面的例子不是方法链接的例子。方法链接目前不可能,因为方法不返回类的对象。

这种格式有点重复,单调乏味,特别是对于长描述性变量名称。我的主要抱怨是我觉得它不太可读。

我想改变我的类以从每个方法调用返回一个新对象,这样我就可以进行方法链接。但是这些方法的副作用并没有改变类 - 它们通过API对数据库进行了更改,因此返回一个新对象会感觉很奇怪。

我的想法是创建一个将方法名称列表作为字符串的运行器类。所以我可以做这样的事情。

object_alpha = MyClass().runner([
    'method1',
    'method2',
    'method3(arg1)',
    'method4'
])

object_bravo = MyClass().runner([
    'method1',
    'method3(arg1)',
    'method4',
    'method5'
])

这是个坏主意吗?有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

你的想法很好,但它可以使用一个主要的改进:使用一个元组列表或类似的东西列表,而不是使用你必须评估的字符串列表,包含方法本身及其参数:

object_bravo = MyClass()
bravo_runner = [
    (object_bravo.method1, (arg1, arg2), {k1: v1, k2, v2}),
    (object_bravo.method2, (arg3), {}),
    (object_bravo.method3, (), {k3: v3}),
    (MyClass.method4, (object_bravo, arg4), {k4: v4})
]

运行它的方法比解析字符串容易得多:

for spec in bravo_runner:
    spec[0](*spec[1], **spec[2])

如果你使用namedtuple作为跑步者元素,它看起来会更好:

from collections import namedtuple
RunnerSpec = namedtuple('RunnerSpec', ['method', 'args', 'kwargs'])
object_bravo = MyClass()
bravo_runner = [
    RunnerSpec(object_bravo.method1, (arg1, arg2), {k1: v1, k2, v2}),
    RunnerSpec(object_bravo.method2, (arg3), {}),
    RunnerSpec(object_bravo.method3, (), {k3: v3}),
    RunnerSpec(MyClass.method4, (object_bravo, arg4), {k4: v4})
]

run方法:

for spec in bravo_runner:
    spec.method(*spec.args, **spec.kwargs)

<强>结论

此时,您实际上可以通过在类中为每个使用self而不是描述性对象名称的序列/方案编写方法来保存一些类型。这样可以最终节省你的时间,因为你会有预先构建的,命名的调用序列。无需将它们存储为列表。 bravo_object.run_scenario3()优于bravo_object.runner([big_ass_hard_to_read_list_that_is_basically_a_method_anyway]).run()

答案 1 :(得分:1)

基本上,您在这里尝试发明特定于域的语言。因为它的唯一目的是执行类似Python的东西,只需要不必命名上下文对象,我就不认为它值得麻烦。从一个方法返回一个对象以允许方法链接的模式,即使该对象不是操作的逻辑结果,实际上也不是闻所未闻的,所以我会去那。