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 相关文章推荐
django开发教程之利用缓存文件进行页面缓存的方法
Nov 10 Python
Python利用字典将两个通讯录文本合并为一个文本实例
Jan 16 Python
python实现简单名片管理系统
Nov 30 Python
python代码 输入数字使其反向输出的方法
Dec 22 Python
基于python 微信小程序之获取已存在模板消息列表
Aug 05 Python
python开头的coding设置方法
Aug 08 Python
python jenkins 打包构建代码的示例代码
Nov 29 Python
Python安装tar.gz格式文件方法详解
Jan 19 Python
PIL包中Image模块的convert()函数的具体使用
Feb 26 Python
Python pip使用超时问题解决方案
Aug 03 Python
简单了解Python字典copy与赋值的区别
Sep 16 Python
python3中布局背景颜色代码分析
Dec 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
PHP生成Flash动画的实现代码
2010/03/12 PHP
PHP重载基础知识回顾
2020/09/10 PHP
JavaScript 用cloneNode方法克隆节点的代码
2012/10/15 Javascript
JS的replace方法详细介绍
2012/11/09 Javascript
jquery实现textarea输入字符控制(仿微博输入控制字符)
2013/04/26 Javascript
Extjs407 getValue()和getRawValue()区别介绍
2013/05/21 Javascript
JavaScript页面模板库handlebars的简单用法
2015/03/02 Javascript
javascript排序函数实现数字排序
2015/06/26 Javascript
jquery轮播的实现方式 附完整实例
2016/07/28 Javascript
微信小程序 使用canvas制作K线实例详解
2017/01/12 Javascript
浅谈vue方法内的方法使用this的问题
2018/09/15 Javascript
vue webpack打包后图片路径错误的完美解决方法
2018/12/07 Javascript
微信小程序实现组件顶端固定或底端固定效果(不随滚动而滚动)
2020/04/09 Javascript
vantUI 获得piker选中值的自定义ID操作
2020/11/04 Javascript
[01:01:36]Optic vs paiN 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
使用Python脚本来控制Windows Azure的简单教程
2015/04/16 Python
Python可变参数函数用法实例
2015/07/07 Python
python字符串的方法与操作大全
2018/01/30 Python
Python机器学习之K-Means聚类实现详解
2018/02/22 Python
python+pandas+时间、日期以及时间序列处理方法
2018/07/10 Python
Django中ajax发送post请求 报403错误CSRF验证失败解决方案
2019/08/13 Python
python字符串的拼接方法总结
2019/11/18 Python
解决Pycharm的项目目录突然消失的问题
2020/01/20 Python
opencv+python实现鼠标点击图像,输出该点的RGB和HSV值
2020/06/02 Python
python 解决Windows平台上路径有空格的问题
2020/11/10 Python
Black Halo官方网站:购买连衣裙、礼服和连体裤
2018/06/13 全球购物
编程实现当输入某产品代码则打印出该产品记录的功能
2014/05/03 面试题
股东协议书
2014/04/14 职场文书
汉语专业毕业生自荐信
2014/07/06 职场文书
微观世界观后感
2015/06/10 职场文书
记者节感言
2015/08/03 职场文书
任命书格式范文
2015/09/22 职场文书
大学生村官工作心得体会
2016/01/23 职场文书
《雷雨》教学反思
2016/02/20 职场文书
Nginx配置https原理及实现过程详解
2021/03/31 Servers
Python干货实战之八音符酱小游戏全过程详解
2021/10/24 Python