gpt4 book ai didi

惰性可调用的 Python 依赖注入(inject)

转载 作者:太空宇宙 更新时间:2023-11-03 16:17:25 24 4
gpt4 key购买 nike

在有趣的编程中,我注意到管理依赖项感觉就像是一件我想尽量减少的无聊苦差事。 After reading this ,我想出了一个 super 简单的依赖注入(inject)器,通过字符串键查找依赖实例:

def run_job(job, args, instance_keys, injected):
args.extend([injected[key] for key in instance_keys])
return job(*args)

这个廉价的技巧很有效,因为我的程序中的调用总是在迭代器中延迟定义(其中函数句柄与其参数分开存储),例如:

jobs_to_run = [[some_func, ("arg1", "arg2"), ("obj_key",)], [other_func,(),()]]

原因是中央主循环必须安排所有事件。它具有对所有依赖项的引用,因此 "obj_key" 的注入(inject)可以在 dict 对象中传递,例如:

# inside main loop
injection = {"obj_key" : injected_instance}
for (callable, with_args, and_dependencies) in jobs_to_run:
run_job(callable, with_args, and_dependencies, injection)

因此,当事件发生(用户输入等)时,主循环可能会对特定对象调用 update() ,该对象对该输入使用react,进而构建作业列表让主循环在有资源时进行调度。对我来说,关键引用任何依赖项供其他人注入(inject),而不是让所有对象形成直接关系,会更干净。

因为我懒惰地定义了 game clock engine to run them on its own accord 的所有可调用对象(函数) ,上述朴素的方法几乎没有增加任何复杂性。尽管如此,必须通过字符串引用对象仍然存在代码问题。同时,传递依赖关系也很糟糕,并且 constructor or setter injection将是矫枉过正,也许最大的dependency injection libraries .

对于在可调用对象中注入(inject)依赖关系的特殊情况(惰性定义的),是否有更具表现力的设计存在模式吗?

最佳答案

I've noticed that managing dependencies feels like a boring chore that I want to minimize.

首先,您不应该假设依赖项注入(inject)是最小化依赖项管理工作的一种方法。它不会消失,只是推迟到另一个地点和时间,并可能委托(delegate)给其他人。

也就是说,如果您正在构建的内容将被其他人使用,那么明智的做法是在您的“注入(inject)程序”中包含某种形式的版本检查,以便您的用户可以轻松地检查其版本是否匹配符合预期。

are there more expressive design patterns in existence?

据我了解,您的方法本质上是 Strategy-Pattern ,即作业的代码(可调用)依赖于调用几个具体对象之一的方法。你这样做的方式是完全合理的——它有效而且有效。

您可能希望将其更加形式化,以使其更易于阅读和维护,例如

from collections import namedtuple

Job = namedtuple('Job', ['callable', 'args', 'strategies'])

def run_job(job, using=None):
strategies = { k: using[k] for k in job.strategies] }
return job.callable(*args, **strategies)

jobs_to_run = [
Job(callable=some_func, args=(1,2), strategies=('A', 'B')),
Job(callable=other_func, ...),
]

strategies = {"A": injected_strategy, ...}
for job in jobs_to_run:
run_job(job, using=strategies)

# actual job
def some_func(arg1, arg2, A=None, B=None):
...

正如您所看到的,代码仍然执行相同的操作,但它立即更具可读性,并且它集中了有关 run_job 中 Job() 对象结构的知识。此外,如果传递了错误数量的参数,对诸如 some_func 之类的作业函数的调用也会失败,并且作业函数由于其明确列出和命名的参数而更容易编码和调试。

关于惰性可调用的 Python 依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38817923/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com