另一个Python相对导入的灾难

另一个Python相对导入的灾难,python,python-3.x,Python,Python 3.x,#背景和问题# 我正试图建立一个网络-刮板来备份我的社交媒体账户(暑期项目,我知道它没用) 我试图创建一个好的类结构,因此我提出了以下结构(我接受批评,我对编程非常陌生): (Twitter和VSCO目前为空。任何没有扩展名且以开头的文件都是文件夹。每个文件都有一个与其中文件同名的类) #问题# 我在哪里可以确切地学习Python的打包系统?有推荐书或网站吗 如何将图像导入GraphImage?如何将文件导入SocialMediaPost 我需要在\uuuu init\uuuu.py中写些什么,

#背景和问题# 我正试图建立一个网络-刮板来备份我的社交媒体账户(暑期项目,我知道它没用)

我试图创建一个好的类结构,因此我提出了以下结构(我接受批评,我对编程非常陌生):

(Twitter和VSCO目前为空。任何没有扩展名且以开头的文件都是文件夹。每个文件都有一个与其中文件同名的类)

#问题#

  • 我在哪里可以确切地学习Python的打包系统?有推荐书或网站吗
  • 如何将图像导入GraphImage?如何将文件导入SocialMediaPost
  • 我需要在
    \uuuu init\uuuu.py
    中写些什么,以便
    导入一些包
    并让它导入每个模块?(例如:导入文件并使文件、图像和文件、视频可访问)
  • (我知道有很多问题。它们是按重要性顺序写的)

    #要完成将文件导入SocialMediaPost,我已尝试:#

    来自文件。文件导入文件

    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