代码之家  ›  专栏  ›  技术社区  ›  LcdDrm

python绝地,动态属性的自动完成

  •  0
  • LcdDrm  · 技术社区  · 3 年前

    我正试着写一门课。该类的对象可以获取标签/值对,并以如下方式存储它: label 可以作为属性访问,返回 value : obj.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 . 我宁愿让它抛出一个异常。我可以想出两种方法来实现这一点,但不幸的是,这两种方法都破坏了自动完成功能:

    改变 __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 对于自动完成,它什么也不做。据我所知,在jupyterlab中,绝地默认用于自动完成。 有没有办法让无效名称上的异常和自动完成功能都正常工作?

    0 回复  |  直到 3 年前
        1
  •  0
  •   LcdDrm    3 年前

    我自己想出来的。处理无效属性名称的正确方法是引发AttributeError。这一点绝地武士才能理解。

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

    请注意 __dir__ 方法仍然是需要的。