[英]Python3: module 'x' has no attribute '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’
当您import config
,Python使用的是config文件夹(一个带有JSON文件的文件夹),而不是lib/config.py
模块。 您可以在导入后通过打印config.__path__
进行检查:
import config as config
print(config.__path__)
# _NamespacePath(['/path/to/root/config'])
_NamespacePath
表示文件夹配置被视为隐式Python包 ,它不像常规Python包一样包含__init__.py
,但名称与导入的“ config”匹配。
在为父路径中的每个目录查找名为“ foo”的模块或软件包时:
- 如果找到
<directory>/foo/__init__.py
,<directory>/foo/__init__.py
导入并返回常规包。- 如果没有,则找到
<directory>/foo.{py,pyc,so,pyd}
,将导入并返回一个模块。 扩展的确切列表因平台以及是否指定-O标志而异。 这里的列表是代表性的。- 如果不是,而是找到
<directory>/foo
并且它是一个目录,则会记录该目录,并且扫描将继续使用父路径中的下一个目录。- 否则,扫描将继续使用父路径中的下一个目录。
您的设置属于项目符号3,因为<directory>/config
与import config
目标匹配。 然后,您可能想知道这里的<directory>
是什么? 这取决于存储在sys.path
的模块搜索路径 ,该路径是Python将在其中查找导入目标的所有目录的列表。 当您在root用户下运行测试脚本时, sys.path
根目录添加到sys.path
。
包含正在运行的脚本的目录位于搜索路径的开始,在标准库路径之前。
通过在basestation_config.py中 import config
之前添加此选项来进行检查:
import sys
print(sys.path)
# ['/path/to/root', ... ]
import config as config
这就解释了为什么。 要解决此问题,您可以执行以下操作:
更改lib以遵循常规的Python包结构 ,方法是在lib下添加__init__.py
文件以将其明确标记为包。
lib ├── __init__.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:模块'lib.config'没有属性__path__
“)。
这些更改之后,它现在应该可以工作了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.