结论:
在 __init__.py
文件中定义的 __getattr__
方法,如果存在的话,通常用于处理包级别的属性访问。在包级别,__getattr__
方法在导入模块时被调用,而不是在实例化包时。当你尝试访问包中不存在的属性时,__getattr__
方法会被调用,给你一个机会来处理这个属性访问。
问题:
在调试langchain代码的时候遇到个少见的现象如下:
这俩为什么是白色的?第一反应是想这俩是C++实现,没法调试进入,所以是白色的;
基于这样的好奇心,进入到对应的__init__文件查看如下:
下面全是这样的自定义类import方法:
然后接一个__getattr__方法:
这个 __getattr__方法里面根据参数name选择调用上述的不同_import方法,进而导入不同的包;
再然后就是一个__all__属性,用于限制相对导入from xxx import *;注意,__all__只限制相对导入;明确了模块名的绝对导入是不受__all__限制的;
调试的时候发现,根据这两条import语句,进入到__init__文件以后,再调试到__all__的时候,直接进入了 __getattr__方法里面去导入包;