在python中,如何导入文件名以数字开头


82

基本上有一个名为的文件8puzzle.py,我想将该文件导入另一个文件(在同一文件夹中,因为提供了该文件,所以无法更改文件名)。无论如何,在Python中可以做到这一点吗?我尝试了通常的方式from 8puzzle import *,这给了我一个错误。

错误是:

>>> import 8puzzle
  File "<input>", line 1
    import 8puzzle
           ^
SyntaxError: invalid syntax
>>> 

11
人们为什么说“它给我(一个)错误”,然后不张贴错误是什么?
John Zwinck

7
@JohnZwinck这是语法错误。我猜是因为“ 8puzzle”不是有效的标识符(它以数字开头),并且import语句的语法在那里需要Python标识符。这将给出答案“不,您不能。将模块重命名为以字母或下划线开头的名称。”
millimoose '02

约翰说的很对,我会记住的。并感谢Abhijeet为我添加错误消息。谢谢。
西蒙·郭

1
重命名8puzzle.pypuzzle8.py和使用import puzzle8
巴库里

Answers:


94

你可以做

puzzle = __import__('8puzzle')

非常有趣的问题。我会记住不要用数字命名。

如果您愿意import *-您应该查看此问题和答案


1
很棒!谢谢。是的,我不会以数字开头来命名,但是它是课程分配讲义文件,因此我无法更改名称。但这似乎无关紧要,因为我们已经找到了解决方案。再次感谢。
西蒙·郭

3
帮助拯救世界,至少帮助您的同学。如果您收到了不可能的输入,请提请教师注意。是的,有时候他们讨厌错了,但是如果您遇到了这个问题,那么其他所有人也都会错了,尽管这个答案有效,但这不是正确的解决方案(除非该类是“ Obfuscated Python 101”)。
msw 2012年

1
更好的方法(至少使用python 2.7)是使用“ importlib”模块:puzzle = importlib.import_module('8puzzle')
Cédric

3
其实这是一个很好的用例这一点-因为编译/ productionizing过程中,串联Python模块在一起的部分是最容易,如果他们在lexigraphical形式命名(一般也没关系,但常数和顶部,如果进口“的名字',因此一些以'0'开头的模块可能会有用。)在调试这种异常的目录布局(与inotify或watch结合使用时)时也很有用,例如:watch -n .1'cat * | python”,它将每十分之一秒(或至少尽快)加载python应用,或者:cat $(find。-name“ * .py”)| python
fatal_error 2015年

1
聚会晚了,但是另一个使用案例是从Alembic迁移中导入的,因为它们都是以随机散列开始的
kevlarr

35

上面的答案是正确的,但是到目前为止,推荐的方法是使用import_modulefunction:

importlib.import_module(name, package=None)
导入模块。name参数以绝对或相对术语(例如pkg.mod..mod)指定要导入的模块。如果使用相对术语指定名称,则必须将package参数设置为要用作解析包名称的锚点的包的名称(例如,import_module('..mod', 'pkg.subpkg')import pkg.mod)。

import_module()函数充当的简化包装 importlib.__import__()。这意味着该函数的所有语义均源自importlib.__import__()。这两个函数之间最重要的区别是,import_module()返回指定的包或模块(例如pkg.mod),而__import__()返回顶级包或模块(例如pkg)。

如果要动态导入自解释程序开始执行以来创建的模块(例如,创建了Python源文件),则可能需要调用invalidate_caches()以便导入系统注意到新模块。

__import__ 现在不推荐。

importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)
内置__import__()功能的实现。

注意应该以编程方式导入模块,import_module()而不要使用此功能。


的确可以工作,但是不能在以数字开头的文件之一中导入函数或变量。如果我做:an_imported_file = importlib.import_module('13_file'),那我就做不了from an_imported_file import var_x。有什么办法可以做到这一点?
马丁

/usr/local/bin/python3.7 "/Users/constan/Desktop/2_COData/1_PYTHON /CODEX/13_Spacy/children.py" Traceback (most recent call last): File "/Users/constan/Desktop/2_COData/1_PYTHON /CODEX/13_Spacy/children.py", line 7, in <module> from an_imported_file import var_x ModuleNotFoundError: No module named 'an_imported_file'
马丁

此外,Pycharm中来自an_imported_file import var_x`的行用红色下划线显示...
Martin

我不知道抱歉 我的一般建议是避免这样做。
6

0

不要.py在导入中使用扩展名。

from 8puzzle import *工作吗?

就其价值而言,from x import *不是首选的Python模式,因为它会将模块的命名空间渗入当前上下文中。

通常,尝试从该模块导入您特别想要的东西。可以从其他模块导入任何全局变量。

例如,如果可以的8puzzle.foo话,可以从8puzzle导入

编辑:

虽然我的.py信息是正确的,但这还不够。

另一个张贴者的__import__('8puzzle')建议是正确的。但是,我强烈建议您避免使用此模式

首先,它保留了内部私有Python方法。 您基本上打破了能够导入模块意味着什么的基本假设。 只需将文件重命名为其他名称即可puzzle8解决此问题。

这将使经验丰富的Python程序员感到沮丧,他们希望知道您导入的内容最重要,并且期望代码(尝试)符合PEP8


1
对不起,我感到困惑。我所做的是,from 8puzzle import *然后我编辑了原始问题。就像mvanveen所说的那样,它是行不通的。
西蒙·郭

那是我的坏事。我忘记了模块文件名不能以数字开头。我已经发布了修改。
mvanveen'2
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.