Python中的特殊方法以及应用详解


Posted in Python onSeptember 20, 2020

前言

Python 中的特殊方法主要是为了被解释器调用的,因此应该尽量使用 len(my_object) 而不是 my_object.__len__() 这种写法。在执行 len(my_object) 时,Python 解释器会自行调用 my_object 中实现的 __len__ 方法。

除非有大量的元编程存在,直接调用特殊方法的频率应远小于实现它们的次数。

模拟数值类型

可以通过在自定义对象中实现 __add__ 和 __mul__ 等特殊方法 ,令其支持 +、* 等运算符。

如下面的模拟向量的 Vector 类:

# vector.py
from math import hypot

class Vector:
  def __init__(self, x=0, y=0):
    self.x = x
    self.y = y

  def __repr__(self):
    return f'Vector({self.x}, {self.y})'

  def __abs__(self):
    return hypot(self.x, self.y)

  def __bool__(self):
    return bool(self.x or self.y)

  def __add__(self, other):
    return Vector(self.x + other.x, self.y + other.y)

  def __mul__(self, scalar):
    return Vector(self.x * scalar, self.y * scalar)

运行效果如下:

>>> from vector import Vector
>>> v1 = Vector(2, 4)
>>> v2 = Vector(2, 1)
>>> v1 + v2
Vector(4, 5)
>>> v = Vector(3, 4)
>>> abs(v)
5.0
>>> v * 3
Vector(9, 12)

对象的字符串表示

Python 有一个 repr 内置函数,能把一个对象用字符串的形式表示出来。实际上这种字符串表达是通过对象内部的 __repr__ 特殊方法定义的。默认情况下,在控制台里查看某个对象时,输出的字符串一般是 <xxx object at 0x7fc99d6ab2e0> 这种形式。

__repr__ 返回的字符串应该准确、无歧义,并尽可能表示出该对象是如何创建的。比如前面的 Vector 对象,其 __repr__ 中定义的字符串形式类似于 Vector(3, 4),和对象初始化的语法非常近似。

__repr__ 和 __str__ 的区别在于,__str__ 是在向对象应用 str() 函数(或者用 print 函数打印某个对象)时被调用。其返回的字符串对终端用户更友好。

如果只想实现其中一个特殊方法,__repr__ 应该是更优的选择。在对象没有实现 __str__ 方法的情况下,Python 解释器会用 __repr__ 代替。

# myclass.py
class MyClass:
  def __repr__(self):
    return 'MyClass'

  def __str__(self):
    return 'This is an instance of MyClass'
>>> from myclass import MyClass
>>> my = MyClass()
>>> my
MyClass
>>> print(my)
This is an instance of MyClass

自定义布尔值

Python 里有 bool 类型,但实际上任何对象都可以用在需要 bool 类型的上下文(比如 if 或 while 语句)中。为了判断某个值 x 的真假,Python 会调用 bool(x) 返回 True 或 False。

默认情况下,自定义类的实例总是为真。除非这个类对于 __bool__ 或 __len__ 方法有自己的实现。
bool(x) 实际上调用了对象 x 中的 __bool__ 方法。如不存在 __bool__ 方法,则 bool(x) 会尝试调用 x.__len__(),返回 0 则为 False,否则为 True。

# boolclass.py
class BoolClass:
  def __init__(self):
    self.list = []

  def add(self, item):
    self.list.append(item)

  def __len__(self):
    return len(self.list)
>>> from boolclass import BoolClass
>>> b = BoolClass()
>>> len(b)
0
>>> bool(b)
False
>>> b.add(1)
>>> len(b)
1
>>> bool(b)
True
# boolclass.py
class BoolClass:
  def __init__(self):
    self.list = []

  def add(self, item):
    self.list.append(item)

  def __len__(self):
    return len(self.list)

  def __bool__(self):
    return bool(sum(self.list))
>>> from boolclass import BoolClass
>>> b = BoolClass()
>>> b.add(1)
>>> len(b)
1
>>> bool(b)
True
>>> b.add(-1)
>>> len(b)
2
>>> bool(b)
False

参考资料

Fluent Python

总结

