重构具有相同签名的多个函数的优雅方法?

Elegant way to refactor multiple functions that have same signatures?

我有两个接受相同(许多)参数的排序函数:

def sort_A(a, b, c, d, e):
    print('sorting A', a, c, b, d, e)
    hook()
    return 'sort A result'

def sort_B(a, b, c, d, e):
    print('sorting B', e, b, a, c, d)
    return 'sort B result'

def hook():
    print('HOOK')

a = 'a'
if a == 'a':
    sorter = sort_A
else:
    sorter = sort_B
sorter(a, 'b', 'c', 'd', 'e')

我不喜欢那些排序函数签名中的重复,所以我想出了两个解决方案:

  1. 制作一个 Sorter class 可以在其构造函数中接受这么多参数并将它们保存以供在方法中使用 sort_Asort_B。但是代码会被所有需要的 self 引用弄得一团糟,我认为这对于我的简单用例来说不值得。
  2. 创建某种工厂函数,如下所示,它接受许多参数,并通过这样做为其中定义的排序函数提供上下文。

但是解决方案 2 是一个好的做法吗?具体来说,像这样的工厂函数可以有一些其他的函数定义吗 在它的范围内?这似乎打破了单一职责原则——工厂函数不仅 returns 对象,而且还定义了它。 它在性能方面也可能不是最好的,因为在每次调用工厂函数时都会解释定义。

def get_sorter(a, b, c, d, e):
    def sort_A():
        print('sorting A', a, c, b, d, e)
        hook()
        return 'sort A result'

    def sort_B():
        print('sorting B', e, b, a, c, d)
        return 'sort B result'

    def hook():
        print('HOOK')

    if a == 'a':
        return sort_A
    return sort_B

sorter = get_sorter('a', 'b', 'c', 'd', 'e')
print(sorter())

你最好使用 类:

import abc
from dataclasses import dataclass


@dataclass
class Sorter:
    a: str
    b: str
    c: str
    d: str
    e: str

    @abc.abstractmethod
    def sort(self):
        """sort realization"""


@dataclass     
class SorterA(Sorter):
    @staticmethod
    def hook():
         print('HOOK')

    def sort(self):
        print('sorting A', self.a, self.c, self.b, self.d, self.e)
        self.hook()
        return 'sort A result'

 

@dataclass
class SorterB(Sorter):
    def sort(self):
        print('sorting B', self.e, self.b, self.a, self.c, self.d)
        return 'sort B result'

a = 'a'
sorter_class = SorterA if a == 'a' else SorterB
sorter = sorter_class(a, 'b', 'c', 'd', 'e')
print(sorter.sort())