确保所有模块具有相同参数的模式?

Posted

技术标签:

【中文标题】确保所有模块具有相同参数的模式?【英文标题】:Pattern for ensuring all modules have same parameters? 【发布时间】:2021-04-13 10:50:52 【问题描述】:

我正在用 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 的类继承。但是,您仍然需要检查同一个合成器中的所有模块是否都继承自同一种封装类。由于它只有两个参数,因此不会以任何方式使事情更符合人体工程学。

有没有我遗漏的模式?

【问题讨论】:

不是每个模块都有自己的采样率和控制率,也许一个模块可以依赖于某种SynthContext类提供的这些值?似乎永远不会有这样的情况,您可以拥有一个模块而不将它也附加到合成器。 FWIW,我认为您的第一种方法很好。也就是说,我认为您希望在其中使用 for m in modules[1:]: 进行检查。 【参考方案1】:

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

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 值提供给工厂一次,然后在创建模块实例时自动提供。

【讨论】:

以上是关于确保所有模块具有相同参数的模式?的主要内容,如果未能解决你的问题,请参考以下文章

如何确保 Spring Boot 额外的 Jackson 模块具有相同的版本?

Dash Plotly 如何修复“所有参数应具有相同的长度。x 和 y”

“表中的错误(pred = 预测,true = W[, 8]):所有参数必须具有相同的长度”

R中的KNN——所有参数必须具有相同的长度,test.X为空

相同相机的内在参数相同?

Bigquery - UNION ALL 具有不同参数的相同查询