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文件读取的3种方法及路径转义
Jun 21 Python
详解Python中的元组与逻辑运算符
Oct 13 Python
浅谈python类属性的访问、设置和删除方法
Jul 25 Python
Python 装饰器深入理解
Mar 16 Python
Python使用pickle模块存储数据报错解决示例代码
Jan 26 Python
Python高级用法总结
May 26 Python
PyCharm代码回滚,恢复历史版本的解决方法
Oct 22 Python
python 多个参数不为空校验方法
Feb 14 Python
树莓派实现移动拍照
Jun 22 Python
使用 Python 在京东上抢口罩的思路详解
Feb 27 Python
Python中使用subprocess库创建附加进程
May 11 Python
python垃圾回收机制原理分析
Apr 13 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数组函数序列之array_key_exists() - 查找数组键名是否存在
2011/10/29 PHP
Php Ctemplate引擎开发相关内容
2012/03/03 PHP
php数组键值用法实例分析
2015/02/27 PHP
PHP的HTTP客户端Guzzle简单使用方法分析
2019/10/30 PHP
laravel框架分组控制器和分组路由实现方法示例
2020/01/25 PHP
js+div实现图片滚动效果代码
2014/02/10 Javascript
提高NodeJS中SSL服务的性能
2014/07/15 NodeJs
jQuery 复合选择器应用的几个例子
2014/09/11 Javascript
js实现table添加行tr、删除行tr、清空行tr的简单实例
2016/10/15 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
2017/03/15 Javascript
详解Node.js串行化流程控制
2017/05/04 Javascript
JavaScript与Java正则表达式写法的区别介绍
2017/08/15 Javascript
vue做网页开场视频的实例代码
2017/10/20 Javascript
让bootstrap的carousel支持滑动滚屏的实现代码
2017/11/27 Javascript
Windows下Node爬虫神器Puppeteer安装记
2019/01/09 Javascript
vue中实现动态生成二维码的方法
2020/02/21 Javascript
JavaScript鼠标悬停事件用法解析
2020/05/15 Javascript
antd table按表格里的日期去排序操作
2020/11/17 Javascript
python批量设置多个Excel文件页眉页脚的脚本
2018/03/14 Python
Python面向对象程序设计构造函数和析构函数用法分析
2019/04/12 Python
如何在Python中实现goto语句的方法
2019/05/18 Python
pyqt5 comboBox获得下标、文本和事件选中函数的方法
2019/06/14 Python
python GUI库图形界面开发之PyQt5工具栏控件QToolBar的详细使用方法与实例
2020/02/28 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
GEOX鞋美国官方网站:意大利会呼吸的鞋
2017/07/12 全球购物
西班牙国家航空官方网站:Iberia
2017/11/16 全球购物
爱尔兰电子产品购物网站:Komplett.ie
2018/04/04 全球购物
美国值得信赖的婚恋交友网站:eHarmony
2018/10/04 全球购物
绘画设计学生的个人自我评价
2013/09/20 职场文书
酒店管理毕业生自荐信
2013/10/24 职场文书
幼儿园中班新学期寄语
2014/01/18 职场文书
幼儿园社区活动总结
2014/07/07 职场文书
2014年减负工作总结
2014/12/10 职场文书
2015年手术室工作总结
2015/05/11 职场文书
pytorch中F.avg_pool1d()和F.avg_pool2d()的使用操作
2021/05/22 Python
修改MySQL的数据库引擎为INNODB的方法
2021/05/26 MySQL