Вот надуманный игрушечный пример для запуска проблемы, с которой я сталкиваюсь:
У меня есть несколько классов, предположим, что они находятся в локальном файле «issue.py»:
class A(object):
def save(self):
# fancy stuff
pass
class B(A):
def save(self):
# misc stuff
super(B, self).save()
class C(B):
pass
Я использую их в сеансе IPython, возможно, так:
In [1]: %load_ext autoreload
In [2]: %autoreload 2
In [3]: from issue import A, B, C
In [4]: c = C()
In [5]: c.foo = 'whatever'
In [6]: c.save()
Все идет нормально. Но потом я понимаю, что есть ошибка в «причудливых вещах» класса А, и делаю там небольшое редактирование — может быть, даже просто добавляю немного логирования. Затем я хочу повторить save():
In [7]: c.save()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-6970514bfc33> in <module>()
----> 1 c.save()
/Users/scratch/Documents/dev2015/gensim_venv/src/gensim-develop/docs/notebooks/scratch~/issue.py in save(self)
7 def save(self):
8 # misc stuff
----> 9 super(B, self).save()
10
11 class C(B):
TypeError: super(type, obj): obj must be an instance or subtype of type
О, нет!. Страшный TypeError после перезагрузки классов, в то время как более старые экземпляры сохраняют некоторые старые суперклассы! Эта проблема обсуждается в SO и других местах, но четкого рецепта восстановления нет.
Но так получилось, что мне очень, очень хотелось бы иметь возможность запускать слегка обновленную версию A.save() на моем старом экземпляре c. (У меня есть более 20 ГБ данных в памяти, на создание которых у меня ушло около полутора дней, и которые будут сохранены предпочтительным способом с помощью метода суперкласса. Я сохранил достаточно других ручных методов, которые, я думаю, я "мог бы реконструировать c в перезапущенном ядре IPython. Но, хотя у меня все еще есть подлинный объект, я бы предпочел дать реалистичный тест пропатченному A.save() - возможно, даже сделать для него больше исправлений/тестов. перед полным перезапуском ядра.)
Так что меня интересуют любые тактики или уловки, какими бы неразумными они ни были в других ситуациях, для принуждения c к текущим определениям классов, вплоть до самого верха, чтобы c.save() просто работало.
Любые идеи?
Я ожидаю, что все, что работает для этого игрушечного примера, будет работать и в моей реальной установке, которая представляет собой IPython на основе CPython 2.7.10). (Однако в реальной ситуации эти три класса находятся в разных файлах.)
C, а затем вручную перезаписать его данные данными из старогоc? То, как это будет работать, зависит от того, какие данныеcхранит и как, но это первый подход, который приходит на ум. - person BrenBarn   schedule 12.07.2015c2даже в игрушечном примере, он получит ту же ошибку наc2.save(), поэтому его иерархия надклассов не будет фиксированной. (В моей реальной установке есть также аналогичная ошибка TypeError, влияющая на метод__init__C, который делает super() для__init__B. - person gojomo   schedule 12.07.2015