【问题标题】:Dynamic class definition with methods from multiple modules具有来自多个模块的方法的动态类定义
【发布时间】:2021-05-24 14:33:17
【问题描述】:

我尝试使用在多个模块中定义的相当广​​泛的方法来创建类。我需要一些包装器来确保与其他类的兼容性,并且不能大大改变我的模块。这是一个最小示例的尝试:


让我的(许多)模块类似于:

"""moduleA.py"""
def print_something(text):
    print(f"Here is some output from module A: {text}")

这个例子只需要一秒钟:

"""moduleB.py"""
def print_something(text):
    print(f"Here is some output from module B: {text}")

如果我围绕许多这样的模块构建动态类定义,我的方法的分配不会像希望的那样工作:

import os
import re
from importlib import import_module

# create class for every pyd-module in current working directory
cwd = os.getcwd()
for fileName in os.listdir(cwd):
    if re.search('module.+\.py', fileName):
        moduleName = re.split('\.', fileName)[0]
        module = import_module(moduleName)

        # wrapper does something needed
        def print_wrapper(self, text):
            module.print_something(text.upper())

        className = 'ClassM'+moduleName[1:]
        dynamicClass = type(className, (object, ), {
            "print_something": print_wrapper})
        # register dynamic class for use
        globals()[dynamicClass.__name__] = dynamicClass

instanceA = ClassModuleA()
instanceA.print_something("testA")
instanceB = ClassModuleB()
instanceB.print_something("testB")

输出(仅来自模块 B,而不来自模块 A):

Here is some output from module B: TESTA
Here is some output from module B: TESTB

我尝试使用复制操作,但它们不适用于 builtin_function_or_method(s)。 (看: How to get builtin_function_or_method objects copied in ram without wrapping?How can I make a deepcopy of a function in Python?)

有没有办法解决这个问题?

【问题讨论】:

    标签: python class methods copy


    【解决方案1】:

    与 Cython 无关。在这种情况下,也值得使用纯 Python 进行测试(即“最小化”您的最小可重现示例)。

    def print_wrapper(self, text):  # wrapper does something needed
        module.print_something(text.upper())
    

    这表示“在全局范围内查找module 的当前值并调用其属性print_something”。 module 的当前值在函数被调用的那一点进行评估,因此它始终是循环中的最后一个值。

    有许多技术可以在定义时捕获变量,但一种选择可能是

    def print_wrapper(self, text, local_module=module):  # wrapper does something needed
        local_module.print_something(text.upper())
    

    if re.search('.pyd', fileName): 行中,您知道. 在正则表达式中具有特殊含义,对吧?

    【讨论】:

    • 非常感谢!有道理并且工作正常。我在那里不必要地不知所措。我用 cython 简化了我的例子以避免混淆其他人并纠正了不相关的正则表达式错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    相关资源
    最近更新 更多