python-3.x - Python3:模块'x'没有属性'y'
问题描述
Python import 语句让我很困惑。有人可以帮我解决这个问题吗?
文件树看起来像这样
root
+- notebook.ipynb
+- lib/
+- basestation_config.py
+- config.py
+- config/
+- valence_pod.json
+- etc…
在config.py
我有:
import json
import os
default_config_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'config'))
def read_filepath(filepath):
with open(filepath, "r") as read_file:
return json.load(read_file)
def read(filename):
filepath = os.path.join(default_config_path, filename) + '.json'
return read_filepath(filepath)
在basestation_config.py
我有:
import config as config
# … a buncha class libraries, including BasestationConfig
def read_basestation_config(config_name = 'valence_pod'):
return BasestationConfig(config.read(config_name))
在notebook.ipynb
我有一个测试单元:
import lib.basestation_config as bsc
bs_config = bsc.read_basestation_config()
display(bs_config)
当我运行它时,我得到:
<module 'config' (namespace)>
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-1-f2942fb5fb2d> in <module>
1 import lib.basestation_config as bsc
----> 2 bs_config = bsc.read_basestation_config()
3 display(bs_config)
/mnt/eng_store/pod/logs/embedded/utils/logutils/indot-py/lib/basestation_config.py in read_basestation_config(config_name)
270 def read_basestation_config(config_name = 'valence_pod'):
271 print(config)
--> 272 return BasestationConfig(config.read(config_name))
AttributeError: module 'config' has no attribute ‘read’
解决方案
当你使用configimport config
文件夹时,Python 使用的是配置文件夹(带有 JSON 文件的文件夹)而不是模块。您可以在导入后通过打印来检查:lib/config.py
config.__path__
import config as config
print(config.__path__)
# _NamespacePath(['/path/to/root/config'])
_NamespacePath
表示文件夹config被视为隐式 Python 包,它不包含__init__.py
类似常规 Python 包,但名称与正在导入的“config”匹配。
在查找名为“foo”的模块或包时,对于父路径中的每个目录:
- 如果
<directory>/foo/__init__.py
找到,则导入并返回常规包。- 如果没有,但是
<directory>/foo.{py,pyc,so,pyd}
找到,一个模块被导入并返回。扩展的确切列表因平台和是否指定 -O 标志而异。这里的列表具有代表性。- 如果不是,但
<directory>/foo
找到并且是一个目录,则记录它并继续扫描父路径中的下一个目录。- 否则,扫描将继续父路径中的下一个目录。
您的设置属于第 3 条,与目标<directory>/config
匹配import config
。然后你可能想知道<directory>
这里有什么?这取决于存储在 中的Module Search Pathsys.path
,它是 Python 将在其中查找导入目标的所有目录的列表。当您在root下运行测试脚本时,根目录会添加到您的sys.path
.
包含正在运行的脚本的目录位于搜索路径的开头,位于标准库路径之前。
import config
通过在basestation_config.py之前添加它来检查它:
import sys
print(sys.path)
# ['/path/to/root', ... ]
import config as config
这就解释了原因。要解决此问题,您可以执行以下操作:
- 将config文件夹重命名为其他名称(例如jsonfiles),只是为了防止将来出现此类错误并将其与config.py模块区分开来
更改lib以遵循常规的 Python 包结构,方法是在lib下添加一个
__init__.py
文件以清楚地将其标记为包。lib ├── __init__.py ├── basestation_config.py └── config.py
- 最后,在basestation_config.py中明确说明您将在同一目录
中导入config.py 。
from . import config as config print(config.__file__) # /path/to/lib/config.py
请注意,在执行第 3 步之前,如果您添加了print(config.__path__)
前面的代码,请确保在应用更正后的代码后将其删除,因为它很可能在您的config.py中不可用(您可能会收到“ AttributeError: module 'lib.config' has没有属性__path__
")。
它现在应该在这些更改之后工作。
推荐阅读
- python - 机器人框架 - 将列表变量作为关键字参数传递
- merge - 在mercurial中合并来自合并子存储库的多个分支的历史记录
- c# - .NET 可视化代码(两个硬盘)
- doctrine-orm - 每次测试后 Nuke/Delete/Truncate 数据库条目,而不使用数据夹具
- kubernetes - 使用外部 Nginx 负载均衡器或 F5 负载均衡器的 Kubernetes HA 设置用户“system:anonymous”无法在集群范围内创建节点
- python - 从文件中读取数据并使用 python 中的 anytree 创建树
- python - HTML Select - 稍后在 HTML 中使用当前选择值,与 Flask
- python - Python中空列表中的常用词
- javascript - Jmeter用双引号发送Cookie
- vba - workbooks.open 拉错文件