简体   繁体   English

Python:带有装饰器的策略模式

[英]Python: Strategy pattern with decorators

I need to create an algorithm which is executed as a sequence of functions chosen at run-time, a bit like the strategy pattern.我需要创建一个算法,它作为在运行时选择的一系列函数来执行,有点像策略模式。 I want to avoid creating many single method classes (100+), but use simple functions, and assemble them using a decorator.我想避免创建许多单一的方法类(100+),而是使用简单的函数,并使用装饰器组装它们。

actions = []

def act(specific_fn):
    actions.append(specific_fn)
    return specific_fn


@act
def specific_fn1():
    print("specific_fn1")

@act
def specific_fn2():
    print("specific_fn2")

def execute_strategy():
    [f() for f in actions]

I have a couple of questions:我有一些问题:

  1. How can I modify the decorator function act to take the list actions as a parameter, so that it adds the decorated function into the list?如何修改装饰器函数act以将列表actions作为参数,以便将装饰函数添加到列表中?
  2. How do I use specific_fnX defined in another file?如何使用在另一个文件中定义的specific_fnX Currently, I just import the file inside the calling function - but that seems odd.目前,我只是在调用函数中导入文件 - 但这似乎很奇怪。 Any other options?还有其他选择吗?

Also, any other ideas on implementing this pattern?另外,关于实现这种模式的任何其他想法?

This is a pretty good tutorial on using decorators, both with and without arguments.是一个关于使用装饰器的非常好的教程,包括带参数和不带参数。 Others may know of others.其他人可能知道其他人。

The trick is to remember that a decorator is a function call, but when applied to a function definition, it magically replaces the function with the returned result.诀窍是记住装饰器是一个函数调用,但是当应用于函数定义时,它神奇地用返回的结果替换了函数。 If you want @my_decorator(my_list) to be a decorator, then my_decorator(my_list) must either return a function or an object with a __call__ method, and that function is then called on called on specific_fn1 .如果您希望@my_decorator(my_list)成为装饰器,则my_decorator(my_list)必须返回一个函数或具有__call__方法的对象,然后在调用specific_fn1调用该函数。

So yes, you need a function that returns a function that returns a function.所以是的,您需要一个返回函数的函数,该函数返回一个函数。 Looking at some examples in a tutorial will make this clearer.查看教程中的一些示例将使这一点更加清晰。

As to your second question, you can just call my_decorator(my_list)(specific_fn1) without using a decorator, and then ignorning the result.至于你的第二个问题,你可以在不使用装饰器的情况下调用my_decorator(my_list)(specific_fn1) ,然后忽略结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM