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安装以及IDE的配置教程
Apr 29 Python
Python线程指南详细介绍
Jan 05 Python
关于Django外键赋值问题详解
Aug 13 Python
tensorflow实现对图片的读取的示例代码
Feb 12 Python
Python走楼梯问题解决方法示例
Jul 25 Python
用python脚本24小时刷浏览器的访问量方法
Dec 07 Python
图文详解python安装Scrapy框架步骤
May 20 Python
python分割一个文本为多个文本的方法
Jul 22 Python
py-charm延长试用期限实例
Dec 22 Python
Jupyter notebook快速入门教程(推荐)
May 18 Python
Python关于拓扑排序知识点讲解
Jan 04 Python
Python卷积神经网络图片分类框架详解分析
Nov 07 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
Yii的CDbCriteria查询条件用法实例
2014/12/04 PHP
PHP使用栈解决约瑟夫环问题算法示例
2017/08/27 PHP
Laravel 实现添加多语言提示信息
2019/10/25 PHP
PHP 超级全局变量相关总结
2020/06/30 PHP
jQuery 操作下拉列表框实现代码
2010/02/22 Javascript
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
2010/06/18 Javascript
ExtJS4 组件化编程,动态加载,面向对象,Direct
2011/05/12 Javascript
javascript 兼容所有浏览器的DOM扩展功能
2012/08/01 Javascript
JQuery的Ajax跨域请求原理概述及实例
2013/04/26 Javascript
javascript内置对象arguments详解
2014/03/16 Javascript
用Move.js配合创建CSS3动画的入门指引
2015/07/22 Javascript
jquery实现ajax提交表单信息的简单方法(推荐)
2016/08/24 Javascript
利用Js+Css实现折纸动态导航效果实例源码
2017/01/25 Javascript
js通过keyCode值判断单击键盘上某个键,然后触发指定的事件方法
2017/02/19 Javascript
js读取json文件片段中的数据实例
2017/03/09 Javascript
详解bootstrap用dropdown-menu实现上下文菜单
2017/09/22 Javascript
jquery使用FormData实现异步上传文件
2018/10/25 jQuery
详解一个基于react+webpack的多页面应用配置
2019/01/21 Javascript
Vue 实现输入框新增搜索历史记录功能
2019/10/15 Javascript
利用原生JS实现欢乐水果机小游戏
2020/04/23 Javascript
vue单应用在ios系统中实现微信分享功能操作
2020/09/07 Javascript
[01:09]DOTA2次级职业联赛 - 99战队宣传片
2014/12/01 DOTA
[02:36]DOTA2上海特锦赛 回忆电竞生涯的重要瞬间
2016/03/25 DOTA
[01:56]无止竞 再出发——中国军团出征2017年DOTA2国际邀请赛
2017/07/05 DOTA
python分析nignx访问日志脚本分享
2015/02/26 Python
PyChar学习教程之自定义文件与代码模板详解
2017/07/17 Python
python中实现精确的浮点数运算详解
2017/11/02 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
python获取中文字符串长度的方法
2018/11/14 Python
基于selenium及python实现下拉选项定位select
2020/07/22 Python
html5 worker 实例(二) 图片变换效果
2013/06/24 HTML / CSS
日本非常有名的内衣丝袜品牌:GUNZE
2017/01/06 全球购物
如何理解委托
2012/01/06 面试题
口才训练演讲稿范文
2014/09/16 职场文书
2015年学校后勤工作总结
2015/04/08 职场文书
2016八一建军节慰问信
2015/11/30 职场文书