Python Pitfalls: Passing and Using Class vs. Class Object Type Parameters
Preface For beginners, Python is indeed simple and easy to use. After all, it's a dynamically typed language—you can use things without defining them, and freely converting between types couldn't be more convenient. So using Python to write small scripts, crawlers, and the like is no problem. However, once you use it to develop a slightly larger project, such as building a web application, you'll run into some issues. People who generally lack experience will fall into certain pitfalls. = =... Pitfalls Let's talk about the pitfalls first. Function parameter types are one pitfall, and classes versus class objects are another. Although I had figured this out when using other statically typed languages (such as C
目录3 个章节
Preface
For beginners, Python is indeed simple and easy to use. After all, it's a dynamically typed language—you can use things without defining them, and freely converting between types couldn't be more convenient. So using Python to write small scripts, crawlers, and the like is no problem. However, once you use it to develop a slightly larger project, such as building a web application, you'll run into some issues. People who generally lack experience will fall into certain pitfalls. = =...
Pitfalls
Let's talk about the pitfalls first. Function parameter types are one pitfall, and classes versus class objects are another. Although I had figured this out when using other statically typed languages (such as C#/Java), switching to dynamically typed Python always leaves one a bit puzzled.
Example
Let me illustrate with code.
First, define two classes, both inheriting from the built-in Exception class, which means these two classes are exception classes.
class Error1(Exception):
def __str__(self):
return 'error1'
class Error2(Exception):
def __init__(self):
print('error2 init')
def __str__(self):
return 'error2'
Then define methods for handling exceptions:
def error(err: object):
print(f'err:{err.__str__()}')
def error2(err: Exception):
print(err)
Next is the test code:
try:
raise Error1
except Error1 as e:
error(e)
if 1 != 2:
error(Error2)
Running result:
err:error1
File "/home/test.py", line 33, in <module>
error(Error2)
File "/home/test.py", line 19, in error
print(f'err:{err.__str__()}')
TypeError: __str__() missing 1 required positional argument: 'self'
The result of the first error() is fine, but the second one then threw an exception. Let's look at the error message first: TypeError: __str__() missing 1 required positional argument: 'self'. The self parameter was not provided, because this argument is not an instance of the Error2 class, so naturally there is no self parameter.
At this point you should have some idea: when calling the error(Error2) method, the Error2 argument passed in is actually the Error2 type itself, not an object of it. It's a bit magical that you can actually use a type as an argument.
So how do we solve this? It's simple: just pass in an object of Error2.
The code is as follows:
if 1 != 2:
error(Error2())
Running result
error2 init
err:error2
No problem now. There's still an error2 method in the code above that hasn't been used. Let's try it.
error2(Error2)
error2(Error2())
Running result
<class '__main__.Error2'>
error2 init
error2
As you can see, when using print(Object), if it's a type, it prints information about that type; only when it's an object of the type will it print the result returned by Object.__str__().
Once you understand it, it's actually quite simple. But Python doesn't restrict function parameters. Even if you add type hints to methods, they only serve as hints and don't actually enforce restrictions or implicit conversions. So sometimes after writing code for a long time and getting dizzy, it's easy to fall into the dynamic typing pit T_T...
As is international custom, here's an image:

_EOF_
Python Pitfalls: Passing and Using Class vs. Class Object Type Parameters
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
自己动手开发简单消息队列(异步任务队列):Python实现
又是造轮子系列咯,Python上有很多成熟完善的异步任务队列框架可以用,比如Celery,或者RQ,不过这些都不自带消息队列服务,都需要使用Redis、RabbitMQ之类的消息队列才行,我用到小项目中又不需要附带这么多东西,于是自己动手来实现咯。 思路 将需要异步执行的任务添加到队列 自动从队列中取出任务,创建新线程执行 保存任务的执行结果和输出 任务完成,调用回调函数,处理返回的数据 使用输出
2021-12-18 · Python · 约 1 分钟
关于Python的异常处理
前言 异常处理在任何一门编程语言里都是值得关注的一个话题,良好的异常处理可以让你的程序更加健壮,清晰的错误信息更能帮助你快速修复问题。在Python中,和部分高级语言一样,使用了try/except/finally语句块来处理异常,如果你有其他编程语言的经验,实践起来并不难。 Python 中(至少)有两种错误:语法错误和异常( syntax errors 和 exceptions )。下面稍微介
2022-05-27 · Python · 约 1 分钟
python实现解析markdown文档中的图片,并且保存到本地~
背景 前阵子简书好像说是凉了,搞得我有点小慌,毕竟我的大部分博客都是放在简书上面的,虽然简书提供了打包导出功能,但是只能导出文字,图片的话还是存在简书服务器上面,再加上我一直想要重新做一个个人博客,于是就有了这篇文章。 思路 首先是要解析markdown文档,然后获取到其中的所有图片,再把图片按md文件分好目录保存。 解析markdown文档 这里我用了misaka模块,据说是python的mar
2021-12-18 · Python · 约 1 分钟
Python中的三元表达式
一般语言的三元表达式都是这种形式: result = statement ? true : false // For examle result = a b ? a : b Python中的三元表达式比较特殊,用下面这种形式 result = true if statement else false # For example result = a if a b else b
2022-05-27 · Python · 约 1 分钟
讨论
共 0 条加载评论中…