到此这篇关于Python中特殊方法以及应用详解的文章就介绍到这了,更多相关Python特殊方法及应用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python 图片验证码代码
Dec 07 Python
git使用.gitignore设置不生效或不起作用问题的解决方法
Jun 01 Python
python print 按逗号或空格分隔的方法
May 02 Python
python实现批量修改图片格式和尺寸
Jun 07 Python
django模板结构优化的方法
Feb 28 Python
django框架基于模板 生成 excel(xls) 文件操作示例
Jun 19 Python
Python产生一个数值范围内的不重复的随机数的实现方法
Aug 21 Python
python Canny边缘检测算法的实现
Apr 24 Python
python和js交互调用的方法
Jun 23 Python
python 8种必备的gui库
Aug 27 Python
详解用python -m http.server搭一个简易的本地局域网
Sep 24 Python
用Python实现定时备份Mongodb数据并上传到FTP服务器
Jan 27 Python
matplotlib 三维图表绘制方法简介
Sep 20 #Python
Python三维绘图之Matplotlib库的使用方法
Sep 20 #Python
scrapy利用selenium爬取豆瓣阅读的全步骤
Sep 20 #Python
Python操作dict时避免出现KeyError的几种解决方法
Sep 20 #Python
python中random.randint和random.randrange的区别详解
Sep 20 #Python
详解如何在pyqt中通过OpenCV实现对窗口的透视变换
Sep 20 #Python
Python Pillow(PIL)库的用法详解
Sep 19 #Python
You might like
一个阿拉伯数字转中文数字的函数
2006/10/09 PHP
简单介绍PHP非阻塞模式
2016/03/03 PHP
strpos() 函数判断字符串中是否包含某字符串的方法
2019/01/16 PHP
基于jquery的一个浮动框(扩展性比较好 )
2010/08/27 Javascript
js 事件处理函数间的Event物件是否全等
2011/04/08 Javascript
详谈JavaScript内存泄漏
2014/11/14 Javascript
jQuery背景插件backstretch使用指南
2015/04/21 Javascript
Jquery+Ajax+PHP+MySQL实现分类列表管理(下)
2015/10/28 Javascript
jQuery组件easyui基本布局实现代码
2016/08/25 Javascript
自制微信公众号一键排版工具
2016/09/22 Javascript
基于ionic实现下拉刷新功能
2018/05/10 Javascript
基于nodejs res.end和res.send的区别
2018/05/14 NodeJs
关于element-ui的隐藏组件el-scrollbar的使用
2019/05/29 Javascript
Layui 导航默认展开和菜单栏选中高亮设置的方法
2019/09/04 Javascript
react native 仿微信聊天室实例代码
2019/09/17 Javascript
在vue中使用jsx语法的使用方法
2019/09/30 Javascript
浅谈vue websocket nodeJS 进行实时通信踩到的坑
2020/09/22 NodeJs
[02:29]完美世界高校联赛上海赛区回顾
2015/12/15 DOTA
Python面向对象编程中关于类和方法的学习笔记
2016/06/30 Python
python在ubuntu中的几种安装方法(小结)
2017/12/08 Python
python使用Qt界面以及逻辑实现方法
2019/07/10 Python
解决jupyter notebook显示不全出现框框或者乱码问题
2020/04/09 Python
HTML5 播放 RTSP 视频的实例代码
2019/07/29 HTML / CSS
天猫超市:阿里巴巴打造的网上超市
2016/11/02 全球购物
英国书籍、CD、DVD和游戏的第一道德零售商:Awesome Books
2020/02/22 全球购物
学年自我鉴定范文
2013/10/01 职场文书
计算机专业大学生的自我评价
2013/11/14 职场文书
自我评价的写作规则
2014/01/06 职场文书
学生会副主席竞聘书
2014/03/31 职场文书
安全负责人任命书
2014/06/06 职场文书
乡镇消防安全责任书
2014/07/23 职场文书
教师节倡议书2015
2015/04/27 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书
高效笔记技巧分享:学会这些让你不再困扰
2019/09/04 职场文书
如何使用php生成zip压缩包
2021/04/21 PHP
分享很少见很有用的SQL功能CORRESPONDING
2022/08/05 MySQL