【问题标题】:Module name different than directory name?模块名称与目录名称不同?
【发布时间】:2012-10-26 14:00:48
【问题描述】:

假设我有一个名为 bestpackage 的 python 包。

约定规定bestpacakge 也将是sys.path 上的一个目录,其中包含一个__init__.py,以使解释器假定它可以从中导入。

有什么方法可以为包名称设置一个变量,以便可以将目录命名为与我导入它时使用的指令不同的名称?有什么方法可以让命名空间不关心目录名,而是尊重其他一些配置?

我的超级时尚客户端开发人员非常喜欢这些性感的 something.otherthing.js 项目名称,用于我们的一个较小的副项目!

编辑:

澄清一下,我的问题的主要目的是让我的客户端人员继续使用他们现有的约定 (some.app. js),尽管在某些情况下它们实际上是 python 包,它们将在路径上并在内部来源于import 语句。我意识到这在实践中是一件非常可怕的事情,所以出于好奇我问了更多。因此,这里的部分大问题是规避目录名称中的.(以及由此假定的包名称)暗示属性访问这一事实。无法解决这个问题并不让我感到惊讶,我只是好奇是否有可能更深入地了解导入背后的“魔力”。

这里有一些很好的响应,但都依赖于执行某种经典导入,其中属性访问器 . 将与目录名称发生冲突。

【问题讨论】:

  • 带有__init__.py 文件的目录称为包。
  • 谢谢,我总是混淆这些术语。将编辑。

标签: python pythonpath


【解决方案1】:

我一直在寻找 setup.py 在 sdist 和安装时而不是运行时发生这种情况,并找到了指令 package_dir:

【讨论】:

    【解决方案2】:

    有一种解决方案需要在某处进行初始导入

    >>> import sys
    >>> sys.modules['blinot_existing_blubb'] = sys
    >>> import blinot_existing_blubb
    >>> blinot_existing_blubb
    <module 'sys' (built-in)>
    

    如果不更改导入机制,您将无法从其他名称导入。我认为这是为了让 Python 更容易理解。

    但是如果你想改变导入机制我推荐这个:Getting the Most Out of Python Imports

    【讨论】:

      【解决方案3】:

      带有__init__.py 文件的目录称为包。

      不,包名总是与目录相同。这就是 Python 发现包的方式,它将它与在搜索路径中找到的目录名称进行匹配,如果该目录中有 __init__.py 文件,它会找到匹配并导入包含的 __init__.py 文件。

      您始终可以使用 from module import something 或 import module as alias 语法以更短、更易于使用的名称将某些内容导入本地模块命名空间:

      from something.otherthing.js import foo
      from something.otherthing import js as bar
      import something.otherthing.js as hamspam
      

      【讨论】:

      • 在旁注中,总是可以做到import X as Y。因此,您必须将目录称为“X”,但您可以在代码中将其称为“Y”。(对于 OP 来说,这可能就足够了吗?)
      • @Bakuriu:是的,在二读时(已编辑?)这可能就是 OP 想要的。已更新。
      • 也许我并不清楚这一点。这里的主要问题是同步一堆本地运行的烧瓶应用程序包。该系统是一个客户端 api,在烧瓶中具有服务器端后端,因此我的客户端开发人员都将他们的 dirs 命名为“the.project.js”的效果,因为这是他们对项目所做的典型事情。在将这些作为包处理时,这对于 Python 解释器来说当然是一个大问题。
      【解决方案4】:

      其实是的! 你可以做一个规范的import Whatever 或newmodulename = __import__("Whatever")

      python 会跟踪您的模块,您可以通过以下方式对其进行检查:

      import sys
      print sys.modules
      

      更多详情请见this article

      但这也许不是你的问题?让我们猜一下:您有一个位于不同路径中的模块,您当前的项目无法访问它,因为它不在 sys-path 中?

      好吧,只是添加:

      import sys
      sys.path.append('path_to_the_other_package_or_module_directory')
      

      在您的 import 声明之前或查看此 SO-post 以获得更持久的解决方案。

      【讨论】:

        【解决方案5】:

        嗯,首先我要说的是Python is not Java/Javascript/C/C++/Cobol/YourFavoriteLanguageThatIsntPython。当然,在现实世界中,我们中的一些人必须回答不同意的老板。因此,如果您想要的只是一些间接性,请使用烟雾和镜子,只要他们不太关注引擎盖下的内容。以 Python 的方式编写你的模块,然后以你的同事想要的重点风格提供一个 API。例如:

        pythonic_module.py

        def func_1():
            pass
        
        def func_2():
            pass
        
        def func_3():
            pass
        
        def func_4():
            pass
        

        indirection

        /dotty_api_1/__init__.py

        from pythonic_module import func_1 as foo, func_2 as bar
        

        /dotty_api_2/__init__.py

        from pythonic_module import func_3 as foo, func_4 as bar
        

        现在他们可以随心所欲地点点滴滴,但您可以在底层以 Python 式的方式编写内容。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-18
          • 2020-04-04
          • 1970-01-01
          • 2023-03-13
          • 2023-03-12
          • 2020-06-27
          • 2013-12-06
          相关资源
          最近更新 更多