另一个Python相对导入的灾难
#背景和问题# 我正试图建立一个网络-刮板来备份我的社交媒体账户(暑期项目,我知道它没用) 我试图创建一个好的类结构,因此我提出了以下结构(我接受批评,我对编程非常陌生): (Twitter和VSCO目前为空。任何没有扩展名且以开头的文件都是文件夹。每个文件都有一个与其中文件同名的类) #问题#另一个Python相对导入的灾难,python,python-3.x,Python,Python 3.x,#背景和问题# 我正试图建立一个网络-刮板来备份我的社交媒体账户(暑期项目,我知道它没用) 我试图创建一个好的类结构,因此我提出了以下结构(我接受批评,我对编程非常陌生): (Twitter和VSCO目前为空。任何没有扩展名且以开头的文件都是文件夹。每个文件都有一个与其中文件同名的类) #问题# 我在哪里可以确切地学习Python的打包系统?有推荐书或网站吗 如何将图像导入GraphImage?如何将文件导入SocialMediaPost 我需要在\uuuu init\uuuu.py中写些什么,
\uuuu init\uuuu.py
中写些什么,以便导入一些包
并让它导入每个模块?(例如:导入文件并使文件、图像和文件、视频可访问)来自文件。文件导入文件
from…Files.File导入文件
导入文件
从文件导入文件
几乎任何你能想象的组合
我总是得到一个无法导入
,没有名为“\uuuu main\uuuu.Files”的模块
或试图在顶级包之外进行相对导入
#预期行为#
我已经习惯了Java的方式,我不知道如何在Python中实现这一点。看起来很混乱。我真的很怀念添加一个包和一个运行编译器的文件夹树
敲桌子
##谢谢## 我支持Damian和user2357112的评论-在创建模块时,尽量避免文件夹、文件和类/函数之间的名称冲突
如果不将当前工作目录添加到PYTHONPATH中,您可能无法导入当前工作目录之外的任何内容。将文件夹添加到PYTHONPATH环境变量意味着python在导入模块时将始终检查该文件夹,因此您可以从任何地方导入它
这方面已经有了一条很好的线索,可以让你找到正确的方向:
(在一篇文章中涉及的内容很多)关于这方面有很多文章。。。然而,大多数指南关注的是你如何做,而不是做什么
我是如何做到的(对于中小型项目):
不要弄乱sys.path
有一个“projectroot”目录,下面有您的模块/包(就像您已经做的那样)
始终使用绝对导入,但“姐妹”模块除外
始终作为模块运行,即使用python-mfoo.bar
使用您的结构的具体示例。假设您的入口点可能位于\SocialMedia\SocialMediaFeed.py
中,请使用导入语句:
来自。导入SocialMediaPost
(姐妹模块)
导入Instagram
(子模块)
从文件导入图像
(其他模块)
并使用以下命令运行:python-msocialmedia.SocialMediaFeed
通过作为模块运行,您始终可以将项目根(社交媒体备份
)添加为“搜索路径”。这样,引用其子文件夹的绝对导入始终有效。顺便说一下,您可以使用import sys打印出模块搜索路径;打印(系统路径)
其中一些可能看起来过于复杂了,但我发现,只要您尝试打包要安装的内容(关键字setup.py
),遵循上述几点就会大有裨益
编辑:回答第三个问题:Have\uuuuu init\uuuuu.py
包含:
from . import File
from . import Image
from . import Video
尝试从项目的根开始(但在此之前,请将其重命名为social_media_backup)-“from social_media_backup.Files.File…”,此外,广泛建议使用小写字母命名模块,并使用下划线而不是破折号。此外,将_init_uuuuy.py文件放在社交媒体备份中。在Python中,将WhateverClass
放在名为WhateverClass.py
的文件中是一个非常糟糕的主意。如果您真的希望每个文件有一个类,至少将其命名为whateverclass.py
,这样您就不会在模块和类之间产生超级混乱的名称冲突。Stackoverflow是“一次一个问题”的好地方。一件事你应该考虑的是,你从哪里启动这个应用程序?您应该搜索最小Python包
。这不是很琐碎,但你应该花时间通读一遍Packaging@Damian谢谢你的回复!我曾用它来命名我的类,但我把它与Java中的操作方式混为一谈。我觉得有点像这样:当你导入一个模块时,你可以通过module.class
访问其中的类。但是,如果您从模块导入类,您可以只使用class
?我将改变我的命名约定,然后尝试所有其他解决方案。@user2357112我想我明白为什么会有达米安的评论。在尝试任何其他解决方案之前,我一定会改变这一点。谢谢你的回复。我试图不惜一切代价避免修改sys.path
和PYTHONPATH
。当你说我应该总是使用绝对导入时,它们是指我的CMD执行目录吗?我的意思是,如果我站在PATH\TO\MY\PROJECT\DIRECTORY\social media downloader
中执行python-m SocialMedia.SocialMedia.SocialMedia afeed
,我是否应该从social-media-backup.some.other.folder导入一些东西?(正如建议的那样,我已经在我的项目中更改了for)。是的,在脚本开始时,您的当前目录将添加到python搜索路径(sys.path
变量)。import语句不应包括根文件夹名称:from some.other.folder import some\u thing
。哦,还有你的包文件夹名
from . import File
from . import Image
from . import Video