克服python中无法预料的问题

I learned Python after learning Java and C++, which led to me spending most of my serpentine-coding career believing that the functionality of Python’s import statement was fundamentally identical to imports in other languages. Oh man, was I wrong. After hours of blood, sweat, and tears, I’ve come to learn that — if you’re not careful — this six-lettered demon will destroy any and all hopes that you have of creating production-level code (burning hours of your time in the process). Not wanting others to suffer the same woes that I did, I decided to put together an article detailing the issue that plagued me and how I found a way through it.

在学习Java和C ++之后,我学习了Python,这使我度过了大部分的蛇形编码生涯,并认为Python的import语句的功能与其他语言的import基本相同。 哦,老兄,我错了。 经过数小时的流血,汗水和眼泪,我学会了-如果您不小心的话,这个六字母恶魔将摧毁您创建生产级代码的所有希望(燃烧您的小时数)。时间)。 我不想让别人遭受与我同样的痛苦,所以我决定写一篇文章,详细介绍困扰我的问题以及如何找到解决方法。

问题 (The Problem)

While developing a library on Python’s package manager (PIP), I ran into two error messages consistently:

在Python的包管理器(PIP)上开发库时,我始终遇到两个错误消息:

ModuleNotFoundError: No module named 'XXXXX'# ORImportError: attempted relative import with no known parent package

These errors come from Python’s interpreter not being able to locate an imported file. For example, if I import the file testclass:

这些错误来自Python的解释器无法找到导入的文件。 例如,如果我导入文件testclass

import testclass

and Python can’t find it, it will give you a ModuleNotFoundError . Seems pretty standard, so what’s the issue? And how does the ImportError come in?

而Python找不到它,它将为您提供ModuleNotFoundError 。 看起来很标准,那是什么问题呢? 以及ImportError如何进入?

In some cases (or all if you’re creating PIP packages), Python won’t find the file even if it’s in the same directory. This means that you can import a script/module from the same directory but Python won’t recognize it. To make matters even worse, an import might work in testing but break horribly in production — especially if you use relative imports:

在某些情况下(如果创建的是PIP软件包,则全部为Python),即使文件位于同一目录中,Python也找不到。 这意味着您可以从同一目录导入脚本/模块,但是Python无法识别它。 更糟糕的是,导入可能会在测试中起作用,但会在生产中造成严重破坏—尤其是在使用相对导入时:

from . import testclass# ORimport .testclass

Now let’s look at why this happens and how we can fix it.

现在让我们看看为什么会发生这种情况以及如何解决它。

PYTHONPATH难题 (The PYTHONPATH Conundrum)

It turns out that this is an issue related to how Python searches for files. For example, when you import the file

事实证明,这是与Python搜索文件有关的问题。 例如,当您导入文件时

import testclass

Python will first search through a list of installed packages such as requests or collections . If it doesn’t find testclass , it will search other folders in your PYTHONPATH (this is a collection of locations where your file may be). However, your current folder might not be added to your PYTHONPATH if you’re creating a module/package, and the chance of theimport failing rises tremendously if the file isn’t in the same directory.

Python将首先搜索已安装软件包的列表,例如requestscollections 。 如果找不到testclass ,它将搜索您的PYTHONPATH中的其他文件夹(这是文件可能位于的位置的集合)。 但是,您当前的文件夹可能未添加到您的PYTHONPATH中 如果您要创建模块/软件包,并且文件不在同一目录中,则import失败的可能性会大大增加

If you attempt to access a parent folder using relative imports, you’ll get the aforementioned error message:

如果您尝试使用相对导入来访问父文件夹,则会收到上述错误消息:

ImportError: attempted relative import with no known parent package

You’re almost guaranteed to run into this issue if you create any package that you wish to distribute through the “Python Package” manager (PIP). Thankfully the solution is quick and easy.

如果您创建希望通过“ Python软件包”管理器(PIP)分发的任何软件包,几乎可以肯定会遇到此问题。 幸运的是,该解决方案既快速又简单。

解决方案 (The Solution)

Searching this issue will most likely yield outdated and conflicting information. The easiest and quickest solution to this problem is to directly add the missing locations to your PYTHONPATH as follows:

搜索此问题很可能会产生过时且冲突的信息。 解决此问题的最简单,最快的方法是将缺少的位置直接添加到PYTHONPATH中,如下所示:

  1. Find the entry-point of your program (the file you run)

    查找程序的入口点(运行的文件)
  2. Before all your other imports, import the os library

    在所有其他导入之前,请导入os

  3. Manually add all the paths that you wish to import from

    手动添加您要从中导入的所有路径

An example would look like this:

一个示例如下所示:

import os# the current directory
sys.path.append(os.path.abspath(os.path.dirname(__file__))) # a folder on the same level in the project
sys.path.append(os.path.abspath("../testfolder"))# now this will work
import testclass# rest of your code

概要 (Summary)

Due to a lack of understanding on my part, I found myself facing confusing issues when writing in Python. Happily, there are work throughs for these problems. As explored in this article, one such solution to use if you’re creating any library or project that you wish to distribute is to use sys.path.append to add all the paths that you’ll need to import from (otherwise, you’ll risk running into inconsistencies and errors). Thank you for spending this reading this article, I hope you found it helpful.

由于缺乏理解,我发现自己在用Python编写时遇到混乱的问题。 幸运的是,有解决这些问题的方法。 正如本文中探讨的那样,如果要创建要分发的任何库或项目,则可以使用的一种这样的解决方案是使用sys.path.append添加您需要从中导入的所有路径(否则,您可以可能会出现不一致和错误的风险)。 感谢您花费本文阅读本文,希望对您有所帮助。

翻译自: https://codeburst.io/overcoming-an-unforeseen-issue-in-python-52eaa1de83db

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值