我想控制当用户在ipython中的自定义对象上使用制表符完成时出现哪些方法 - 特别是,我想隐藏我已弃用的函数。我仍然希望这些方法可以调用,但我不希望用户看到它们并在检查对象时开始使用它们。这是可能的吗?
答案 0 :(得分:4)
部分答案。我将发布示例代码,然后解释为什么它只是部分答案 代码:
class hidden(object): # or whatever its parent class is
def __init__(self):
self.value = 4
def show(self):
return self.value
def change(self,n):
self.value = n
def __getattr__(self, attrname):
# put the dep'd method/attribute names here
deprecateds = ['dep_show','dep_change']
if attrname in deprecateds:
print("These aren't the methods you're looking for.")
def dep_change(n):
self.value = n
def dep_show():
return self.value
return eval(attrname)
else:
raise AttributeError, attrname
所以现在需要注意的是:它们不是方法(注意缺少自我作为第一个变量)。如果您需要您的用户(或您的代码)能够在任何已弃用的方法上调用im_class,im_func或im_self,那么这个hack将无法工作。此外,我非常确定会因为你在__getattr__
内定义每个dep'd函数而受到性能影响。这不会影响您的其他属性查找(如果我将它们放在__getattribute__
中,那将是另一回事),但它会减慢对这些已弃用的方法的访问速度。这可以(很大程度上,但不是完全)通过将每个函数定义放在它自己的if块中而不是进行列表成员资格检查来否定,但是,根据你的函数有多大,这可能真的很难维护。
更新:
1)如果你想制作弃用的函数方法(你可以),只需使用
import types
return types.MethodType(eval(attrname), self)
而不是
return eval(attrname)
在上面的代码片段中,并将self添加为函数defs的第一个参数。它将它们变成实例方法(因此您可以将im_class,im_func和im_self用于您的内心)。
2)如果__getattr__
钩子没有激动你,那么还有另一种选择(我知道)(albiet,有自己的注意事项,我们会得到那些):放弃已弃用的函数定义在__init__
内,并使用自定义__dir__
隐藏它们。以上代码就是这样做的:
class hidden(object):
def __init__(self):
self.value = 4
from types import MethodType
def dep_show(self):
return self.value
self.__setattr__('dep_show', MethodType(dep_show, self))
def dep_change(self, n):
self.value = n
self.__setattr__('dep_change', MethodType(dep_change, self))
def show(self):
return self.value
def change(self, n):
self.value = n
def __dir__(self):
heritage = dir(super(self.__class__, self)) # inherited attributes
hide = ['dep_show', 'dep_change']
show = [k for k in self.__class__.__dict__.keys() + self.__dict__.keys() if not k in heritage + private]
return sorted(heritage + show)
这里的优点是你不会在每次查找时重新定义函数,这会让你加快速度。这里的缺点是,因为你不是每次查找都重新定义函数,所以它们必须“持久”(如果你愿意)。因此,虽然自定义__dir__
方法隐藏了dir(hiddenObj)
中已弃用的内容,因此隐藏了IPython的tab-completion,但它们仍然存在于实例的__dict__
属性中,用户可以在其中发现它们。
答案 1 :(得分:0)
在调用方法之前不会发出DeprecationWarning
,因此您必须在类上有一个单独的属性来存储已弃用方法的名称,然后在建议完成之前检查它。
或者,你可以在寻找DeprecationWarning
的方法中使用AST,但是如果在C中定义了类,或者方法可能发出{{} 1}}基于参数的类型或值。
答案 2 :(得分:0)
关于IPython中的完成机制,它在此处记录:
http://ipython.scipy.org/doc/manual/html/api/generated/IPython.core.completer.html#ipcompleter
但是一个非常有趣的例子是traits completer,它正是你想要做的:它隐藏了一些自动完成的方法(基于它们的名字)。
以下是代码:
答案 3 :(得分:0)
似乎有一个特殊的magic method用于由dir()调用的内省:__dir__()
。这不是你想要的吗?