什么是\uuuMethods_Uu,它为什么要调用?getattr?

2024-06-26 12:33:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我最近尝试在我的一些类上实现一个“传递”,以允许使用__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和{}。在

^{pr2}$

我很想知道发生了什么。在

谢谢

另外,我知道这样做是非常不透明的,是暂时的。不过,我还是很好奇。在

更新

根据我从下面接受的答案中了解到的,我已经能够成功地“传递”自动完成,因此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配置文件选择执行器的设备(即激光器)。为了方便用户使用,我们希望在执行器上有顶级访问权限。在

我很想知道是否有人对我的方法有什么想法,以及我是否会在今后的道路上引发任何问题。在


Tags: 方法selfreturndefdirmyclasspropertypass
1条回答
网友
1楼 · 发布于 2024-06-26 12:33:23

IPython正在请求您的对象提供其属性的列表,尝试了几种不同级别的模糊协议。这些协议都不是核心Python语言的一部分(至少,不再是这样),当前的IPython源代码似乎已经删除了大部分这些检查。在


__methods__是Python的一个非常古老的部分,在大约14年前的2.2版本中被淘汰了。在

过去,内置类型的实例将提供一个__methods__属性,该属性是它们支持的所有方法的列表。这需要一个类型的实例,而它所属的系统还有许多其他缺陷。在

相比之下,用户定义的类提供了你在现代Python中熟悉的内省系统,对象和类__dict__s。这比其他系统更强大、更一致,因此当它们统一类型和类时,基于类的自省系统被保留,另一个则被删除。在

__methods__现在几乎完全消失了。可能有一些第三方遗留代码仍然提供__methods__属性,但是Python唯一一个仍然支持__methods__的东西似乎是this weird thing in idlelib。不过,在python2中,^{} still tries to look for it,而IPython的制表符补全使用dir,因此__methods__访问就是从这里来的。还应该尝试访问__members__,由于消息出现在您键入的同一行上,您可能没有注意到这一点。在


_getAttributeNames显然是pyrclast引入的一种协议,它是pythonshell的另一种选择。如果已定义,_getAttributeNames方法将提供对象通过__getattr__支持的所有动态属性的列表。(这是在__getattribute__存在之前。)

^{} appears to have been introduced around 2001,比同一时间段消失的__methods__更新。自从ipython0.12.1以来,^{} check has been removed from IPython。在


trait_names来自Enthought Traits。对于使用traits的类,^{} method是一个实例方法,它返回其traits名称的列表。它还接受搜索条件来列出特定的特征。像_getAttributeNamesthis has been removed from IPython,显然是因为不再需要检查来处理特征。在

相关问题 更多 >