如何在Python中动态定义一个type/class?
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
class ClassName(SQLTable):
items = []
def __init__(self, value):
SQLTable.__init__(self)
# some common code
if value in self.items:
return
self.items.append(value)
对于每个ClassName
,items
的内容会有所不同,所以我想要
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__
属性。之后,你 return 它这样你就可以在你的客户端代码中随意使用它。请记住,Python class 与任何其他对象一样都是一个对象,因此您可以 return
它,将其存储在变量中,将其放入字典或任何您喜欢的东西一次你已经定义了它。
__name__
属性很方便,主要是让错误消息有意义。您实际上可能不需要给每个 class 一个唯一的名称。
此特定用例的替代方法可能是使用 subclassing:
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 = []
通过不在基础 class 上定义 items
,您确保必须子class 它并定义一个 per-class items
到实际上 使用 class.
kindall 的回答非常清楚并且可能更可取,但是有一个内置函数可以生成 classes:type
。当使用一个参数调用时,它 returns 对象的类型。当使用三个参数调用时,它会生成一个新的 type/class。参数是 class 名称、基础 classes 和 class 字典。
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': [] })
在 C 中,如果我想根据名称定义类型,我可以使用预处理器。例如,
#define DEFINE_STRUCT(name) \
struct My##name##Struct \
{ \
int integerMember##name; \
double doubleMember##name; \
}
然后我可以像这样定义一个具体的结构
DEFINE_STRUCT(Useless);
并像这样使用 Useless
结构
struct MyUseslessStruct instance;
所以我的问题是
- 有没有办法在 Python 中实现这一点?
我有以下class
class ClassName(SQLTable):
items = []
def __init__(self, value):
SQLTable.__init__(self)
# some common code
if value in self.items:
return
self.items.append(value)
对于每个ClassName
,items
的内容会有所不同,所以我想要
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__
属性。之后,你 return 它这样你就可以在你的客户端代码中随意使用它。请记住,Python class 与任何其他对象一样都是一个对象,因此您可以 return
它,将其存储在变量中,将其放入字典或任何您喜欢的东西一次你已经定义了它。
__name__
属性很方便,主要是让错误消息有意义。您实际上可能不需要给每个 class 一个唯一的名称。
此特定用例的替代方法可能是使用 subclassing:
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 = []
通过不在基础 class 上定义 items
,您确保必须子class 它并定义一个 per-class items
到实际上 使用 class.
kindall 的回答非常清楚并且可能更可取,但是有一个内置函数可以生成 classes:type
。当使用一个参数调用时,它 returns 对象的类型。当使用三个参数调用时,它会生成一个新的 type/class。参数是 class 名称、基础 classes 和 class 字典。
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': [] })