调用Python模块mir_api中metrics属性时触发AttributeError错误
调用Python模块mir_api中metrics属性时触发AttributeError错误
咱们先拆解下你遇到的问题,其实主要有两个关键点导致了这个AttributeError:
1. 函数被藏在了if __name__ == '__main__'块里
你在mir_api.py里把metrics函数定义在了if __name__ == '__main__'的代码块内部。这个代码块的作用是只有当你直接运行mir_api.py脚本时才会执行里面的代码,如果把它作为模块导入到test.py里,这个块里的所有定义(包括metrics函数)都不会被加载到模块的命名空间中,所以test.py自然找不到mir_api.metrics这个属性。
2. metrics的定义不符合普通函数的规范
你把metrics定义成了带self参数的方法,但并没有把它放到一个类里面。self是Python类实例方法的专用参数,普通函数不需要这个参数,这样的定义就算能被加载,调用起来也会出错。
解决方案
根据你的需求,分两种情况来修改:
情况一:把metrics作为普通函数使用
修改mir_api.py,把metrics移到if __name__ == '__main__'外面,并且去掉多余的self参数:
import requests import time import json import settings_config import payload import headers url = settings_config.url # 把metrics移到全局作用域,改成普通函数 def metrics(): return requests.request("GET", url+settings_config.metrics, headers=headers.wat_auth, data=payload.get) if __name__ == '__main__': # 这里放模块直接运行时的测试代码 get_status = requests.request("GET", url+settings_config.status, headers=headers.wat_auth, data=payload.get) get_diagnostic = requests.request("GET", url+settings_config.diagnostics, headers=headers.wat_auth, data=payload.get) # 测试metrics函数 test_metrics = metrics() print(test_metrics)
然后test.py里的调用就可以正常工作了:
import settings_config import json import payload import headers import mir_api test_call = mir_api.metrics() # 注意要加括号调用函数 print(test_call)
情况二:把metrics作为类的方法(如果需要封装更多API逻辑)
如果后续还要扩展更多API调用,建议把这些功能封装成一个类,这样更便于维护:
import requests import time import json import settings_config import payload import headers class MirAPI: def __init__(self): self.url = settings_config.url self.headers = headers.wat_auth self.payload = payload.get def get_status(self): return requests.request("GET", f"{self.url}{settings_config.status}", headers=self.headers, data=self.payload) def get_diagnostic(self): return requests.request("GET", f"{self.url}{settings_config.diagnostics}", headers=self.headers, data=self.payload) def metrics(self): return requests.request("GET", f"{self.url}{settings_config.metrics}", headers=self.headers, data=self.payload) if __name__ == '__main__': # 直接运行时测试类功能 api_client = MirAPI() print(api_client.get_status()) print(api_client.metrics())
对应的test.py需要先实例化类再调用方法:
import settings_config import json import payload import headers import mir_api # 先创建类实例 api_client = mir_api.MirAPI() test_call = api_client.metrics() print(test_call)
关于if __name__ == '__main__'的疑问
这个代码块非常有用,它的核心作用是区分模块被直接运行和被导入到其他脚本两种场景:
- 当你直接运行
mir_api.py时,__name__的值是'__main__',块里的代码会执行,你可以在这里写一些模块的测试逻辑; - 当你把
mir_api.py作为模块导入时,__name__的值是'mir_api',块里的代码不会执行,不会干扰外部脚本的逻辑。
所以这个块是需要保留的,但要注意:不要把需要被外部模块调用的函数/类定义放在这个块里面。
备注:内容来源于stack exchange,提问作者tyelsew
相关产品推荐
相关产品推荐

