Python只导入包中的模块

Python只导入包中的模块,python,python-import,relative-import,Python,Python Import,Relative Import,我正在创建一个包含多个模块的Python包。我想确保在导入包内的模块时,它们只从包中导入,而不是从包外导入具有相同名称的模块 正确的方法是使用相对导入吗?当我将包移动到机器上的其他位置或安装到客户机器上的任何位置时,这会产生干扰吗?sys.path告诉python在何处查找导入 加 在主python脚本的顶部,这将确保在内置包之前导入本地包,尽管我认为这是自动发生的 如果确实要仅导入文件夹中的包,请执行以下操作: import sys sys.path = ["."] 然而,我不推荐这一切,因

我正在创建一个包含多个模块的Python包。我想确保在导入包内的模块时,它们只从包中导入,而不是从包外导入具有相同名称的模块

正确的方法是使用相对导入吗?当我将包移动到机器上的其他位置或安装到客户机器上的任何位置时,这会产生干扰吗?

sys.path告诉python在何处查找导入

在主python脚本的顶部,这将确保在内置包之前导入本地包,尽管我认为这是自动发生的

如果确实要仅导入文件夹中的包,请执行以下操作:

import sys
sys.path = ["."]
然而,我不推荐这一切,因为它可能会打破你的东西很多

大多数IDE的eclipse/pycharm/etc提供了设置项目使用的环境(包括其路径)的机制

实际上,最好的选择是不要将软件包命名为与系统上安装的内置软件包或第三方模块相同的名称

另外,最好的选择是通过一个正确绑定的包分发它,这应该足以满足sys.path告诉python在哪里查找导入

在主python脚本的顶部,这将确保在内置包之前导入本地包,尽管我认为这是自动发生的

如果确实要仅导入文件夹中的包,请执行以下操作:

import sys
sys.path = ["."]
然而,我不推荐这一切,因为它可能会打破你的东西很多

大多数IDE的eclipse/pycharm/etc提供了设置项目使用的环境(包括其路径)的机制

实际上,最好的选择是不要将软件包命名为与系统上安装的内置软件包或第三方模块相同的名称

另外,最好的选择是通过一个正确捆绑的包来分发,这应该足够了

现代相对导入是包相关的和包特定的,因此只要包的内部结构没有改变,您就可以将包作为一个整体移动到任何您想要的地方

虽然在Python的旧版本中,绝对导入不是默认的,但是应该也可以工作,因为旧的导入方式首先在包的目录中进行检查,我个人并不喜欢在不需要的情况下修改导入路径,尤其是当您需要加载模块或包现在所隐藏的其他一些包或模块时

但是,警告:这些确实要求所讨论的模块作为包的一部分加载,或者至少将其_name__设置为指示包中的位置。当uuu name_uuuu=='uuuu main_uuuuu'时,相对导入对模块不起作用,因此,如果您正在编写一个简单/临时脚本,该脚本使用与它相同的目录中的另一个模块,并且希望确保脚本将引用正确的目录,那么如果当前工作目录未设置为脚本的,你可以做一些像导入操作系统,系统;sys.path.insert0,os.path.dirnameos.path.abspath\uuuu文件\uuuu,感谢您的创意。如中所述,这可能不是您希望专业地或作为团队项目的一部分来做的事情,但是对于您个人来说,如果您只是在做一些琐碎的任务自动化或诸如此类的事情,这应该是很好的。

现代相对导入是包相关和包特定的,因此,只要包的内部结构没有改变,您就可以将包作为一个整体移动到任何您想要的地方

虽然在Python的旧版本中,绝对导入不是默认的,但是应该也可以工作,因为旧的导入方式首先在包的目录中进行检查,我个人并不喜欢在不需要的情况下修改导入路径,尤其是当您需要加载模块或包现在所隐藏的其他一些包或模块时


但是,警告:这些确实要求所讨论的模块作为包的一部分加载,或者至少将其_name__设置为指示包中的位置。当uuu name_uuuu=='uuuu main_uuuuu'时,相对导入对模块不起作用,因此,如果您正在编写一个简单/临时脚本,该脚本使用与它相同的目录中的另一个模块,并且希望确保脚本将引用正确的目录,那么如果当前工作目录未设置为脚本的,你可以做一些像导入操作系统,系统;sys.path.insert0,os.path.dirnameos.path.abspath\uuuu文件\uuuu,感谢您的创意。如中所述,这可能不是你想专业地或作为团队项目的一部分来做的事情,但对于个人来说,如果你只是在做一些琐碎的任务自动化之类的事情,这应该是好的。

我同意把包命名为
与第三方或内置软件包相同,但这几乎是不可能的。例如:我不知道其他人的机器上会有什么软件包。这几乎是不可能的,它应该相对容易避免命名冲突,至少与内置和大多数第三方模块。。。每一个开发人员都会很轻松地完成它。。。类名可以相同,只需使用Myapp_用户的唯一文件名导入用户例如,我同意将包命名为与第三方或内置包相同是个坏主意,但这几乎是不可能的。例如:我不知道其他人的机器上会有什么软件包。这几乎是不可能的,它应该相对容易避免命名冲突,至少与内置和大多数第三方模块。。。每一个开发人员都会很轻松地完成它。。。类名可以相同,只需使用Myapp_用户的唯一文件名导入用户例如,我同意他可能不应该用我给出的方法修改它作为示例。。。我试图说清楚:P@JoranBeasley我主要指的是你答案的第一部分,尽管第二部分的危险性比你想象的要小,即使你使用sys.path=[],内置的包和模块似乎仍然可用,并且你可以随时切换任何必要的导入以使用底层的_导入_;函数,我刚刚意识到,如果当前工作目录在执行过程中发生更改,那么您的版本可能无法正常工作。但是,像这样的方法可以解决这个问题。在创建/调试模块时,我经常使用if _uname _u=='_umain_uu':功能。从你的评论来看,如果我使用相对导入,我似乎无法做到这一点。正确吗?@Jeremy很遗憾没有,但是有一些方法可以避免使用模拟包、设置_init__; py来做事情等,并且您可以始终在条件中使用绝对导入。最简单的方法可能是将uuu name uuuuu设置为导入到uuuu main uuu中的任何模块的包使用时的实际情况,这可能会让您避免一些问题。至少,如果这成为一个问题,我可能会这么做。我同意他可能不应该用我举的例子来修改它。。。我试图说清楚:P@JoranBeasley我主要指的是你答案的第一部分,尽管第二部分的危险性比你想象的要小,即使你使用sys.path=[],内置的包和模块似乎仍然可用,并且你可以随时切换任何必要的导入以使用底层的_导入_;函数,我刚刚意识到,如果当前工作目录在执行过程中发生更改,那么您的版本可能无法正常工作。但是,像这样的方法可以解决这个问题。在创建/调试模块时,我经常使用if _uname _u=='_umain_uu':功能。从你的评论来看,如果我使用相对导入,我似乎无法做到这一点。正确吗?@Jeremy很遗憾没有,但是有一些方法可以避免使用模拟包、设置_init__; py来做事情等,并且您可以始终在条件中使用绝对导入。最简单的方法可能是将uuu name uuuuu设置为导入到uuuu main uuu中的任何模块的包使用时的实际情况,这可能会让您避免一些问题。至少,如果这成为一个问题,我可能会这么做。