main.py调用coordinates_api.py时提示找不到api_keys模块的问题求助
我正在尝试使用谷歌的地理API,为了遵循最佳实践,打算把API密钥放在api_keys.py文件里,避免提交到GitHub仓库。
coordinates_api.py通过import api_keys来导入密钥并调用API,单独测试coordinates_api.py的时候一切正常,能正常打印出我想要的坐标。
但当我测试调用coordinates_api.py的main.py时,却出现了如下错误:
Traceback (most recent call last): File "c:\Users\me\Documents\Projects\Git\ProjectName\src\main.py", line 1, in <module> from apis import * File "c:\Users\me\Documents\Projects\Git\ProjectName\src\apis\coordinates_api.py", line 2, in <module> import api_keys ModuleNotFoundError: No module named 'api_keys'
我搞不懂为什么main.py识别不到api_keys模块。
以下是我的代码:
coordinates_api.py:
import requests import api_keys class CoordinatesAPI: def __init__(self, api_key=None): self.api_key = api_keys.geo def get_coordinates(self, address): base_url = "https://maps.googleapis.com/maps/api/geocode/json" params = { "address": address, "key": self.api_key } response = requests.get(base_url, params=params) if response.status_code == 200: data = response.json() if data['status'] == 'OK': location = data['results'][0]['geometry']['location'] return location['lat'], location['lng'] else: raise Exception(f"Error from API: {data['status']}") else: raise Exception(f"HTTP error: {response.status_code}")
main.py:
from apis import coordinates_api if __name__ == "__main__": address = "1600 Amphitheatre Parkway, Mountain View, CA" CA1 = coordinates_api.CoordinatesAPI() lat, lng = CA1.get_coordinates(address) print(f"Latitude: {lat}, Longitude: {lng}")
(我也尝试调整过导入方式,比如from apis import *,但还是报同样的错误。与其反复试错,我更想搞清楚到底哪里出问题了)
我的项目目录结构如下:
│ main.py │ ├───apis │ │ api_keys.py │ │ coordinates_api.py │ │ __init__.py
嗨,这个问题其实是Python模块导入路径的问题,我来给你解释清楚:
当你直接运行coordinates_api.py时,Python会把当前文件所在的目录(也就是apis文件夹)加入到模块搜索路径里,所以import api_keys能找到同目录下的api_keys.py。
但当你从main.py(它在apis的上级目录)导入coordinates_api时,Python的模块搜索路径是以main.py所在的目录为基准的。这时候coordinates_api.py里的import api_keys会让Python去main.py所在目录找api_keys.py,而不是apis目录下的,所以就找不到了。
解决方法有两种,推荐第一种(更符合Python包的规范):
方法1:使用相对导入或者绝对导入
因为apis是一个包(有__init__.py),你可以在coordinates_api.py里把导入改成相对导入:
import requests from . import api_keys # 用.表示当前目录
或者用绝对导入(更清晰,尤其是包结构复杂时):
import requests from apis import api_keys
这样不管是直接运行coordinates_api.py(注意如果用绝对导入,需要确保项目根目录在Python路径里,或者你用python -m apis.coordinates_api来运行),还是从main.py导入,都能正确找到api_keys模块。
方法2:手动添加模块路径
你也可以在coordinates_api.py开头手动把当前文件所在目录加入到Python的搜索路径里,但这种方法不够优雅,不推荐:
import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) import requests import api_keys
另外,提醒一下:如果你用相对导入,直接运行coordinates_api.py可能会报错(因为相对导入不能在顶层脚本里用),这时候你可以用python -m apis.coordinates_api来运行它,这样Python会把它当作包的一部分来处理,就能识别相对导入了。
这样调整之后,main.py应该就能正常运行啦!
备注:内容来源于stack exchange,提问作者user24196311

