在ipython中有效编辑已定义类的方法

19 投票
6 回答
8376 浏览
提问于 2025-04-15 21:17

我想知道在ipython中,如果我想重新定义一个之前定义的类的成员,有什么好的方法。比如说:

我已经定义了一个叫做intro的类,如下所示,后来我想重新定义其中一个函数 _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)

6 个回答

0

其实没有一个“好”的方法来做到这一点。你能做的最好的就是像这样:

# 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

这样做即使你已经定义了 intro 对象也能正常工作(也就是说,当你在一个已经创建的对象上调用 introObject._print_api 时,它会调用你设置的新函数)。不过,遗憾的是,你还是需要重新定义这个函数,但至少你不需要重写整个类。

根据你的具体需求,最好的做法可能是把它放在一个单独的模块里。你可以 import 这个类,当你需要修改某些东西时,只需使用 reload() 函数。不过,这样做不会影响之前的类实例(这可能是你想要的,也可能不是)。

7

如果你使用IPython的%edit功能,你可以试试像这个这样的东西。

13

使用 %edit 命令,或者它的别名 %ed。假设在 ipython 的命名空间中已经有了一个叫 intro 的类,输入 %ed intro 就会打开一个外部编辑器,让你编辑这个类的源代码。当你保存并退出编辑器后,ipython 会执行这些代码,实际上就是重新定义了这个类。

不过,这样做有个缺点,就是之前已经创建的实例仍然会使用旧版本的类。如果这对你来说是个问题,那你需要重新创建这些对象,或者把对象的 class 属性重新指向新版本的类。

你也可以对模块、文件和之前的输入行使用 %ed,比如 %ed 5 10:13 16 会创建并编辑一个文件,这个文件包含了 ipython 输入的第 5 行、10 行到 13 行,以及第 16 行的内容。

撰写回答