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中使用item()方法遍历字典的例子
Aug 26 Python
python模拟鼠标拖动操作的方法
Mar 11 Python
Python抽象和自定义类定义与用法示例
Aug 23 Python
Python父目录、子目录的相互调用方法
Feb 16 Python
详解pandas的外部数据导入与常用方法
May 01 Python
在django中实现页面倒数几秒后自动跳转的例子
Aug 16 Python
Python 通过截图匹配原图中的位置(opencv)实例
Aug 27 Python
django框架创建应用操作示例
Sep 26 Python
python文件绝对路径写法介绍(windows)
Dec 25 Python
python自动点赞功能的实现思路
Feb 26 Python
python对指定字符串逆序的6种方法(小结)
Apr 02 Python
python神经网络学习 使用Keras进行回归运算
May 04 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 mail()函数使用及配置方法
2014/01/14 PHP
php 调用ffmpeg获取视频信息的简单实现
2017/04/03 PHP
图片连续滚动代码[兼容IE/firefox]
2009/06/11 Javascript
JSQL SQLProxy 的 php 版本代码
2010/05/05 Javascript
jquery(live)中File input的change方法只起一次作用的解决办法
2011/10/21 Javascript
jquery中插件实现自动添加用户的具体代码
2013/11/15 Javascript
jquery实现瀑布流效果分享
2014/03/26 Javascript
JS获取网页属性包括宽、高等等
2014/04/03 Javascript
jQuery .tmpl() 用法示例介绍
2014/08/21 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
2015/10/08 Javascript
JS仿淘宝实现的简单滑动门效果代码
2015/10/14 Javascript
JavaScript学习笔记整理_用于模式匹配的String方法
2016/09/19 Javascript
利用VUE框架,实现列表分页功能示例代码
2017/01/12 Javascript
angular.js+node.js实现下载图片处理详解
2017/03/31 Javascript
防止页面url缓存中ajax中post请求的处理方法
2017/10/10 Javascript
详解原生JS回到顶部
2019/03/25 Javascript
小程序获取当前位置加搜索附近热门小区及商区的方法
2019/04/08 Javascript
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
2019/05/01 Javascript
详解Vue前端生产环境发布配置实战篇
2019/05/07 Javascript
vue打开子组件弹窗都刷新功能的实现
2020/09/21 Javascript
Python中optparser库用法实例详解
2018/01/26 Python
tensorflow实现简单的卷积神经网络
2018/05/24 Python
在Python中Dataframe通过print输出多行时显示省略号的实例
2018/12/22 Python
wxpython+pymysql实现用户登陆功能
2019/11/19 Python
Django REST framwork的权限验证实例
2020/04/02 Python
Python+Kepler.gl实现时间轮播地图过程解析
2020/07/20 Python
2014五一国际劳动节活动总结范文
2014/04/14 职场文书
公司节能减排方案
2014/05/16 职场文书
出国签证在职证明
2014/09/20 职场文书
2014年纪检部工作总结
2014/11/12 职场文书
质检员岗位职责
2015/02/03 职场文书
2015大学生自我评价范文
2015/03/03 职场文书
2015年公务员工作总结
2015/04/24 职场文书
python常见的占位符总结及用法
2021/07/02 Python
redis sentinel监控高可用集群实现的配置步骤
2022/04/01 Redis