python滥用eval_不要滥用除Python外的尝试

python滥用eval

Like most of the other programming language, Python supports catching and handling exceptions during runtime. However, sometimes I found that it has been overused.

像大多数其他编程语言一样,Python支持在运行时捕获和处理异常。 但是,有时我发现它已被过度使用。

It turns out that some developers, especially those who are newbies in Python, tend to use try … except … a lot, once they found such a feature. However, I would say that we should try to avoid using that if possible, especially during the early stage of the development. You will find that it is actually better to let the problem reveal, rather than hide it.

事实证明,一旦发现了这样的功能,一些开发人员,尤其是那些使用Python的新手,往往会尝试使用try…除了…以外的很多方法。 但是,我要说的是,如果可能的话,我们应该尽量避免使用它,尤其是在开发的早期阶段。 您会发现,让问题揭示而不是隐藏问题实际上更好。

In this article, I will demonstrate some examples to show how try … except … can create problems and what is the better manner in Python programming.

在本文中,我将演示一些示例,以展示…除了…可能会产生问题以及Python编程中更好的方式是什么。

问题定义 (Problem Definition)

Image for post
Photo by geralt on Pixabay
照片由 GeraltPixabay发布

Let’s start with a problematic example, which is a very typical scenario that I have seen.

让我们从一个有问题的示例开始,这是我所看到的一个非常典型的场景。

def f1(num):
try:
return (num+1)*2
except Exception as e:
print('Error: ', e)def f2(num):
try:
return (num+1)*3
except Exception as e:
print('Error: ', e)def f3(num):
try:
return (num+1)*4
except Exception as e:
print('Error: ', e)

We have three functions that do some simple numerical calculations. All of them are implemented with try … except … with everything. Then, we want to use them in our code as follows.

我们有三个函数可以执行一些简单的数值计算。 所有这些都可以通过try来实现……除了……一切都可以实现。 然后,我们要在我们的代码中使用它们,如下所示。

num1 = f1(5)
num2 = f2('5')
num3 = f3(5)

Please note that I deliberately pass a string “5” in the second function, because I just want to create an exception artificially. The result we have is as follows.

请注意,我故意在第二个函数中传递字符串“ 5”,因为我只是想人为地创建一个异常。 我们得到的结果如下。

Image for post

Well, here we have only a few lines of code. It is not to difficult to realise the problem, perhaps. However, imagine that you are doing a project has a much larger scale, the error message must be str, not int will not be very helpful for you to locate the problem.

好吧,这里我们只有几行代码。 也许不难意识到问题。 但是,假设您正在做的项目规模更大,错误消息must be str, not int不会对您找到问题很有帮助。

另一个例子 (Another Example)

Image for post
guvo59 on guvo59Pixabay Pixabay上

The error message we can get from the exception object e is sometimes very limited. I would say that it does not always make sense in Python. In fact, the previous one is not too bad because at least it tells you why the error happened. Let’s see this one.

我们有时从异常对象e得到的错误消息非常有限。 我会说这在Python中并不总是有意义。 实际上,上一个还不错,因为至少它告诉您错误发生的原因。 让我们看看这个。

def f4(key):
try:
d = {'a': 1, 'b': 2}
return d[key]
except Exception as e:
print('Error: ', e)f4('c')
Image for post

Of course, in this example we have only one line of code, we definitely know what is the “c”. However, again, if this happens in a project, how could we troubleshoot the problem if we were only given an error message “c”?

当然,在此示例中,我们只有一行代码,我们肯定知道什么是“ c”。 但是,如果在项目中发生这种情况,又给我们一个错误消息“ c”,我们如何解决该问题呢?

最坏的情况 (The Worst-Case)

Image for post
Photo by Ramdlon on Pixabay
照片由 RamdlonPixabay发布

Can you imagine that the case can be worse? Well, this one might not be 100% related to our topic, but I just want to present it because it can be potentially solved by the solutions in the later section.

您能想象情况会更糟吗? 嗯,这可能与我们的主题并非100%相关,但我只想介绍它,因为下一部分的解决方案可以解决它。

Do you think it gonna be very safe if we put all of the code in the try block and catch all the generic exceptions in the except block? The answer is definitely no. Otherwise, I will probably recommend using it everywhere :)

如果我们将所有代码放在try块中并在except块中捕获所有通用异常,您认为这会非常安全吗? 答案是肯定的。 否则,我可能会建议在各处使用它:)

Let’s see this example.

让我们来看这个例子。

def f5(num):
try:
return num*3
except Exception as e:
print('Error: ', e)num = f5('5')
print('Result is', num)

Again, we define a very simple numerical computing function and pass a string into it. We might expect that the “exception” will be caught, but there is actually no exception.

同样,我们定义了一个非常简单的数值计算函数,并将一个字符串传递给它。 我们可能希望会捕获到“例外”,但实际上没有例外。

Image for post

Python is too flexible to have an error :)

Python太灵活了,不会出现错误:)

丑陋的解决方案:追溯库 (Ugly Solution: Traceback Library)

Image for post
Photo by geralt on Pixabay
照片由 geraltPixabay发布

