Генерация класса динамически из списка значений - PullRequest
2 голосов
/ 04 августа 2011

Скажем, у меня есть список словарей примерно так:

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

И я хочу создать для классов; один с именем Person с атрибутом title, установленным в «Person class», и другой класс с именем Employee, в котором title установлен в «Employee class». Имя класса может быть любым, но имена атрибутов, которые будут иметь класс, известны, в данном случае title.

Что я хочу закончить, так это новый список динамически создаваемых классов;

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

Я знаю, что вышеупомянутое не работает - и, возможно, это даже не имеет смысла. Но может ли это быть сделано как показано - присвоение метода, определенного в классе, другому классу?

Ответы [ 3 ]

1 голос
/ 04 августа 2011

Используйте встроенную функцию 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.sum: X.sum возвращает <unbound method X.sum> - функцию, которая «знает», что принадлежит классу X.Необработанная функция sum, как она была определена в классе, лежит в X.__dict__.Вы можете прочитать больше в Объединение типов и классов .

Но, тем не менее, убедитесь, что вам это нужно, и вы полностью понимаете, что здесь делаете.

1 голос
/ 04 августа 2011

Вы можете использовать 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'
0 голосов
/ 04 августа 2011

В 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...