首页 > 解决方案 > 确保所有模块具有相同参数的模式?

问题描述

我正在用 Python 中的以下架构编写代码。基本上,它是一个模块化合成器,由“模块”元组组成。现在为简单起见,每个模块都是原子的(没有嵌套模块)。

每个模块包含两个参数,p1 和 p2。我想确保同一合成器中的每个模块都具有相同的 p1 和 p2 参数值。

这是一种方法,它有一些样板:

DEFAULT_P1 = ...
DEFAULT_P2 = ...

class Module:
    """
    Abstract base class.
    """

    def __init__(
        self, p1: int = DEFAULT_P1, p2: int = DEFAULT_P2
    ):
        self.p1 = p1
        self.p2 = p2


class ModuleK(Module):
    """
    A handful of submodules.
    """
    def __init__(
        self,
        ... other params
        p1: int = DEFAULT_P1,
        p2: int = DEFAULT_P2,
    ):
    super().__init__(p1=p1, p2=p2)
    ...


class Synth:
    """
    An abstract class for a modular synth, ensuring that all modules
    have the same sample and control rate.
    """

    def __init__(self, modules: Tuple[Module]):
        # Check that we are not mixing different control rates or sample rates
        for m in modules[:1]:
            assert m.p1 == modules[0].p1
            assert m.p1 == modules[0].p2

这是使用全局变量的更简洁的方法。我担心这可能会产生副作用,即不能在同一运行时拥有两个具有不同 p1 和 p2 的合成器,除非你做一些非常复杂和脆弱的事情。

DEFAULT_P1 = ...
DEFAULT_P2 = ...

class Module:
    """
    Abstract base class.
    """

    def __init__(
        self
    ):
        self.p1 = DEFAULT_P1
        self.p2 = DEFAULT_P2


class ModuleK(Module):
    """
    A handful of submodules.
    """
    def __init__(
        self,
        ... other params
    ):
    ...

我还考虑过从封装两个 p1 和 p2 的类继承。但是,您仍然需要检查同一个合成器中的所有模块是否都继承自同一种封装类。由于它只有两个参数,它不会以任何方式使事情更符合人体工程学。

有没有我错过的模式?

标签: pythoninheritancedesign-patterns

解决方案


“模块工厂”在这里可能会有所帮助。首先,上下文:

DEFAULT_P1 = 1
DEFAULT_P2 = 2

class Module:
    def __init__(self, p1: int = DEFAULT_P1, p2: int = DEFAULT_P2, **other_args):
        self.p1: int = p1
        self.p2: int = p2

class ModuleX(Module):  # May take other arguments other than p1 and p2
    pass

class ModuleY(Module):
    pass

然后:

class ModuleFactory:
    def __init__(self, module_p1: int = DEFAULT_P1, module_p2: int = DEFAULT_P2):
        self.module_p1: int = module_p1
        self.module_p2: int = module_p2

    def create_module_instance(self, module_class: type[Module], **other_args):
        return module_class(self.module_p1, self.module_p2, **other_args)

然后,使用它:

f = ModuleFactory(1, 2)
x_inst = f.create_module_instance(ModuleX, some_x_thing=1)
y_inst = f.create_module_instance(ModuleY, some_y_thing=2)

和值一次性提供给工厂p1p2然后在创建模块实例时自动提供。


推荐阅读