If you really want to try all your code and catch the exceptions, you can use the traceback library which is built-in Python. Let’s use the same examples as above shown.

如果您真的想尝试所有代码并捕获异常,则可以使用内置的Python traceback库。 让我们使用上面显示的相同示例。

import tracebackdef f4(key):
try:
d = {'a': 1, 'b': 2}
return d[key]
except Exception as e:
e = traceback.format_exc()
print('Error: ', e)f4('c')
Image for post

Using traceback helped us to print more information about the error, so it will be easier for us to troubleshoot the problem. However, we need to import an extra library and write more code to do this.

使用回溯可以帮助我们打印有关该错误的更多信息,因此我们可以更轻松地解决问题。 但是,我们需要导入一个额外的库并编写更多代码来执行此操作。

Just need to think twice whether it is really worth to do this? Let’s see some other good manners.

只是需要三思而行,这样做是否真的值得? 让我们看看其他一些好的举止。

解决方案0:不要抓住它 (Solution 0: Do Not Catch It)

Image for post
Photo by lechenie-narkomanii on Pixabay
照片由 lechenie-narkomaniiPixabay发布

This section is added just in case someone will say something like:

添加此部分是为了防止有人说以下内容:

why use raise or assert? The full traceback stack will be simply displayed if you don’t use try … except … at all!

为什么要使用raise或assert? 如果不使用try…完全除外,将仅显示完整的回溯堆栈!

Indeed, this is what I want to say in this article. It is exactly the solution to the title “Do not abuse try … except … in Python”. The reason that I provide the two “solutions” below is just want to demonstrate what is the good manner.

确实,这就是我在本文中要说的。 这正是标题“请勿滥用………Python中的……”的解决方案。 我在下面提供两个“解决方案”的原因只是想证明什么是好的方法。

解决方案1:引发异常 (Solution 1: Raise Exception)

Image for post
Photo by Pezibear on Pixabay
照片由 PezibearPixabay发布

As I said earlier, we should avoid using too much try … except … which can hide the exceptions. In contrast, we would like to have the exception reveal as much as possible. Using raise to manually raise an exception is one of a good manner.

就像我之前说的,我们应该避免使用过多的try ...,因为…可能会隐藏异常。 相反,我们希望让异常尽可能多地显示出来。 使用raise手动引发异常是一种很好的方法。

Let’s modify our f1, f2 and f3 functions.

让我们修改f1f2f3函数。

INVALID_NUM_EXCEPTION = Exception('The parameter must be integer!')def f1(num):
if type(num) != int:
raise INVALID_NUM_EXCEPTION
return (num+1)*2def f2(num):
if type(num) != int:
raise INVALID_NUM_EXCEPTION
return (num+1)*2def f3(num):
if type(num) != int:
raise INVALID_NUM_EXCEPTION
return (num+1)*2

Here, we defined an exception and raise it in the functions when the type of arguments passed in are not an integer.

在这里,我们定义了一个异常,并在传入的参数类型不是整数时在函数中引发它。

Then, let’s run the same code to use these functions.

然后,让我们运行相同的代码来使用这些功能。

num1 = f1(5)
num2 = f2('5')
num3 = f3(5)
Image for post

It is not too bad to meet an error if it tells you what is the error exactly and where did that happen.

如果错误告诉您确切的错误是什么以及在哪里发生的,那么遇到错误也不错。

解决方案2:断言 (Solution 2: Assertion)

Image for post
Photo by aitoff on Pixabay
照片由 aitoffPixabay发布

Although assertion is more often used in testing, we can still use it during development to make sure that our code has fewer bugs. Also, it is usually kind of neat to use assertion than raising an exception, if we don’t really care what’s the exact exception type.

尽管断言在测试中更经常使用,但是我们仍然可以在开发过程中使用断言,以确保我们的代码具有更少的错误。 另外,如果我们不太在意确切的异常类型是什么,那么使用断言通常比抛出异常要好。

INVALID_NUM_MSG = 'The parameter must be integer!'def f1(num):
assert isinstance(num, int), INVALID_NUM_MSG
return (num+1)*2def f2(num):
assert isinstance(num, int), INVALID_NUM_MSG
return (num+1)*2def f3(num):
assert isinstance(num, int), INVALID_NUM_MSG
return (num+1)*2
Image for post

摘要 (Summary)

Image for post
pasja1000 on pasja1000Pixabay Pixabay上

It is good to know more tricks in a programming language. I have to say that whenever I know something cool, I would also tend to use it. However, it also needs to think twice whether we need to do this and if that trick gives us more benefit than barriers.

最好了解编程语言中的更多技巧。 我不得不说,每当我知道一些很棒的东西时,我也会倾向于使用它。 但是,它还需要三思而行,我们是否需要这样做,以及这种窍门是否给我们带来的好处多于障碍。

Therefore, do not put all your code in the try … except … block in Python. Let the error reveal and make our life easier!

因此,请勿将所有代码都放入try…Python块中...除外。 让错误揭示出来,让我们的生活更轻松!

翻译自: https://towardsdatascience.com/do-not-abuse-try-except-in-python-d9b8ee59e23b

python滥用eval

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值