什么是在运行时创建Python类的最佳方法?

8

我正在使用一个ORM,它接受类作为输入,并且我需要能够提供一些动态生成的类。目前,我正在执行以下类似的虚构示例:

def make_cls(_param):
   def Cls(object):
       param = _param
   return Cls

A, B = map(make_cls, ['A', 'B'])

print A().foo
print B().foo

虽然这种方法可以正常工作,但感觉有些不对:例如,在repl上,两个类都被打印为<class '__main__.Cls'>。虽然名称的问题不是很大(我认为我可以通过设置__name__来解决它),但我想知道是否还有其他我不知道的问题。

所以我的问题是:是否有更好的动态创建类的方法,或者我的示例已经基本上很好了?


可能是 https://dev59.com/U2855IYBdhLWcg3wJQvT 的重复问题。 - cEz
3
如下所述,您可以使用“type”动态创建类。 此问题 的最佳答案详细解释了这一点。 - aganders3
"ORM是什么?使用哪个ORM?很有可能ORM会为您完成大部分工作。" - S.Lott
@S.Lott:我正在使用SQLAlchemy玩耍。不管怎样,我认为问题的根源并不在ORM中,而是在于我决定使用一堆具有相似模式的表格,而不是将它们捆绑在一个单独的表格中,这样会更加简单。 - hugomg
这就是开箱即用的方式。我不明白为什么普通的SQLAlchemy对你不起作用。 - S.Lott
显示剩余5条评论
1个回答

10

什么是类?它只是type的一个实例。例如:

>>> A = type('A', (object,), {'s': 'i am a member', 'double_s': lambda self: self.s * 2})
>>> a = A()
>>> a
<__main__.A object at 0x01229F50>
>>> a.s
'i am a member'
>>> a.double_s()
'i am a memberi am a member'

来自文档

type(name, bases, dict)

返回一个新的类型对象。实际上,这相当于类语句的动态形式。


由于“type”仅接收这3个参数,我可以安全地假设名称确实是出了问题的唯一原因,还是使用“type”的其他优点? - hugomg
1
一个不错的打包方式是将其封装在一个接受关键字参数的函数中,这样你就可以在函数调用中轻松指定新类的属性。 - kindall
@missingno 嗯,你的方法在创建一些复杂的类时可能很有用(例如,添加classmethod并使用type会很丑陋),但如果你需要在运行时构建一些复杂的东西,那么你的架构可能真的出了问题 :) type只是这种情况下的推荐解决方案。 - Roman Bodnarchuk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接