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中threading模块join函数用法实例分析
Jun 04 Python
详谈Python2.6和Python3.0中对除法操作的异同
Apr 28 Python
Django自定义manage命令实例代码
Feb 11 Python
pytorch 更改预训练模型网络结构的方法
Aug 19 Python
python 非线性规划方式(scipy.optimize.minimize)
Feb 11 Python
Python如何通过百度翻译API实现翻译功能
Apr 02 Python
python上传时包含boundary时的解决方法
Apr 08 Python
如何将json数据转换为python数据
Sep 04 Python
Python常用GUI框架原理解析汇总
Dec 07 Python
Python第三方库安装缓慢的解决方法
Feb 06 Python
python实现网络五子棋
Apr 11 Python
pytorch通过训练结果的复现设置随机种子
Jun 01 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
PHP4与PHP5的时间格式问题
2008/02/17 PHP
PHP SEO优化之URL优化方法
2011/04/21 PHP
ThinkPHP登录功能的实现方法
2014/08/20 PHP
codeigniter中实现一次性加载多个view的方法
2015/03/20 PHP
Thinkphp实现自动验证和自动完成
2015/12/19 PHP
PHPExcel在linux环境下导出报500错误的解决方法
2017/01/26 PHP
PHP的mysqli_sqlstate()函数讲解
2019/01/23 PHP
解决Laravel无法使用COOKIE和SESSION的问题
2019/10/16 PHP
PHP实现文件上传与下载
2020/08/28 PHP
PHPStorm 2020.1 调试 Nodejs的多种方法详解
2020/09/17 NodeJs
js 剪切板应用clipboardData详细解析
2013/12/17 Javascript
javascript轻量级模板引擎juicer使用指南
2014/06/22 Javascript
JavaScript数组各种常见用法实例分析
2015/08/04 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
2017/02/14 Javascript
vue.js的computed,filter,get,set的用法及区别详解
2018/03/08 Javascript
JS加密插件CryptoJS实现的DES加密示例
2018/08/16 Javascript
基于html+css+js实现简易计算器代码实例
2020/02/28 Javascript
使用python检查yaml配置文件是否符合要求
2020/04/09 Python
python判断是空的实例分享
2020/07/06 Python
Python进行统计建模
2020/08/10 Python
LTD Commodities:礼品,独特发现,家居装饰,家用器皿
2017/08/11 全球购物
澳大利亚在线奢侈品时尚零售平台:Azura Runway
2021/01/13 全球购物
三维科技面试题
2013/07/27 面试题
在网络中有两台主机A和B,并通过路由器和其他交换设备连接起来,已经确认物理连接正确无误,怎么来测试这两台机器是否连通?如果不通,怎么来判断故障点?怎么排
2014/01/13 面试题
Prototype如何实现页面局部定时刷新
2013/08/06 面试题
酒店办公室文员岗位职责
2013/12/18 职场文书
超市开店计划书
2014/04/26 职场文书
入党积极分子学习党的纲领思想汇报
2014/09/13 职场文书
个人公司授权委托书范本
2014/10/12 职场文书
云南省召开党的群众路线教育实践活动总结会议新闻稿
2014/10/21 职场文书
学历证明范文
2015/06/16 职场文书
2015年四年级班主任工作总结
2015/10/22 职场文书
导游词之苏州寒山寺
2019/12/05 职场文书
MySQL中VARCHAR与CHAR格式数据的区别
2021/05/26 MySQL
Python数据可视化之基于pyecharts实现的地理图表的绘制
2021/06/10 Python
Python使用pyecharts控件绘制图表
2022/06/05 Python