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装饰器使用示例及实际应用例子
Mar 06 Python
python连接字符串的方法小结
Jul 13 Python
详解python之heapq模块及排序操作
Apr 04 Python
我们为什么要减少Python中循环的使用
Jul 10 Python
详解python 利用echarts画地图(热力图)(世界地图,省市地图,区县地图)
Aug 06 Python
python多进程并行代码实例
Sep 30 Python
pytorch ImageFolder的覆写实例
Feb 20 Python
python 画图 图例自由定义方式
Apr 17 Python
Python中SQLite如何使用
May 27 Python
Python基础之数据结构详解
Apr 28 Python
OpenCV图像变换之傅里叶变换的一些应用
Jul 26 Python
Python使用OpenCV实现虚拟缩放效果
Feb 28 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
做个自己站内搜索引擎
2006/10/09 PHP
运用Windows XP附带的Msicuu.exe、Msizap.exe来彻底卸载顽固程序
2007/04/21 Javascript
javascript新手语法小结
2008/06/15 Javascript
javascript间隔定时器(延时定时器)学习 间隔调用和延时调用
2014/01/13 Javascript
如何让浏览器支持jquery ajax load 前进、后退功能
2014/06/12 Javascript
javascript仿百度输入框提示自动下拉补全
2016/01/07 Javascript
node.js平台下的mysql数据库配置及连接
2017/03/31 Javascript
js解决软键盘遮挡输入框的问题分享
2017/12/19 Javascript
vue数据传递--我有特殊的实现技巧
2018/03/20 Javascript
微信小程序实现星级评价效果
2018/12/28 Javascript
微信公众平台 发送模板消息(Java接口开发)
2019/04/17 Javascript
Vue 实现前进刷新后退不刷新的效果
2019/06/14 Javascript
react koa rematch 如何打造一套服务端渲染架子
2019/06/26 Javascript
小程序实现左滑删除的效果的实例代码
2020/10/19 Javascript
详解vue3.0 的 Composition API 的一种使用方法
2020/10/26 Javascript
Python使用pip安装pySerial串口通讯模块
2018/04/20 Python
Python实现判断一行代码是否为注释的方法
2018/05/23 Python
Django后台admin的使用详解
2019/07/08 Python
解决django FileFIELD的编码问题
2020/03/30 Python
解决jupyter notebook import error但是命令提示符import正常的问题
2020/04/15 Python
python super()函数的基本使用
2020/09/10 Python
Selenium执行完毕未关闭chromedriver/geckodriver进程的解决办法(java版+python版)
2020/12/07 Python
世界知名接发和假发品牌:Poze Hair
2017/03/08 全球购物
加拿大领先的冒险和户外零售商:Atmosphere
2017/12/19 全球购物
Hotels.com日本:国外和海外住宿,酒店预订
2019/12/13 全球购物
一份全面的PHP面试问题考卷
2012/07/15 面试题
人事部主管岗位职责
2013/12/26 职场文书
高中考试作弊检讨书
2014/01/14 职场文书
幼儿园教师工作感言
2014/02/15 职场文书
在职员工证明书
2014/09/19 职场文书
区域经理岗位职责
2015/02/02 职场文书
清明节网上祭英烈寄语2015
2015/03/04 职场文书
萤火虫之墓观后感
2015/06/05 职场文书
解决IDEA翻译插件Translation报错更新TTK失败不能使用
2022/04/24 Python
MySQL中JOIN连接的基本用法实例
2022/06/05 MySQL
纯CSS打字动画的实现示例
2022/08/05 HTML / CSS