2009-08-11 45 views
6

导入哪些模块,可以说,我在一个文件叫我和openid.py我做的:的Python:如何选择时,它们被命名为同一

from openid.consumer.discover import discover, DiscoveryFailure 

我有openid模块上我的PYTHONPATH但口译员似乎试图使用我的openid.py文件。我如何获得图书馆版本?

(当然,除了显而易见的'重命名你的文件'的答案会很好)。

+7

“重命名文件” – SilentGhost 2009-08-11 08:49:31

+0

什么是不重命名文件的原因是什么?这看起来像是一个小小的修复,而不是寻找一种解决方法。 – Zoomulator 2009-08-11 09:31:12

+0

该文件应该在语义上称为openid,因为它位于带有“类型”别名的模块中。 openid是类型的名称。 – 2009-08-11 09:46:34

回答

9

这就是绝对导入被选为新的默认行为的原因。但是,它们还不是2.6的默认值(可能在2.7 ...)。您可以通过从未来进口他们现在得到他们的行为:

from __future__ import absolute_import 

您可以在文档中"What's New in Python 2.5"找到更多关于这个由尼克metnioned的PEP或(更容易理解,我认为)。

3

重命名它。这是命名空间背后的想法。您的openid可能是您顶级模块project中的一个子模块。您的email将与stdlib中的顶级模块email发生冲突。

因为你的openid不是通用的,它为你的项目提供了一个特例。

+4

实际上,我认为名称空间背后的想法是*不*必须将其重命名为独特的东西;)myproject.openid与openid不同。 使用新的绝对导入,导入openid将始终获得系统范围(例如stdlib)模块,相对.openid将获取当前模块中的openid子模块。 – c089 2009-08-11 09:32:46

+0

当然不是。 **如果**他的模块“project”比他应该使用'project.openid'。目前还不清楚为什么OP在做他正在做的事情,但是如果他没有模块“project”,那么他应该将'openid'重命名为其他东西。 – SilentGhost 2009-08-11 10:35:26

+0

正确。在包之外它是pkg.openid。但在“openid.py”文件中,我无法访问“openid”库。这是主要问题。 – 2009-08-11 22:48:27

1

您可以使用相对或绝对进口(取决于您的具体情况),最近在PEP 328中涵盖。当然,严重的是,你不应该像这样创建命名冲突,应该重命名你的文件。

+0

即使文件的语义正确名称是openid?就像它是否在一个别名类型的目录一样,电子邮件,网页,域等? – 2009-08-11 09:08:55

+0

@保罗:即使那样。如果它位于“别名类型目录”中,那么它确实应该是一个包,然后是pkg.openid,这是明确的。 – 2009-08-11 20:34:43

+0

正确。在包之外它是pkg.openid。但在“openid.py”文件中,我无法访问“openid”库。这是主要问题。 – 2009-08-11 22:47:51

-1

你可以尝试洗牌sys.path,做进口之前有趣的目录移动到前面。

+0

如果已经设置了'sys.modules ['openid']',它就不会有帮助,因为在'openid.py'中就是OP。 – 2009-08-11 15:08:59

+0

@Alex为什么会这样?当前文件是否自动添加到sys.modules?一个快速的test.py <“import sys; print sys.modules.keys()”,运行时会有其他建议! – ThomasH 2009-08-11 16:20:28

+0

将_imported_模块以真实名称添加到sys.modules中;作为“主程序”运行的一个文件取而代之的是传统名称“__main__”。但是,如果您将openid.py作为主模块运行,那么没有理由首先将它放在sys.path上! – 2009-08-12 00:58:37

2

我不会进入重命名上的论战,而是专注于你展示如何做你想做的(不管它是“对你有好处”或不;-)。解决方案并不难...

只需设置__path__!小演示:

$ mkdir /tmp/modules /tmp/packages 
$ mkdir /tmp/packages/openid 
$ echo 'print "Package!"' > /tmp/packages/openid/__init__.py 
$ gvim /tmp/modules/openid.py 
$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid' 
Module! 
Package! 

这显示了模块 OpenID的管理,即使该模块的路径来此前在sys.path中,sys.modules['openid']显然已经设置在那个时候导入同名。和所有的“秘密”是openid.py的简单的代码...:

print "Module!" 
__path__ = ['/tmp/packages'] 
import openid 

没有__path__分配,当然,也只是发出Module!

也适用于包内的进口,当然子模块。做:

$ echo 'print "Submod!"' > /tmp/packages/openid/submod.py 

并改变openid。PY的最后一行

from openid import submod 

,你会看到:

$ PYTHONPATH='/tmp/modules:/tmp/packages' python -c'import openid' 
Module! 
Package! 
Submod! 
$ 
+0

关于sys.modules ['openid']被设置。你也在另一个评论中这样说,但我不太确定。为什么会是这种情况?当前文件是否自动添加到sys.modules?一个快速的test.py <“导入sys;在sys.modules.keys()中打印'test',运行时会有其他建议! – ThomasH 2009-08-11 21:06:54

+0

正如我回复其他评论:作为主要模块运行的一个文件进入'sys.modules ['__ main __']'而不是(因为它的'__name__'被人为地和常规地设置为'__main__')。这就是为什么我在这里输入** openid来表示'__path__'仍然有效。如果所有你需要的w/openid.py是运行它为主,那么没有理由在sys.path中。 – 2009-08-12 01:01:05

+0

我认为OP的问题仅仅来自'。'这一事实。在sys.path中较早出现,所以在当前目录中搜索找到导入openid.py脚本的'openid'。但是,如果您将sys.path的“有趣”目录转移到其前面,则首先会找到另一个“openid”(模块),并且一切都很好。 – ThomasH 2009-08-12 08:10:37

相关问题