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写一个贪吃蛇游戏实例代码
Aug 21 Python
python定向爬取淘宝商品价格
Feb 27 Python
Python 删除整个文本中的空格,并实现按行显示
Jul 24 Python
Python sorted函数详解(高级篇)
Sep 18 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
Dec 05 Python
如何更优雅地写python代码
Jul 02 Python
Pytorch反向求导更新网络参数的方法
Aug 17 Python
解决Django连接db遇到的问题
Aug 29 Python
np.random.seed() 的使用详解
Jan 14 Python
解决tensorboard多个events文件显示紊乱的问题
Feb 15 Python
python 追踪except信息方式
Apr 25 Python
Pycharm的Available Packages为空的解决方法
Sep 18 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
外媒评选出10支2020年最受欢迎的Dota2战队
2021/03/05 DOTA
php入门学习知识点四 PHP正则表达式基本应用
2011/07/14 PHP
php 的加密函数 md5,crypt,base64_encode 等使用介绍
2012/04/09 PHP
PHP的autoload机制的实现解析
2012/09/15 PHP
PHP判断远程图片或文件是否存在的实现代码
2014/02/20 PHP
PHP内置过滤器FILTER使用实例
2014/06/25 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
JavaScript学习笔记(二) js对象
2011/10/25 Javascript
简约JS日历控件 实例代码
2013/07/12 Javascript
js实现正方形颜色从下往上升的效果
2014/08/04 Javascript
JavaScript bold方法入门实例(把指定文字显示为粗体)
2014/10/17 Javascript
javascript实现模拟时钟的方法
2015/05/13 Javascript
基于JS实现的笛卡尔乘积之商品发布
2016/05/13 Javascript
JS优化与惰性载入函数实例分析
2017/04/06 Javascript
d3.js入门教程之数据绑定详解
2017/04/28 Javascript
vue自定义过滤器创建和使用方法详解
2017/11/06 Javascript
vue-cli webpack 引入jquery的方法
2018/01/10 jQuery
Vue.js 中的 v-show 指令及用法详解
2018/11/19 Javascript
详解小程序设置缓存并且不覆盖原有数据
2019/04/15 Javascript
JavaScript实现美化滑块效果
2019/05/17 Javascript
JS实现页面数据懒加载
2020/02/13 Javascript
解决vue-photo-preview 异步图片放大失效的问题
2020/07/29 Javascript
Python实现二叉树结构与进行二叉树遍历的方法详解
2016/05/24 Python
Python中的id()函数指的什么
2017/10/17 Python
Python实现PS滤镜的万花筒效果示例
2018/01/23 Python
Python操作mongodb的9个步骤
2018/06/04 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
2019/01/05 Python
浅谈Python 命令行参数argparse写入图片路径操作
2020/07/12 Python
python爬虫筛选工作实例讲解
2020/11/23 Python
韩国CJ食品专卖网:CJonmart
2016/09/11 全球购物
一家专门做特卖的网站:唯品会
2016/10/09 全球购物
美国折扣香水网站:The Perfume Spot
2020/12/12 全球购物
介绍一下Ruby的特点
2013/01/20 面试题
化工专业个人的求职信范文
2013/11/28 职场文书
详解nginx进程锁的实现
2021/06/14 Servers