我最近尝试在我的几个类上实现"传递",以允许使用该__getattr__
方法调用类的特定属性上的方法.这已经在ipython中破坏了(类型)自动完成,我很想知道为什么.第一:
class MyClass(object): def __init__(): #create an instance of class ClassProperty self.class_property = ClassProperty() def __getattr__(self, item): #pass through calls to non-existent methods, print first print item return getattr(self.class_property,item)
当创建这个类的一个实例,然后试图制表完成在IPython中(0.12.1),似乎几个函数被调用,包括__methods__
,trait_names
和_getAttributeNames
.
In [1]: my_class = MyClass() In [2]: my_class.not_in_my_class__methods__ trait_names _getAttributeNames
我很想知道发生了什么.
谢谢,
PS我知道这样做是非常不透明的,而且是暂时的.不过,我很好奇.
UPDATE
基于我从下面接受的答案中学到的东西,我已经能够成功地"通过"自动完成,以便ClassProperty
现在存在于自动完成实例中的方法MyClass
.成功通过所需的是对该__dir__
方法的更新
class MyClass(object): def __init__(): #create an instance of class ClassProperty self.class_property = ClassProperty() def __getattr__(self, item): #pass through calls to non-existent methods, print first print item return getattr(self.class_property,item) def __dir__(self): dir_list = self.__dict__.keys() try: dir_list.extend(dir(self.class_property)) except: pass return dir_list
之所以我实现这个,是因为我们使用python作为带有ipython命令行界面的仪器控制包.我们有基于json配置文件选择执行器的设备(即激光器).为了方便用户,我们希望能够对执行器上的方法进行顶级访问.
如果有关于我的方法的想法,以及我是否在接受任何问题,我会很好奇.
IPython正在向您的对象询问其属性列表,尝试了几种不同程度的默认设置.这些协议都不是核心Python语言的一部分(至少,不再是),而且当前的IPython源代码似乎已经删除了大部分这些检查.
__methods__
是一个非常古老的Python部分,当他们在大约14年前的2.2中统一类型和类系统时,它已被逐步淘汰.
过去,内置类型的实例将提供一个__methods__
属性,该属性将是它们支持的所有方法的列表.这需要一个类型的实例,它所属的系统有许多其他缺陷.
相比之下,用户定义的类提供了您熟悉现代Python的内省系统,包括对象和类__dict__
.这比其他系统更强大,更一致,因此当它们统一类型和类时,基于类的内省系统被保留,另一个被删除.
__methods__
现在已经完全消失了.可能有一些第三方遗留代码仍然提供__methods__
属性,但仍然支持Python的唯一东西__methods__
似乎是在idlelib中这个奇怪的事情.在Python 2中,dir
仍然会尝试查找它,并且IPython的选项卡完成使用dir
,因此这是__methods__
访问来自的地方.还应该尝试访问__members__
,由于消息出现在您键入的同一行上,您可能没有注意到.
_getAttributeNames
是一个显然由PyCrust引入的协议,PyCrust是一个替代的Python shell.如果已定义,则_getAttributeNames
方法将提供对象支持的所有动态属性的列表__getattr__
.(这是以前__getattribute__
存在的.)
_getAttributeNames
似乎是在2001年左右推出,使它比__methods__
在同一时间框架内消失的更新.自IPython 0.12.1以来的一段时间,_getAttributeNames
检查已从IPython中删除.
trait_names
来自Enthought Traits.对于使用traits的类,该trait_names
方法是一个实例方法,它返回其特征名称的列表.它还接受搜索条件以列出特定特征.就像_getAttributeNames
,这已经从IPython中删除了,显然是因为不需要检查来处理特征(更多?).