Хороший способ редактировать предыдущий определенный класс в 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