Поскольку приятно узнать о динамических функциях Python, вот как вы можете сделать это «волшебным образом».Хотя в реальном коде делать подобные вещи не очень хорошая идея - он хрупок и может привести к неожиданному поведению.Также помещает данные в имена переменных , что является плохой привычкой.
Кроме того, вы не можете делать то, что хотите, потому что есть проблема с последовательностью операций.В частности, когда вы определяете Record
, вы еще не можете определить его подклассы (очевидно).Таким образом, вы не можете в этот момент применить диспетчерскую логику в классе.Но нет другого особенного времени, когда вы можете сказать: «теперь мы закончили определение подклассов, настроили диспетчеризацию», поэтому вы должны жестко закодировать его в свой исходный код после всех определений подкласса.Тогда вы можете так же жестко закодировать диктовку, как и в моем другом ответе.
В любом случае, с этим отказом от ответственности, вот магия.(Это работает только для классов нового стиля.)
@classmethod
def update_record_types(cls):
cls.records = {c.__name__.upper(): c for c in cls.__subclasses__()}
Тогда Record.__init__
просто ссылается на атрибут класса records
, который вы можете обновить в любое время, вызвав Record.update_record_types()
.
РЕДАКТИРОВАТЬ: я думаю, я должен указать, как это использовать!
>>> class Record(object):
... @classmethod
... def update_record_types(cls):
... cls.records = {c.__name__.upper(): c for c in cls.__subclasses__()}
...
>>> # define some record types, each with their own __init__
>>> class sen_record(Record): pass
>>> class dsp_record(Record): pass
>>> class uso_record(Record): pass
>>>
>>> # update the listing of record types
>>> Record.update_record_types()
>>>
>>> # look up the one you want
>>> Record.records["SEN_RECORD"]
<class '__main__.sen_record'>