Python中类的初始化特殊方法


Posted in Python onDecember 01, 2017

什么是特殊方法?当我们在设计一个类的时候,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 Web框架Flask中使用百度云存储BCS实例
Feb 08 Python
Python Web框架Flask中使用七牛云存储实例
Feb 08 Python
Python中的高级函数map/reduce使用实例
Apr 13 Python
python 排序算法总结及实例详解
Sep 28 Python
python如何求解两数的最大公约数
Sep 27 Python
Python3.5实现的罗马数字转换成整数功能示例
Feb 25 Python
Python3安装Pillow与PIL的方法
Apr 03 Python
Pycharm如何打断点的方法步骤
Jun 13 Python
Python中利用LSTM模型进行时间序列预测分析的实现
Jul 26 Python
Python切割图片成九宫格的示例代码
Mar 10 Python
Python生成器next方法和send方法区别详解
May 30 Python
python实现canny边缘检测
Sep 14 Python
Python抓取框架Scrapy爬虫入门:页面提取
Dec 01 #Python
Python实现调度算法代码详解
Dec 01 #Python
Python进阶学习之特殊方法实例详析
Dec 01 #Python
Python用户推荐系统曼哈顿算法实现完整代码
Dec 01 #Python
浅谈python 里面的单下划线与双下划线的区别
Dec 01 #Python
vscode 远程调试python的方法
Dec 01 #Python
Python中单、双下划线的区别总结
Dec 01 #Python
You might like
一个PHP模板,主要想体现一下思路
2006/12/25 PHP
php中使用cookie来保存用户登录信息的实现代码
2012/03/08 PHP
php内嵌函数用法实例
2015/03/20 PHP
Laravel中的Auth模块详解
2017/08/17 PHP
优化网页之快速的呈现我们的网页
2007/06/29 Javascript
JavaScript字符串String和Array操作的有趣方法
2012/12/18 Javascript
经过绑定元素时会多次触发mouseover和mouseout事件
2014/02/28 Javascript
离开当前页面前使用js判断条件提示是否要离开页面
2014/05/02 Javascript
node.js中的emitter.emit方法使用说明
2014/12/10 Javascript
javascript操作Cookie(设置、读取、删除)方法详解
2015/03/18 Javascript
JQuery CheckBox(复选框)操作方法汇总
2015/04/15 Javascript
详解AngularJS中的依赖注入机制
2015/06/17 Javascript
AngularJs 指令详解及示例代码
2016/09/01 Javascript
AngularJs Understanding the Controller Component
2016/09/02 Javascript
JSP防止网页刷新重复提交数据的几种方法
2016/11/19 Javascript
JS实现本地存储信息的方法(基于localStorage与userData)
2017/02/18 Javascript
在vue中使用Autoprefixed的方法
2018/07/27 Javascript
python实现的登录和操作开心网脚本分享
2014/07/09 Python
Python实现自定义读写分离代码实例
2019/11/16 Python
基于Python数据分析之pandas统计分析
2020/03/03 Python
python实现俄罗斯方块小游戏
2020/04/24 Python
Scrapy基于scrapy_redis实现分布式爬虫部署的示例
2020/09/29 Python
HTML5中使用postMessage实现Ajax跨域请求的方法
2016/04/19 HTML / CSS
巴西儿童时尚购物网站:Dinda
2019/08/14 全球购物
Timberland法国官网:购买靴子、鞋子、衣服、夹克和配饰
2019/11/30 全球购物
英国健身专家:WIT Fitness
2021/02/09 全球购物
js正则匹配markdown里的图片标签的实现
2021/03/24 Javascript
人民教师求职自荐信
2014/03/12 职场文书
农民工工资承诺书范文
2014/03/31 职场文书
庆六一开幕词
2015/01/29 职场文书
实施意见格式范本
2015/06/05 职场文书
在 Golang 中实现 Cache::remember 方法详解
2021/03/30 Python
Java中PriorityQueue实现最小堆和最大堆的用法
2021/06/27 Java/Android
Python中可变和不可变对象的深入讲解
2021/08/02 Python
Java基础——Map集合
2022/04/01 Java/Android
Python绘制散乱的点构成的图的方法
2022/04/21 Python