首页 > 解决方案 > 在使用 `types.new_class` 创建的类上设置模块

问题描述

我正在使用types.new_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

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

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

有没有办法在代码运行的模块中定义类?<class '__main__.Implementation'>在这个例子中就是这样。

标签: pythonpython-3.xtypesmetaprogramming

解决方案


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

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

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

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

推荐阅读