Python。设计。以相同的方式扩展各种功能

Posted

技术标签:

【中文标题】Python。设计。以相同的方式扩展各种功能【英文标题】:Python. Design. Expanding various functions in identical way 【发布时间】:2021-06-04 21:06:40 【问题描述】:

我有以下设置。 我有 3 个函数,draw1、draw2 和 draw3。 所有这些都将图像和其他一些参数(不同参数用于各种绘制,但图像始终是参数之一)作为输入。

对于每个绘图函数(比如说 draw1),我想定义另一个具有以下属性的函数: 参数与draw1参数+布尔参数相同,称为“in_place”。 如果 in_place=True -> 使用 draw1 在图像上绘制并返回图像。 如果 in_place=False -> 复制图像并使用 draw1 在图像的副本上绘制并返回图像的副本。

draw1 的这种“扩展”与所有绘图函数相同。 我怎样才能以干净的方式做到这一点? 装饰器可以在这里使用吗? 提前致谢!

【问题讨论】:

【参考方案1】:

您可以创建一个工厂函数,从原始函数构建这些函数。它必须检查 in_place 关键字参数,决定将哪个目标用于绘制函数,然后调用它(原始参数减去 in_place)。

可能是:

def extend(draw):
    def extended(img, *args, **kwargs):
        # Default value for 'in_place': False
        # You can change it to True if you prefer
        in_place = kwargs.pop('in_place', False)
        if in_place:
            target = img
        else:
            target = img.copy()
        
        draw(target, *args, **kwargs)
        return target
    
    return extended

一些使用示例(为了清楚起见,我使用列表而不是图像):

我们的绘图函数:

def draw1(lst, color):
    lst.extend(['draw1', color])

def draw2(lst, shape, color):
    lst.extend(['draw2', shape, color])
    

我们使用以下方法创建扩展函数:

extended_draw1 = extend(draw1)
extended_draw2 = extend(draw2)

如果我们在没有in_place 参数的情况下调用它们,请使用默认值(这里是False,我们在副本上绘制)

orig = ['Hello']
out = extended_draw1(orig, 'red')
print(out)
# ['Hello', 'draw1', 'red']
print(orig)
# ['Hello']

如果 in_place 为False,则返回修改后的副本,原件不变

orig = ['Hello']
out = extended_draw1(orig, 'red', in_place=False)  # won't change the original
print(out)
# ['Hello', 'draw1', 'red']
print(orig)
# ['Hello']

如果in_place为True,则修改原来的

orig = ['Hello']
out = extended_draw1(orig, 'red', in_place=True)  # won't change the original
print(out)
# ['Hello', 'draw1', 'red']
print(orig)
# ['Hello', 'draw1', 'red']

更多,使用第二个函数:

print(extended_draw2(orig, 'square', 'blue'))
#['Hello', 'draw1', 'red', 'draw2', 'square', 'blue']
print(orig)
#['Hello', 'draw1', 'red']

print(extended_draw2(orig, 'square', 'blue', in_place=True))
#['Hello', 'draw1', 'red', 'draw2', 'square', 'blue']
print(orig)
#['Hello', 'draw1', 'red', 'draw2', 'square', 'blue']

【讨论】:

非常感谢另一位母亲的兄弟

以上是关于Python。设计。以相同的方式扩展各种功能的主要内容,如果未能解决你的问题,请参考以下文章

设计模式—“单一职责”

[设计模式] 设计模式课程--装饰模式

Javascript设计模式之装饰者模式详解篇

Decorate设计模式

设计模式之装饰模式

设计模式之动态代理模式