从外部modu替换类

2024-04-20 11:54:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用我自己的实现NamedRoutine替换一个external module的整个类^{}。我希望外部模块使用我的重新定义,而不是原始类Instruction

为了尽可能具有最佳的兼容性,并且因为我不想重新键入Instruction类,所以重新定义的类继承自InstructionNamedRoutine实现是:

from qiskit.circuit.instruction import Instruction

from ._interfaces import interfaces


class NamedRoutine(Instruction, interfaces.NamedRoutine):
    def __init__(self, name: str, num_qubits: int, num_clbits: int, params):
        super().__init__(
            name=name, num_qubits=num_qubits, num_clbits=num_clbits, params=params
        )
        self.name = name

    @staticmethod
    def from_Routine(rout: Instruction) -> "NamedRoutine":
        named_routine = NamedRoutine(
            rout.name, rout.num_qubits, rout.num_clbits, rout.params
        )
        named_routine.definition = rout.definition
        return named_routine

    @staticmethod
    def from_Routine_and_name(rout: Instruction, name: str) -> "NamedRoutine":
        named_routine = NamedRoutine(
            name, rout.num_qubits, rout.num_clbits, rout.params
        )
        named_routine.definition = rout.definition
        return named_routine

    def inverse(self) -> "NamedRoutine":
        return NamedRoutine.from_Routine_and_name(
            super().inverse(), name="D-" + self.name
        )

如您所见,这两个类之间没有兼容性问题。NamedRoutine实现只是确保设置了正确的名称,添加了2个静态方法并重载了Instruction的一个方法,以相应地更改实例name属性

为了用我的NamedRoutine实现完全替换qiskit.circuit.instruction.Instruction的定义,我尝试在导入任何qiskit相关代码之前调用以下函数:

def _wrap_instruction_class():
    import qiskit.circuit.instruction
    from .NamedRoutine import NamedRoutine

    setattr(qiskit.circuit.instruction, "Instruction", NamedRoutine)
    setattr(qiskit.circuit, "Instruction", NamedRoutine)

注意:Instructionqiskit.circuit__init__.py文件中导入

当我成功地用自己的实现替换Instruction的定义时,这个方法几乎可以工作

我仍然面临的问题是:在导入qiskit.circuit.instruction时,执行^{}^{}模块的__init__.py文件,并用Instruction方法的原始定义加载大量的方法/类(因为它仍然没有被替换)

使用这个Instruction类的方法/函数/类的数量非常庞大,我不想逐一跟踪它们。此外,这个解决方案需要我在每次更新qiskit库之后检查是否需要“注入”更多的例程/函数/类

我还搜索了一个解决方案,从qiskit库中“取消”除Instruction类以外的所有内容,然后在修改Instruction类后重新导入所有相关部分,但似乎unimporting is not possible in Python

一种可能的解决方案是递归地导入qiskit库的所有包/模块,如果符号Instruction是在模块中定义的,则用我的定义替换它,但这需要从qiskit导入所有的模块。我的软件实际上并不受运行时的限制,但是在我的笔记本电脑上使用最新的SSD和一个相当干净(软件包数量较少)的虚拟环境大约需要4秒钟,而且可能需要更多的时间,这取决于机器上安装的软件包

你们有没有其他的解决方案,可能比迭代所有的模块来找到qiskit中定义了Instruction符号的模块并替换它更有效


Tags: 模块namefrom定义defnumnamedqiskit