我有一个对设备测量进行操作的Python代码。在一节中,我必须将匹配网络应用于测量。我正在使用 Scikit Rf 模块处理与射频测量相关的所有内容,并且正在使用我需要的东西创建电路,然后使用 .network 属性从电路中提取网络,并将其替换为我的对象的网络属性。 这个操作非常慢,我想通过并行进行多个匹配来加快速度。请注意,此操作是逐个元素完成的,没有任何内容反馈到主循环或任何其他内容,唯一更新的是我的对象的 .network 属性(这是一个 rf.Network)。
我尝试了以下方法(chatGPT 建议):
def process_element(element, matching_network):
return element.apply_matching(matching_network)
with multiprocessing.Pool(processes=8) as pool:
pool.starmap(process_element, [(element, matching_network) for element in list_measurements])
我知道 apply_matching() 方法有效,因为我已经对其进行了广泛的测试,但多重处理却无效。当我绘制测量结果时,我发现它们不匹配,因此原始响应和匹配响应之间的替换没有发生。
编辑:我不是一个非常熟练的编码员,这是我第一次使用这种多重处理,所以请注意这一点。与此同时,我正在尝试就该主题记录自己,但由于我在工作中需要这段代码,所以我需要完成它。
无论如何,为了将其分解为最简单的形式,我需要将一个方法(apply_matching)应用于具有一组参数(matching_network)的对象(元素)。 Matching_network 在代码执行过程中不会改变。 该方法执行一些操作,然后使用新值修改对象的一个属性。
我绝对可以返回需要更改特定属性的值,但随后我就迷失了方向
您将在父进程中执行的循环中处理更改 - 一个独立的示例:
import dataclasses
import multiprocessing
def process_element(task):
element, matching_network = task # need to unpack by hand so we can use imap
element.foo = 123 # this won't propagate
return {"bar": matching_network[element.id]}
@dataclasses.dataclass
class Element:
id: int
foo: int = 0
bar: int = 0
def main():
list_measurements = [
Element(1),
Element(2),
Element(3),
]
matching_network = {2: "two", 1: "yksi", 3: "drei"}
with multiprocessing.Pool(processes=8) as pool:
for element, changes in zip(
list_measurements,
pool.imap(
process_element,
[(element, matching_network) for element in list_measurements],
),
):
for key, value in changes.items():
setattr(element, key, value)
print(list_measurements)
if __name__ == "__main__":
main()
打印出:
[Element(id=1, foo=0, bar='yksi'), Element(id=2, foo=0, bar='two'), Element(id=3, foo=0, bar='drei')]
所以你可以知道
bar
已被映射,但 foo
没有(如你所注意到的)。