IPython自动完成正在调用_getattr__

IPython自动完成正在调用_getattr__,python,python-3.x,jupyter-notebook,ipython,Python,Python 3.x,Jupyter Notebook,Ipython,感谢您抽出时间阅读此文章。希望你在这个奇怪的时刻一切都好 我正在实现一个类,并开始研究如何在其属性上提供自动完成。 通过我的在线研究,我得出结论,ipython补全来自\uuuu dir\uuu方法 当您访问不存在的属性时,通常会调用\uuuu getattr\uuuu。在我的项目中,如果发生这种情况,将运行一个需要一段时间的操作。为什么ipython尝试访问属性,而不只是显示返回的\uuuuuuuuu\uuuuuu 在单元格2中,我点击点后的tab键要求完成 我认为问题在于您需要一个类的实例。

感谢您抽出时间阅读此文章。希望你在这个奇怪的时刻一切都好

我正在实现一个类,并开始研究如何在其属性上提供自动完成。 通过我的在线研究,我得出结论,ipython补全来自
\uuuu dir\uuu
方法

当您访问不存在的属性时,通常会调用
\uuuu getattr\uuuu
。在我的项目中,如果发生这种情况,将运行一个需要一段时间的操作。为什么ipython尝试访问属性,而不只是显示返回的
\uuuuuuuuu\uuuuuu

在单元格2中,我点击点后的tab键要求完成


我认为问题在于您需要一个类的实例。这些方法是实例方法

我添加了日志记录以便于调试。我在
example时在
ipython
控制台中得到输出。一些东西
示例。

  • Python版本3.8.2
  • IPython 7.14.0版
这是我的观察:调用On
\uuuu dir\uuuu
,返回的项目集合显示在IPython控制台中。如果在
之后选择的项目不是对象的属性,则调用
\uuu getattr\uuuu
以尝试查找它

import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)


class Example:
    def __init__(self):
        logging.info("init")
        self._attrs = ("foo", "bar", "baz")
        for attr in self._attrs:
            setattr(self, attr, attr)

    def __getattr__(self, attr):
        logging.info(f"__getattr__ called: {attr}")

    def __dir__(self):
        logging.info("__dir__ called")
        return ("extra", *self._attrs)


# Create an instance of Example.
# The instance methods can then be called on the instance.
example = Example()

if __name__ == "__main__":
    logging.info(example)

所以我想出了一个解决办法。如果您知道需要很长时间的属性名,则仅在传递该属性名时执行自定义getattr代码,否则只会引发属性错误。这对我有用

糟糕的是,我忘了创建对象。我已经编辑过了。我使用sleep,因为在ipython调用该方法时不会显示打印。这就是为什么在您的代码中,问题似乎消失了。如果添加睡眠,您可以看到自动完成正在调用
\uuuu getattr\uuuu
。如果解决了您的问题,请接受答案。非常感谢。我可以发誓我看到了一些打印输出。现在我没有了。它没有解决问题。就像我说的,如果你将睡眠添加到你的代码中,并尝试自动完成它将需要2秒钟。我的问题是自动完成调用getattr。在我的示例中,我忘了实例化对象,但这不是我的问题。您是否希望在按下tab键时调用
\uuu getattr\uuu
?根据我的观察,点击tab键时会调用
\uuuuuu dir\uuuu
方法。正在调用
\uuuuu dir\uuuu
,这就是我所期望的。我没有得到的,我提出的问题是,
\uu getattr\uu
在不应该调用的时候也会被调用。您可以通过添加睡眠来验证它。当您点击tab时,它将调用dir(我想要的),但随后它将调用getattr,只有在您访问属性时才应该调用该getattr。自动完成不应访问该属性。那是写在我的问题里的。请复习这个问题。这不是iPython的特例
\uuuu getattr\uuuuuu
似乎是在
\uuuu dir\uuuuuu
返回的列表的最后一项上调用的,即使在CPython中也是如此。刚刚检查过,它在
\uuu dir\uuuuuuuu
的每个元素上都被调用,我不确定。您可能需要深入研究CPython(可能还有iPython)用于启用选项卡完成的。模块注释明确提到调用
\uuu getattr\uuuu
的风险,尽管我不清楚这是如何发生的。这真的很奇怪。我会调查的。