同名google目录下Python模块导入异常:无法导入google.appengine
当然可以不用移动目录来解决这个问题!你遇到的核心问题是Python的模块导入优先级导致的:当两个同名的顶级google包存在于sys.path的不同位置时,Python会优先加载排在sys.path靠前位置的那个包,所以现在你的site-packages里的google包先被找到,自然就无法导入GAE目录下的模块了。
下面给你几个无需移动目录的解决方案,你可以根据自己的使用场景选择:
方法1:动态调整sys.path顺序(最常用)
在需要导入GAE模块的代码开头,把GAE的根目录插入到sys.path的最前面,这样Python会先找到GAE的google包。如果之后还需要导入Google Cloud的模块,再恢复原来的路径顺序即可:
import sys # 保存原始的sys.path顺序,方便后续恢复 original_sys_path = sys.path.copy() # 将GAE的根目录插入到sys.path的首位 gae_root = "C:\\Users\\MohammedT\\Desktop\\dsapp\\sitepackages\\dev\\google_appengine" sys.path.insert(0, gae_root) # 现在可以正常导入GAE的模块了 from google import appengine from google.appengine.api import users # 恢复原始路径,确保后续导入Google Cloud模块不受影响 sys.path = original_sys_path # 现在导入Google Cloud模块也没问题 from google.cloud import datastore
方法2:使用importlib直接从指定路径导入模块
如果只需要导入GAE中的个别模块,也可以用importlib工具从指定路径加载模块,这样不会影响全局的sys.path:
import importlib.util import os # 定义GAE下google目录的路径 gae_google_dir = os.path.join( "C:\\Users\\MohammedT\\Desktop\\dsapp\\sitepackages\\dev\\google_appengine", "google" ) # 加载GAE的appengine模块 spec = importlib.util.spec_from_file_location( "google.appengine", os.path.join(gae_google_dir, "appengine", "__init__.py") ) gae_appengine = importlib.util.module_from_spec(spec) spec.loader.exec_module(gae_appengine) # 现在可以使用该模块的内容,比如: from gae_appengine.api import users
方法3:调整PYTHONPATH环境变量(全局生效)
如果你主要在做GAE开发,很少用到Google Cloud模块,可以直接修改系统的PYTHONPATH环境变量,把GAE的根目录放在site-packages路径的前面。不过这种方法会全局改变Python的模块查找顺序,如果你同时需要开发Google Cloud相关功能,可能会反过来导致Cloud模块无法导入,所以谨慎使用。
补充说明
为什么会出现这个问题?Python在导入模块时,会严格按照sys.path列表的顺序查找对应的包或模块,找到第一个匹配的就会停止查找。你之前虽然把两个路径都加入了sys.path,但site-packages的路径排在了GAE路径的前面,所以Python只会加载site-packages里的google包,自然找不到GAE下的模块内容。
内容的提问来源于stack exchange,提问作者Tameem

