ipython 或 jupyter 中的制表符补全会寻求什么以建议替代方案?

What does tab completion in ipython or jupyter seek in order to suggest alternatives?

我很困惑为什么这个例子:

import attr

@attr.s
class SomeClass(object):
    a_number = attr.ib(default=42)

b = SomeClass(7)
当在此处输入 tab 时,

提供 a_number 作为唯一选择:

b.<tab>

但在这个例子中:

from attrdict import AttrDict
a = AttrDict(dict(a_number=7))  # Edited. was anumber originally

提供了多种选择,但 a_number 不是其中之一:

a.<tab>

能否以某种方式更改第二个示例以允许 ipythona_number 显示为属性?

在每种情况下,a.a_numberb.a_number 的计算结果都是 7。因此它们的行为似乎都具有 a_number 属性。

ipython 使用名为 dir 的 python 内置函数进行自动补全。对于一个对象,dir 意味着 return 对象的属性,对象的 class 和 classes 基础的属性。默认情况下,如果 dir(obj) 的结果以下划线开头,它还会排除任何条目,除非您先输入了下划线。但是,一旦您开始弄乱 __getattribute____getattr__dir 可能不再找到所有有效属性。这是因为您正在使用 Python 获取属性的机制,而 dir 并非无所不知。

在您的第一个示例中,anumber 是 class 的属性,因此通常由 dir 报告。

在您的第二个示例中,您使用了 AttrDict,它 确实__getattr__ 混淆了。事实上,它几乎完全委托给 __getitem__。因此,您的字典的所有键似乎也可作为属性使用。但是,它没有实现 __dir__,因此 dir 的默认实现没有意识到 AttrDict 的键应该在 return 值中报告 dir。因此,ipython 不知道这些属性是否可用。

如果你 subclass AttrDict 你可以让自动完成再次工作。例如

class MyAttrDict(AttrDict):
   def __dir__(self):
       super_dir = super().__dir__()
       string_keys = [key for key in self if type(key) is str]
       return super_dir + [key for key in string_keys if key not in super_dir]

>>> obj = MyAttrDict(something='value')
>>> obj.some<tab>
>>> obj.something