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使用urlparse分析网址中域名的方法
Apr 15 Python
python导入时小括号大作用
Jan 10 Python
Python正则替换字符串函数re.sub用法示例
Jan 19 Python
详解python之简单主机批量管理工具
Jan 27 Python
python 执行shell命令并将结果保存的实例
May 11 Python
Selenium控制浏览器常见操作示例
Aug 13 Python
wxPython的安装与使用教程
Aug 31 Python
基于python操作ES实例详解
Nov 16 Python
Pytorch DataLoader 变长数据处理方式
Jan 08 Python
K最近邻算法(KNN)---sklearn+python实现方式
Feb 24 Python
15个应该掌握的Jupyter Notebook使用技巧(小结)
Sep 23 Python
Python爬取微信小程序Charles实现过程图解
Sep 29 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
PHP 第一节 php简介
2012/04/28 PHP
PHP不用第三变量交换2个变量的值的解决方法
2013/06/02 PHP
thinkphp 字母函数详解T/I/N/D/M/A/R/U
2017/04/03 PHP
php使用curl实现简单模拟提交表单功能
2017/05/15 PHP
php 读写json文件及修改json的方法
2018/03/07 PHP
thinkphp5.0整合phpsocketio完整攻略(绕坑)
2018/10/12 PHP
PHP实现提高SESSION响应速度的几种方法详解
2019/08/09 PHP
PHP数据源架构模式之表入口模式实例分析
2020/01/23 PHP
jquery判断单个复选框是否被选中的代码
2009/09/03 Javascript
浅谈JavaScript编程语言的编码规范
2011/10/21 Javascript
ECMAScript5(ES5)中bind方法使用小结
2015/05/07 Javascript
js文字横向滚动特效
2015/11/11 Javascript
利用Vue.js指令实现全选功能
2016/09/08 Javascript
利用js的闭包原理做对象封装及调用方法
2017/04/07 Javascript
微信小程序实现导航栏选项卡效果
2020/06/19 Javascript
Vue实现简易翻页效果源码分享
2018/11/08 Javascript
js中console在一行内打印字符串和对象的方法
2019/09/10 Javascript
NodeJS http模块用法示例【创建web服务器/客户端】
2019/11/05 NodeJs
详谈Numpy中数组重塑、合并与拆分方法
2018/04/17 Python
python写日志文件操作类与应用示例
2019/07/01 Python
python 根据网易云歌曲的ID 直接下载歌曲的实例
2019/08/24 Python
python接入支付宝的实例操作
2020/07/20 Python
美国最大的城市服装和运动鞋零售商:Jimmy Jazz
2016/11/19 全球购物
阿里旅行:飞猪
2017/01/05 全球购物
美国存储和组织商店:The Container Store
2017/08/16 全球购物
警示教育活动总结
2014/05/05 职场文书
交通文明倡议书
2014/05/16 职场文书
保护环境的标语
2014/06/09 职场文书
2014广电局实施党的群众路线教育实践活动方案思想汇报
2014/09/22 职场文书
大学生翘课检讨书范文
2014/10/06 职场文书
党委书记个人检查对照材料思想汇报
2014/10/11 职场文书
中学生旷课检讨书500字
2014/10/29 职场文书
2014年语文教师工作总结
2014/12/18 职场文书
万能检讨书开头与结尾怎么写
2015/02/17 职场文书
摩登时代观后感
2015/06/03 职场文书
Python 数据可视化工具 Pyecharts 安装及应用
2022/04/20 Python