首页 > 解决方案 > python jedi,动态属性的自动完成

问题描述

我正在尝试写一个类。该类的对象可以采用标签/值对并将其存储label为可以作为属性访问的方式,返回valueobj.label -> value

这里的主要目标是在 jupyter 笔记本中获得自动完成功能,因此obj.<tab>应该生成标签列表作为自动完成建议。下面的类实现了这一点:

class Autocompleter:
    def __init__(self, ):
        self._funcs = {}
    
    def add(self, label):
        self._funcs[label] = 1.
        
    def __dir__(self):
        return list(self._funcs.keys())
    
    def __getattr__(self, name):
        if name in dir(self):
            return self._funcs[name]

问题:访问无效属性时,__getattr__简单地返回None. 我宁愿让它抛出一个异常。我可以想到 2 种方法来实现这一点,但不幸的是,两者都破坏了自动完成功能:

更改__getattr__为:

def __getattr__(self, name):
    return self._funcs[name]

或者

def __getattr__(self, name):
    if name in dir(self):
        return self._funcs[name]
    else:
        raise Exception('invalid name')

产生所需的异常,但会破坏自动完成:

a = Autocompleter()
a.add('foo')

现在a.<tab>不建议foo自动完成,它根本什么都不做。据我所知,jedi 默认用于 jupyterlab 中的自动完成。 问题:有没有办法让无效名称的异常和自动完成功能都工作?

标签: pythongetattrpython-class

解决方案


我自己想通了。处理无效属性名称的正确方法是引发 AttributeError。这点绝地就可以理解了。

def __getattr__(self, name):
    if name in dir(self):
        return self._funcs[name]
    raise AttributeError(name)

请注意,__dir__仍然需要该方法。


推荐阅读