【问题标题】:Set module on class created with `types.new_class`在使用 `types.new_class` 创建的类上设置模块
【发布时间】:2019-12-19 15:11:30
【问题描述】:

我正在使用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'>

有没有办法在代码运行的模块中定义类?在本例中为&lt;class '__main__.Implementation'&gt;

【问题讨论】:

  • 您只想在结果中分配__module__ 还是在exec_body 中分配?
  • @DavisHerring 既然提到了,其实就是这么简单。

标签: python python-3.x types metaprogramming


【解决方案1】:

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'>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-02
    • 2020-10-20
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    相关资源
    最近更新 更多