在使用 `types.new_class` 创建的 class 上设置模块

Set module on class created with `types.new_class`

我正在使用 types.new_class 动态创建 classes。到目前为止一切进展顺利。唯一不方便的是 class 创建的模块是 abc,至少在涉及 abc.ABCMeta 时是这样。考虑以下人为的示例:

import abc
import types

class Base(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def method(self, x):
        pass

def generate_a_class(name):
    def method(self, x):
        print(f"Method recieved {x}")

    class_body = {method.__name__: method}
    NewClass = types.new_class(
        name, bases=(Base,), exec_body=lambda ns: ns.update(class_body))

    return NewClass

然后我们打印这个方法生成的class:

print(generate_a_class("Implementation"))
# Prints <class 'abc.Implementation'>

有没有办法在代码为运行的模块中定义class?在本例中为 <class '__main__.Implementation'>

Davis Herring 的评论是我所需要的;直接在 class 主体中分配模块。这样代码看起来像:

import abc
import types
import sys

class Base(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def method(self, x):
        pass

def generate_a_class(name, module:str = None):
    def method(self, x):
        print(f"Method recieved {x}")

    class_body = {
      "__module__": __name__ if module is None else module,
      method.__name__: method,
    }
    NewClass = types.new_class(
        name, bases=(Base,), exec_body=lambda ns: ns.update(class_body))

    return NewClass

并且 class 与正确的模块相关联。

print(generate_a_class("Implementation"))
# Prints <class '__main__.Implementation'>