【问题标题】:Generating class dynamically from a list of values从值列表动态生成类
【发布时间】:2011-08-04 19:37:12
【问题描述】:

假设我有一个这样的字典列表:

[
    dict(name='Person', title='Person class'), 
    dict(name='Employee', title='Employee class') 
]

我想创建类;一个名为 Person 的属性标题设置为“Person class”,另一个名为 Employee 的类的标题设置为“Employee class”。类的名称可以是任何名称,但类将具有的属性的名称是已知的,在本例中为标题。

我最终想要的是一个动态创建的类的新列表;

classes = [Person, Employee]

好像这个类是手动定义的:

class Person:
    title = 'Person class'

可以像这样实例化:

>>> x = classes[0]()
>>> print x.title
"Person class"

好像这还不够糟糕,我想将在不同类中定义的方法分配给动态创建的类:

class X:
    def sum(self, a, b):
        print self
        return a+b

>>> x = X()
>>> x.sum(1,2)
__main__.x
3

>>> classes[0].sum = X.sum
>>> classes[0].sum(1,2)
__main__.Person
3

我知道上面的方法行不通 - 也许它甚至没有意义。但它可以做到吗 - 将一个类中定义的方法分配给不同的类?

【问题讨论】:

  • 真正想做什么?

标签: python class dynamic


【解决方案1】:

使用内置函数type():

>>> d
[{'name': 'Person', 'title': 'Person class'}, {'name': 'Employee', 'title': 'Employee class'}]
>>> types = [type(x['name'], (object,), {'title': x['title']}) for x in d]
>>> types[0]()
<__main__.Person object at 0x800f5fad0>
>>> types[0]().title
'Person class'

第二个问题的修改:

>>> class X(object):
...     def sum(self, a, b):
...         print self
...         return a+b
...
>>> types = [type(x['name'], (object,), {'title': x['title'], 'sum': X.__dict__['sum']}) for x in d]
>>> types[0]().sum(1,2)
<__main__.Person object at 0x800f5fad0>
3

请注意,为什么 X.__dict__['sum'] 而不是 X.sumX.sum 返回 &lt;unbound method X.sum&gt; - 函数“知道”它属于 X 类。原始函数sum 在类中定义,位于X.__dict__ 中。您可以在Unifying types and classes阅读更多内容。

但是,请确保您需要它并且您完全了解这里的操作。

【讨论】:

  • 啊,这似乎是我要找的。谢谢! :-)
  • 这不是返回对象的实例而不是类吗?如果是这样,我认为标题需要更改。
【解决方案2】:

你可以使用type函数:

>>> d = [
...     dict(name='Person', title='Person class'), 
...     dict(name='Employee', title='Employee class') 
... ]
>>> t = [type(i["name"], (object,), i) for i in d]
>>> t
[<class '__main__.Person'>, <class '__main__.Employee'>]
>>> t[0].title
'Person class'
>>> t[1].title
'Employee class'

【讨论】:

    【解决方案3】:

    Python中有一个很棒的type()函数,它既可以返回一个变量的类型,也可以创建一个新的类型,例如:

    Person = type('Person', (object, ), { 'name' : 'Alex', 
                                          'last_name' : 'Black' } )
    
    Employee = type('Employee', (Person, ), { 'job' : 'Programmer' } )
    

    http://docs.python.org/library/functions.html#type

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-23
      • 1970-01-01
      • 2015-12-05
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 2020-10-29
      • 1970-01-01
      相关资源
      最近更新 更多