当文件名包含句点时如何引用python包

Posted

技术标签:

【中文标题】当文件名包含句点时如何引用python包【英文标题】:How to reference python package when filename contains a period 【发布时间】:2010-12-22 03:17:36 【问题描述】:

我正在使用 django,我有一个名为 models.admin.py 的文件,我想在 models.py 中执行以下想法:

from "models.admin" import *

但是,我收到双引号导致的语法错误。但如果我只是这样做

from models.admin import *

然后我得到“ImportError: No module named admin”

有没有办法从名称中带有句点的 python 文件导入?

【问题讨论】:

从技术上讲,这是一个模块,而不是一个包。 【参考方案1】:

实际上,您可以导入一个名称无效的模块。但是您需要为此使用imp,例如假设文件名为models.admin.py,你可以这样做

import imp
with open('models.admin.py', 'rb') as fp:
    models_admin = imp.load_module(
        'models_admin', fp, 'models.admin.py',
        ('.py', 'rb', imp.PY_SOURCE)
    )

但在开始使用之前请阅读imp.find_moduleimp.load_module 上的文档。

【讨论】:

不好的做法? impimport__import__ 背后的机制。更大的灵活性,但需要更多的代码。不过,这并没有什么神奇之处。 机器码是一切背后的机制。更多的灵活性和.. 看看我要去哪里? :) 如果你真的需要使用它,你显然需要三思而后行,但我不明白使用它是多么错误。 ;) 它用于生产 - 参见例如追踪 - trac.edgewall.org/browser/trunk/trac/loader.py. 为了记录,我从来没有真正命名我的文件,因为我意识到这会很复杂。但是在出于好奇而谷歌搜索并没有找到答案之后,我决定将答案(import imp)和公认实践的声音(不要使用它)存档以供未来的 Google 员工使用。 :) 我认为重要的一点是,根据 python 样式指南,这是一个无效的模块名称:python.org/dev/peps/pep-0008。但是,在 OP 的情况下,如果无法更改模块名称,则此解决方案似乎是合理的,因为它使用了有据可查的接口。换句话说,未来的 python 次要版本不太可能改变这种行为。如果解决方案涉及未记录的功能,那就另当别论了,我会同意 shylent 的意见。【参考方案2】:

如果您真的想要,您可以使用 imp 模块导入具有不寻常文件名的模块(例如,在“.py”之前包含“.”的文件名):

>>> import imp
>>> a_b = imp.load_source('a.b', 'a.b.py')
>>> a_b.x
"I was defined in a.b.py!"

但是,这通常是个坏主意。您更有可能尝试使用包,在这种情况下,您应该创建一个名为“a”的目录,其中包含一个名为“b.py”的文件;然后“import a.b”将加载a/b.py。

【讨论】:

load_source 至少从 1.5 开始就已过时。 没错,虽然非过时的做法有点冗长:a_b = imp.load_module('a.b', open('abpy'), os.path.abspath ('abpy'), ('.py', 'r', imp.PY_SOURCE))【参考方案3】:

不,如果 python 文件的名称包含句点(或问号、感叹号等),则不能将其作为模块导入。 Python 模块的名称(不包括 .py)必须是有效的 Python 名称(即可以用作变量名)。

【讨论】:

你有这方面的参考资料吗? 参考是 Python 语法规范 (docs.python.org/2/reference/grammar.html)。然而,这实际上只指定了 import 语句允许的内容——正如上面在接受的答案中所指出的那样,技术上可以通过使用底层的导入机制来解决这个问题。 对于包含多个单词的长名称,最好的模式是什么?命名一个包,因此一个文件夹“awesome.project”会产生问题,而“awesomeProject”似乎是一种反模式。不确定我是否正确理解了这条规则:python.org/dev/peps/pep-0423/#id87【参考方案4】:

文件名为models/admin.py。 (Source)

也就是说,它应该在名为models的目录中调用admin.py

然后你可以使用from models.admin import * 导入,假设它在你的 Python 路径中。

【讨论】:

【参考方案5】:

如下图

假设目录结构是这样的:

C:.
│   script.py
│   
└───Parent
    └───Child
        ├───1.1
        │       main.py
        │       
        └───1.2

**假设你想在 script.py 中导入 main.py **

您的 main.py 如下所示

def my_function():
  print("Hello from a function")

您的 script.py 如下所示

from os import path
import importlib
from os.path import dirname
import sys
import importlib.util


def getPath():
    # your logic to get to the path
    return path.join(dirname(__file__),'Parent','Child','1.1','main.py')

file_path = getPath() 
module_name = 'main'

spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

#call functions like this
module.my_function()

看看这个gist

【讨论】:

【参考方案6】:

您没有在导入语句中引用 files,而是引用了 modulespackages

请阅读docs,他们对此非常清楚。

无论如何,由于您使用的是 django,因此通常的方法行不通。如果您想将模型保存在单独的文件中,而不是在 models.py 中,则必须采取额外的步骤,例如here。

编辑: 好吧,我真的不知道提问者提到admin是什么意思,以及它是否与django的管理界面有关。我的观点仍然有效。

【讨论】:

一个模块就是一个文件。引用您引用的文档:To support this, Python has a way to put definitions in a file and use them in a script or in an interactive instance of the interpreter. Such a file is called a module;

以上是关于当文件名包含句点时如何引用python包的主要内容,如果未能解决你的问题,请参考以下文章

python中多重目录中的包引用怎么样?

如何验证包含两个句点的电子邮件地址(Python)

英语作文引用名言的标点符号怎么打?

英语作文引用名言的标点符号怎么打

Pytho核心编程笔记——第三章

当 URL 中包含句点的哈希值 (#) 时,IIS 将重定向到 404 错误页面