Python进阶学习之特殊方法实例详析


Posted in Python onDecember 01, 2017

前言

最近在学习python,学习到了一个之前没接触过的--特殊方法。

什么是特殊方法?当我们在设计一个类的时候,python中有一个用于初始化的方法$__init__$,类似于java中的构造器,这个就是特殊方法,也叫作魔术方法。简单来说,特殊方法可以给你设计的类加上一些神奇的特性,比如可以进行python原生的切片操作,迭代、连乘操作等。在python中,特殊方法以双下划线开始,以双下划线结束。

一个大例子

数学中有一个表示数的概念叫做向量,但是python中的数据类型却没有。我们来设法用python实现它。

首先考虑,向量跟普通的数据类型不同,传统的数可以直接进行运算,向量则需要对不同的坐标分别运算。来试试。

首先定义一个类,实现初始化方法。

# 实现向量类型
class Vector:
 
 def __init__(self, x=0, y=0):
  self.x = x
  self.y = y

如何实现向量的加法?二维向量中,向量的加法就是每个坐标分别相加得到的结果。在python中有个$__add__$方法,用来进行加法操作。

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

 # 实现向量加法
 def __add__(self, other):
  x = self.x + other.x
  y = self.y + other.y
  return Vector(x, y)

我们对x和y变量分别进行相加,然后返回Vector。在python你可以对字符串直接用加法拼接起来的原理就在此,python实现了针对字符串的add方法。

实现了加法,乘法的道理一样,分别对每个坐标单独相乘即可。

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

 # 实现向量加法
 def __add__(self, other):
  x = self.x + other.x
  y = self.y + other.y
  return Vector(x, y)
 
 # 实现向量乘法,例如r*3
 def __mul__(self, scalar):
  return Vector(self.x*scalar, self.y*scalar)

我们在进行向量运算时还有一个常用的操作是求向量的模,我们用$__abs__$特殊方法来实现,abs一般用来求一个数的绝对值,向量用不到,用来求模刚好合适。使用math模块中的hypot方法计算$\sqrt(x^2+y^2)$。

class Vector:
 
 def __init__(self, x=0, y=0):
  self.x = x
  self.y = y
 
 # 真假值,如果向量模为0,返回false
 def __bool__(self):
  return bool(abs(self))

 # 实现向量加法
 def __add__(self, other):
  x = self.x + other.x
  y = self.y + other.y
  return Vector(x, y)
 
 # 实现向量乘法,例如r*3
 def __mul__(self, scalar):
  return Vector(self.x*scalar, self.y*scalar)

 
 # 返回向量的模
 # hypot()返回欧几里德范数 sqrt(x*x + y*y)
 def __abs__(self):
  return hypot(self.x, self.y)

找个例子运行下。

v = Vector(2, 3)
print(v)
v2 = Vector(4, 5)
print(v+v2)
print(v+v2*2)
<__main__.Vector object at 0x000002B4B1843C50>
<__main__.Vector object at 0x000002B4B1843EF0>
<__main__.Vector object at 0x000002B4B1843898>

可以运行了,貌似是正确的,但是输出的结果很奇怪。怎么办?python中有个$__repr__$特殊方法,可以修改控制台输出的样式。

class Vector:
 
 def __init__(self, x=0, y=0):
  self.x = x
  self.y = y
 
 # 真假值,如果向量模为0,返回false
 def __bool__(self):
  return bool(abs(self))

 # 实现向量加法
 def __add__(self, other):
  x = self.x + other.x
  y = self.y + other.y
  return Vector(x, y)
 
 # 实现向量乘法,例如r*3
 def __mul__(self, scalar):
  return Vector(self.x*scalar, self.y*scalar)
 
 # 返回向量的模
 # hypot()返回欧几里德范数 sqrt(x*x + y*y)
 def __abs__(self):
  return hypot(self.x, self.y)
 
 # 实现__repr__方法,在控制台打印向量时会输出Vector(1, 2)
 # 实现__str__,使用str()返回字符串
 def __repr__(self):
  return 'Vector(%r, %r)' % (self.x, self.y)

实现了$__repr__$方法,我们就可以在控制台输出Vecotor(x,y)。与之对应的有个$__str__$方法,使用str()返回相应的字符串,展示给用户。

现在来看下之前程序运行的结果。

