尝试导入时可以在Python文件中使用破折号吗?


149

基本上,当我有一个类似python的文件时:

python-code.py

并使用:

import (python-code)

解释器给我语法错误。

关于如何解决它的任何想法?python文件名中的破折号非法吗?

Answers:


167

您应该查看PEP 8(Python代码样式指南):

程序包和模块名称模块应使用简短的全小写名称。如果模块名称可以提高可读性,则可以在模块名称中使用下划线。尽管不鼓励使用下划线,但Python软件包也应使用短小写全名。

由于模块名称被映射为文件名,并且某些文件系统不区分大小写,并且截断长名称,因此,将模块名称选择为相当短是很重要的-在Unix上这不是问题,但可能是将代码传输到较旧的Mac或Windows版本或DOS时出现问题。

换句话说:重命名文件:)


75
问题与样式无关,它是一个语法 错误

4
如下所示,仍然可能有一个使用此名称的文件,因此样式指南非常相关。
Paolo Bergantino

5
当您明确希望防止导入时,在Python目录和文件名中使用连字符可能会非常有帮助。例如,在(例如)Django项目中,您可能具有用Python编写的脚本,这些脚本不应作为应用程序寻址。您可以将它们放在类似的文件夹中,ops-scripts并知道它们无法使用常规的程序包命名空间方法导入。或者可以命名单个脚本以stop-website.py达到类似效果。runpy当然,仍然可以通过其他方法导入其中任何一种,但这有助于避免一些常见的错误。
克里斯·约翰逊

重命名模块可能会出现问题,尤其是在您依赖其他标准的情况下。就我而言,我在文件cgi-bin夹中使用python cgi文件(对它们进行unitttests),这是非常标准的afaik。除非您有这种罕见的情况,否则,如果可以控制模块,则一定要重命名模块。
NuclearPeon 2014年

1
我刚刚发现PyDev允许目录名称带有连字符,但是不会显示该目录中包含的.py文件中的类和/或内部变量。
user5920660

122

代码中需要注意的另一件事是导入不是一个函数。所以import(python-code)应该是import python-code,正如一些已经提到,被解释为“进口蟒蛇减码”,并非您的本意。如果确实需要导入名称中带有短划线的文件,则可以执行以下操作:

python_code = __import__('python-code')

但是,如上所述,这并不是真正的建议。如果要控制文件名,则应更改文件名。


@KevinAudleman您是否有一个使用导入lib和带连字符的文件的有效示例?我尝试失败了。
汤姆·黑尔

@TomHale importlib.import_module('abmodule-1')应该可以工作。如果您的import_module不起作用,我认为普通导入也将不起作用。
Ian Lin)

63

TLDR

短划线不是非法的,但出于以下三个原因,您不应使用它们:

  1. 您需要特殊的语法来导入带有破折号的文件
  2. 没有人期望带有破折号的模块名称
  3. 这违反了Python样式指南的建议

如果您确实需要导入带短划线的文件名,则特殊语法为:

module_name = __import__('module-name')

好奇为什么我们需要特殊的语法?

使用特殊语法的原因是,在编写代码时,import somename您正在创建带有标识符的模块对象somename(因此以后可以将其与eg一起使用somename.funcname)。当然module-name不是有效的标识符,因此是一种有效的特殊语法。

您不明白为什么模块名不是有效的标识符?

不用担心-我也没有。这里有一条提示可以帮助您:查看此python行:x=var1-var2。您看到赋值右侧的减法还是带有破折号的变量名?

聚苯乙烯

除了将我认为是所有其他答案中最相关的信息包括在一个地方之外,我的答案没有任何原始内容


我正在尝试使用此导入带有连字符的pip包。psycopg2_binary = import_module('psycopg2-binary')。错误=> ModuleNotFoundError: No module named 'psycopg2-binary'。但是psycopg2-binary已安装。不知道如何包括它。
Mote Zart

也许这是一个路径问题。看看chrisyeh96.github.io/2017/08/08/…–
ndemou

32

问题是这python-code不是标识符。解析器将其视为python减号code。当然,这不会满足您的要求。您将需要使用也是有效的python标识符的文件名。尝试用-下划线代替。


4
+1。从来没有想过Python源代码的文件名应该是有效的标识符,因为该文件名将用于引用模块对象。
安迪

5

您可能可以通过一些__import__黑客手段将其导入,但是如果您还不知道如何操作,则不应该这样做。Python模块名称应该是有效的变量名称(“标识符”)-这意味着,如果您有一个模块foo_bar,则可以在Python(print foo_bar)中使用它。您将无法使用一个怪异的名称来执行此操作(print foo-bar->语法错误)。


5

在Python 3上,使用import_module

from importlib import import_module
python_code = import_module('python-code')

更普遍,

import_module('package.subpackage.module')

1

尽管正确的文件命名是最好的方法,但是如果python-code不受我们的控制,使用hack __import__比复制,重命名或以其他作者的代码搞乱为佳。但是,我尝试了一下,除非重新命名了添加.py扩展名的文件,否则它不起作用。在查看 了文档以获取如何获取的描述之后.py,我得出了以下结论

import imp

try:
    python_code_file = open("python-code")
    python_code = imp.load_module('python_code', python_code_file, './python-code', ('.py', 'U', 1))
finally:
    python_code_file.close()

python-codec在第一次运行时创建了一个新文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.