Я хочу иметь возможность динамически загружать методы экземпляра во время создания объекта. Согласно моей схеме поведение по умолчанию закодировано в базовом классе. Однако если
определенные условия выполняются во время создания объекта, я динамически
измените это поведение с другим фрагментом кода. Вот как
Я делаю это:
Поведение по умолчанию закодировано в first.py
:
class First(object):
def __init__(self, p):
p = str(p)
#The decision whether or not to perform default action is done
#in the following try/except block. In reality this block
#is more complicated
#and more checks are performed in order to assure proper work
try:
strImport = "__import__('module%s')"%p
e = eval(strImport, {}, {})
if not hasattr(e, p):
raise ImportError()
except ImportError:
e = None #default behaviour
if e is not None:
self.act = getattr(e, p)(p).act #special behaviour
self.p = p
def act(self):
print 'Default behaviour'
import cPickle as pickle
if __name__ == '__main__':
print 'first'
first = First('f')
first.act()
pickle.dump(first, open('first.dump', 'w'))
print 'third'
third = First('Third')
third.act()
pickle.dump(third, open('third.dump', 'w'))
В приведенном выше коде и first
, и third
выполняют действия по умолчанию. Я могу изменить
поведение third
путем добавления файла moduleThird.py
следующим образом:
from temp import First
class Third(First):
def __init__(self, p):
p = 'Third *** %p'
print 'third init'
super(self.__class__, self).__init__(p)
def act(self):
super(self.__class__, self).act()
print 'Third acted'
После добавления этого файла third
меняет свое поведение. Однако я не
не удалось засечь получившийся объект из-за следующей ошибки:
Traceback (most recent call last):
File "C:\temp\temp.py", line 35, in <module>
pickle.dump(fff, open('fff.dump', 'w'))
File "C:\Python26\lib\copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle instancemethod objects
Понятно, что метод динамической загрузки Third.act
вызывает проблемы с рассолом. Как мне изменить свой подход, чтобы получить выбираемые объекты (и более элегантный код тоже)?
Есть ли лучший способ достичь моей цели?