Хороший способ редактировать предыдущий определенный класс в ipython
Мне интересно, как лучше следовать, если я хочу переопределить членов предыдущего определенного класса в ipython.
сказать:
Я определил вступление класса, как показано ниже, а позже я хочу переопределить часть определения функции _print_api. Любой способ сделать это без повторного ввода.
class intro(object):
def _print_api(self,obj):
def _print(key):
if key.startswith('_'):
return ''
value = getattr(obj,key)
if not hasattr(value,im_func):
doc = type(valuee).__name__
else:
if value.__doc__ is None:
doc = 'no docstring'
else:
doc = value.__doc__
return ' %s :%s' %(key,doc)
res = [_print(element) for element in dir(obj)]
return '\n'.join([element for element in res if element != ''])
def __get__(self,instance,klass):
if instance is not None:
return self._print(instance)
else:
return self._print_api(klass)
Ответы
Ответ 1
Используйте команду% edit или ее псевдоним% ed. Предполагая, что класс intro уже существует в пространстве имен ipython, введите %ed intro
, чтобы открыть внешний редактор исходного кода для класса. Когда вы сохраняете и выходите из редактора, код будет выполняться с помощью ipython, эффективно переопределяя класс.
Недостатком этого является то, что все существующие экземпляры все равно будут привязаны к старой версии класса - если это проблема, вам нужно либо воссоздать объекты, либо повторно назначить класс obj. , чтобы указать на новую версию класса.
Вы также можете использовать %ed
для модулей, файлов и предыдущих строк ввода, например. %ed 5 10:13 16
создаст и отредактирует файл, состоящий из входных строк ipython 5,10,11,12,13,16.
Ответ 2
Если вы используете функции редактирования IPython%, вы можете использовать что-то вроде this
Ответ 3
На самом деле нет "хорошего" способа сделать это. Лучшее, что вы можете сделать, это что-то вроде этого:
# class defined as normally above, but now you want to change a funciton
def new_print_api(self, obj):
# redefine the function (have to rewrite it)
...
# now set that function as the _print_api function in the intro class
intro._print_api = new_print_api
Это будет работать, даже если у вас уже есть встроенные объекты (т.е. когда вы вызываете introObject._print_api на уже созданном объекте, он будет вызывать новую установленную вами функцию). К сожалению, вам все равно придется переопределять функцию, но по крайней мере вам не нужно переписывать весь класс.
В зависимости от вашего прецедента лучше всего иметь его в отдельном модуле. import
класс и, когда вам нужно что-то изменить, просто используйте функцию reload()
. Однако это не повлияет на предыдущие экземпляры класса (это может быть или не быть тем, что вы хотите).
Ответ 4
Когда вы дойдете до того, что у вас есть такой код, проще всего просто поместить его в файл и import
в этот конкретный модуль. Затем, когда вам нужно обновить, вы можете отредактировать файл и повторно запустить оператор import
, и вы получите обновленный код, хотя ранее определенные объекты не получат обновления.
Ответ 5
Я столкнулся с проблемами при использовании магии %edit
для классов и получил ту же ошибку, о которой говорилось в предыдущих комментариях:
WARNING: The file 'None' where '<class '__main__.intro'>' was defined cannot be read.
Если вы сделаете %edit intro._print_api
(или любой другой метод в вашем классе), вы можете обойти проблему и отредактировать определение класса, поскольку редактируемая вами функция определяется в определении класса, вы получите полный класс в своем классе. $EDITOR
.
К сожалению, у меня недостаточно репутации, чтобы комментировать, поэтому мне пришлось опубликовать новый ответ. Извините за это, но я надеюсь, что это поможет кому-то!: D