v = Vector(2, 3)
print(v)
v2 = Vector(4, 5)
print(v+v2)
print(v+v2*2)
print(abs(v))
Vector(2, 3)
Vector(6, 8)
Vector(10, 13)
3.605551275463989

效果不错。

通过实现特殊方法,自定义类型可以表现的跟内置类型一样,让我们能够写出更具有python风格的代码。

除了上面说到的几个特殊方法外,python还有差不多80多个特殊方法,比如$__len__$方法可以用来求长度,$__getitem__$可以使用haha[2]之类的操作进行切片和迭代等,同样的还有$__setitem__$。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
学习python (1)
Oct 31 Python
Python 搭建Web站点之Web服务器与Web框架
Nov 06 Python
python数据结构链表之单向链表(实例讲解)
Jul 25 Python
Python网络爬虫神器PyQuery的基本使用教程
Feb 03 Python
Python计算开方、立方、圆周率,精确到小数点后任意位的方法
Jul 17 Python
Python数据可视化教程之Matplotlib实现各种图表实例
Jan 13 Python
基于Django ORM、一对一、一对多、多对多的全面讲解
Jul 26 Python
Django 在iframe里跳转顶层url的例子
Aug 21 Python
django-rest-swagger的优化使用方法
Aug 29 Python
简单了解Python多态与属性运行原理
Jun 15 Python
Python random模块的使用示例
Oct 10 Python
Python 绘制多因子柱状图
May 11 Python
Python用户推荐系统曼哈顿算法实现完整代码
Dec 01 #Python
浅谈python 里面的单下划线与双下划线的区别
Dec 01 #Python
vscode 远程调试python的方法
Dec 01 #Python
Python中单、双下划线的区别总结
Dec 01 #Python
从CentOS安装完成到生成词云python的实例
Dec 01 #Python
Django的分页器实例(paginator)
Dec 01 #Python
浅谈python装饰器探究与参数的领取
Dec 01 #Python
You might like
php面向对象全攻略 (十六) 对象的串行化
2009/09/30 PHP
php面向对象 字段的声明与使用
2012/06/14 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
PHP中散列密码的安全性分析
2019/07/26 PHP
常用的javascript function代码
2008/05/23 Javascript
解析js如何获取当前url中的参数值并复制给input
2013/06/23 Javascript
JavaScript获取网页中第一个图片id的方法
2015/04/03 Javascript
js+css实现上下翻页相册代码分享
2015/08/18 Javascript
jQuery同步提交示例代码
2015/12/12 Javascript
AngularJs自定义服务之实现签名和加密
2016/08/02 Javascript
Node.js读写文件之批量替换图片的实现方法
2016/09/07 Javascript
Jquery表单验证失败后不提交的解决方法
2016/10/18 Javascript
js-FCC算法-No repeats please字符串的全排列(详解)
2017/05/02 Javascript
浅谈jQuery框架Ajax常用选项
2017/07/08 jQuery
vue改变对象或数组时的刷新机制的方法总结
2019/04/24 Javascript
javascript实现前端分页效果
2020/06/24 Javascript
[06:40]2014DOTA2西雅图国际邀请赛 DK战队巡礼
2014/07/07 DOTA
Python下的twisted框架入门指引
2015/04/15 Python
python插入排序算法实例分析
2015/07/03 Python
Python编写简单的HTML页面合并脚本
2016/07/11 Python
Python中BeautifuSoup库的用法使用详解
2019/11/15 Python
使用 prometheus python 库编写自定义指标的方法(完整代码)
2020/06/29 Python
python3列表删除大量重复元素remove()方法的问题详解
2021/01/04 Python
使用python对excel表格处理的一些小功能
2021/01/25 Python
详解CSS3的opacity属性设置透明效果的用法
2016/05/09 HTML / CSS
Canvas实现保存图片到本地的示例代码
2018/06/28 HTML / CSS
大三自我鉴定范文
2013/10/05 职场文书
公积金转移接收函
2014/01/11 职场文书
创建省级文明单位实施方案
2014/02/27 职场文书
2014年基层党组织公开承诺书
2014/03/29 职场文书
通信工程专业求职信
2014/06/04 职场文书
学习三严三实对照检查材料思想汇报
2014/09/22 职场文书
2014小学数学教师个人工作总结
2014/12/18 职场文书
生产车间管理制度
2015/08/04 职场文书
Docker官方工具docker-registry案例演示
2022/04/13 Servers
Win11怎么添加用户?Win11添加用户账户的方法
2022/07/15 数码科技