繁体   English   中英

如何在Python中动态定义类型/类?

[英]How to define a type/class in Python dynamically?

C中 ,如果我想根据名称定义类型,则可以使用预处理器。 例如,

#define DEFINE_STRUCT(name)        \
    struct My##name##Struct        \
     {                             \
        int integerMember##name;   \
        double doubleMember##name; \
     }

然后我可以像这样定义一个具体的结构

DEFINE_STRUCT(Useless);

并像这样使用Useless结构

struct MyUseslessStruct instance;

所以我的问题是

  • 有办法在Python中实现吗?

我有以下课程

class ClassName(SQLTable):
    items = []
    def __init__(self, value):
        SQLTable.__init__(self)
        # some common code
        if value in self.items:
            return
        self.items.append(value)

对于每个ClassNameitems的内容将有所不同,所以我想

def defineclass(ClassName):
    class <Substitute ClassName Here>(SQLTable):
        items = []
        def __init__(self, value):
            SQLTable.__init__(self)
            # some common code
            if value in self.items:
                return
            self.items.append(value)

我不想一遍又一遍地重复代码,如果可能的话,我想生成它。

您非常接近:

def defineclass(ClassName):
    class C(SQLTable):
        items = []
        def __init__(self, value):
            SQLTable.__init__(self)   
            # some common code
            if value in self.items:
                return
            self.items.append(value)
    C.__name__ = ClassName
    return C

如您所见,可以使用占位符名称定义它,然后分配其__name__属性。 之后,将其返回,以便您可以根据需要在客户端代码中使用它。 请记住,Python类是一个与其他对象一样多的对象,因此您可以return它,将其存储在变量中,将其放入字典中,或者定义它后随便使用。

__name__属性很方便,主要是因为错误消息__name__意义。 您可能实际上并不需要为每个类赋予唯一的名称。

此特定用例的替代方法是使用子类化:

class Base(SQLTable):
    def __init__(self, value):
        SQLTable.__init__(self)   
        # some common code
        if value in self.items:
            return
        self.items.append(value)

class Thing1(Base): items = []
class Thing2(Base): items = []

通过不在基类上定义items ,可以确保必须将其子类化,并定义每个类的items才能实际使用该类。

kindall的答案非常明确,可能更可取,但是有一个内置函数可以生成类: type 当使用一个参数调用时,它返回对象的类型。 当使用三个参数调用时,它将生成一个新的类型/类。 参数是类名称,基类和类字典。

def custom_init(self, value):
    SqlTable.__init__(self)
    if value in self.items:
        return
    self.items.append(value)

def defineclass(classname):
    #           __name__   __bases__    __dict__
    return type(classname, (SQLTable,), { '__init__': custom_init,
                                          'items': [] })

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM