__methods__ 是什么,为什么调用 __getattr__?
What is __methods__ and why is it calling __getattr__?
我最近尝试在我的几个 classes 上实现 "pass through" 以允许使用 __getattr__
方法调用 classes 的特定属性的方法.这破坏了 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)
当创建此 class 的实例然后尝试在 Ipython (0.12.1) 中完成制表符时,似乎调用了几个函数,包括 __methods__
、trait_names
和 _getAttributeNames
.
In [1]: my_class = MyClass()
In [2]: my_class.not_in_my_class<tab>
__methods__
trait_names
_getAttributeNames
我很想知道发生了什么。
谢谢,
P.S。我知道这样做是非常不透明的,而且是暂时的。不过,我很好奇。
更新
根据我从下面接受的答案中学到的知识,我已经能够成功 "pass through" 自动完成,因此 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 正在向您的对象询问其属性列表,并尝试了几种不同级别的模糊协议。 None 这些协议是核心 Python 语言的一部分(至少,不再是),当前的 IPython 源代码似乎已经删除了大部分这些检查。
__methods__
是 Python 的一个非常古老的部分,当他们 unified the type and class systems 回到 2.2 时就被淘汰了,大约 14 年以前。
过去,内置类型的实例会提供一个 __methods__
属性,该属性将是它们支持的所有方法的列表。这需要一个类型的实例,而它所属的系统有许多其他缺陷。
相比之下,用户定义的 classes 提供了您熟悉的现代 Python 内省系统,其中包含对象和 class __dict__
s。这比其他系统更强大、更一致,所以当他们统一类型和 classes 时,基于 class 的内省系统被保留,另一个被删除。
__methods__
现在几乎完全消失了。可能有一些第三方遗留代码仍然提供 __methods__
属性,但是 Python 附带的唯一仍然支持 __methods__
的东西似乎是 this weird thing in idlelib. In Python 2, dir
still tries to look for it,不过, IPython 的制表符完成使用 dir
,因此这就是 __methods__
访问的来源。还应该尝试访问 __members__
,由于消息出现在您键入的同一行上,您可能没有注意到。
_getAttributeNames
显然是由 PyCrust 引入的协议,替代 Python shell。如果已定义,_getAttributeNames
方法将提供对象通过 __getattr__
支持的所有动态属性的列表。 (这是在 __getattribute__
存在之前。)
_getAttributeNames
appears to have been introduced around 2001, making it newer than __methods__
, which disappeared around the same time frame. Some time since IPython 0.12.1, the _getAttributeNames
check has been removed from IPython.
trait_names
来自 Enthought Traits. For a class that uses traits, the trait_names
method is an instance method that returns a list of the names of its traits. It also accepts search criteria to list specific traits. Like _getAttributeNames
, this has been removed from IPython,显然是因为不需要检查来处理特征(不再?)。
我最近尝试在我的几个 classes 上实现 "pass through" 以允许使用 __getattr__
方法调用 classes 的特定属性的方法.这破坏了 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)
当创建此 class 的实例然后尝试在 Ipython (0.12.1) 中完成制表符时,似乎调用了几个函数,包括 __methods__
、trait_names
和 _getAttributeNames
.
In [1]: my_class = MyClass()
In [2]: my_class.not_in_my_class<tab>
__methods__
trait_names
_getAttributeNames
我很想知道发生了什么。
谢谢,
P.S。我知道这样做是非常不透明的,而且是暂时的。不过,我很好奇。
更新
根据我从下面接受的答案中学到的知识,我已经能够成功 "pass through" 自动完成,因此 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 正在向您的对象询问其属性列表,并尝试了几种不同级别的模糊协议。 None 这些协议是核心 Python 语言的一部分(至少,不再是),当前的 IPython 源代码似乎已经删除了大部分这些检查。
__methods__
是 Python 的一个非常古老的部分,当他们 unified the type and class systems 回到 2.2 时就被淘汰了,大约 14 年以前。
过去,内置类型的实例会提供一个 __methods__
属性,该属性将是它们支持的所有方法的列表。这需要一个类型的实例,而它所属的系统有许多其他缺陷。
相比之下,用户定义的 classes 提供了您熟悉的现代 Python 内省系统,其中包含对象和 class __dict__
s。这比其他系统更强大、更一致,所以当他们统一类型和 classes 时,基于 class 的内省系统被保留,另一个被删除。
__methods__
现在几乎完全消失了。可能有一些第三方遗留代码仍然提供 __methods__
属性,但是 Python 附带的唯一仍然支持 __methods__
的东西似乎是 this weird thing in idlelib. In Python 2, dir
still tries to look for it,不过, IPython 的制表符完成使用 dir
,因此这就是 __methods__
访问的来源。还应该尝试访问 __members__
,由于消息出现在您键入的同一行上,您可能没有注意到。
_getAttributeNames
显然是由 PyCrust 引入的协议,替代 Python shell。如果已定义,_getAttributeNames
方法将提供对象通过 __getattr__
支持的所有动态属性的列表。 (这是在 __getattribute__
存在之前。)
_getAttributeNames
appears to have been introduced around 2001, making it newer than __methods__
, which disappeared around the same time frame. Some time since IPython 0.12.1, the _getAttributeNames
check has been removed from IPython.
trait_names
来自 Enthought Traits. For a class that uses traits, the trait_names
method is an instance method that returns a list of the names of its traits. It also accepts search criteria to list specific traits. Like _getAttributeNames
, this has been removed from IPython,显然是因为不需要检查来处理特征(不再?)。