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缩进区别分析
Feb 15 Python
Python爬虫框架Scrapy安装使用步骤
Apr 01 Python
在Python中实现贪婪排名算法的教程
Apr 17 Python
Python制作词云的方法
Jan 03 Python
Python3实现的Mysql数据库操作封装类
Jun 06 Python
为什么str(float)在Python 3中比Python 2返回更多的数字
Oct 16 Python
通过python爬虫赚钱的方法
Jan 29 Python
python列表使用实现名字管理系统
Jan 30 Python
python修改字典键(key)的方法
Aug 05 Python
python fuzzywuzzy模块模糊字符串匹配详细用法
Aug 29 Python
在Python中如何使用yield
Jun 07 Python
如何用python清洗文件中的数据
Jun 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
介绍一些PHP判断变量的函数
2012/04/24 PHP
基于PHP读取TXT文件向数据库导入海量数据的方法
2013/04/23 PHP
php设计模式之单例、多例设计模式的应用分析
2013/06/30 PHP
php上传图片并压缩的实现方法
2015/12/22 PHP
javascript 可以拖动的DIV(二)
2009/06/26 Javascript
javascript学习笔记(十六) 系统对话框(alert、confirm、prompt)
2012/06/20 Javascript
window.navigate 与 window.location.href 的使用区别介绍
2013/09/21 Javascript
Jquery Ajax解析XML数据(同步及异步调用)简单实例
2014/02/12 Javascript
JS实现的手机端精简幻灯片效果
2016/09/05 Javascript
用js写的一个路由(简单实例)
2016/09/24 Javascript
jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
2016/12/30 Javascript
react-router实现按需加载
2017/05/09 Javascript
原生JS+HTML5实现跟随鼠标一起流动的粒子动画效果
2018/05/03 Javascript
JS实现常见的查找、排序、去重算法示例
2018/05/21 Javascript
微信内置开发 iOS修改键盘换行为搜索的解决方案
2019/11/06 Javascript
[01:02:25]2014 DOTA2华西杯精英邀请赛5 24 NewBee VS VG
2014/05/25 DOTA
使用 Python 实现简单的 switch/case 语句的方法
2018/09/17 Python
Python中垃圾回收和del语句详解
2018/11/15 Python
在python带权重的列表中随机取值的方法
2019/01/23 Python
python tkinter之 复选、文本、下拉的实现
2020/03/04 Python
python将字典内容写入json文件的实例代码
2020/08/12 Python
python里反向传播算法详解
2020/11/22 Python
实列教程 一款基于jquery和css3的响应式二级导航菜单
2014/11/13 HTML / CSS
html5使用canvas画三角形
2014/12/15 HTML / CSS
Html5踩坑记之mandMobile使用小记
2020/04/02 HTML / CSS
Html5让容器充满屏幕高度或自适应剩余高度的布局实现
2020/05/14 HTML / CSS
EJB需直接实现它的业务接口或Home接口吗,请简述理由
2016/11/23 面试题
自动化专业个人求职信范文
2013/12/30 职场文书
大学生标准自荐书
2014/06/15 职场文书
出纳试用期自我鉴定范文
2014/09/16 职场文书
2015年社区计生工作总结
2015/04/21 职场文书
质量整改通知单
2015/04/21 职场文书
理解深度学习之深度学习简介
2021/04/14 Python
Django一小时写出账号密码管理系统
2021/04/29 Python
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android
python3中apply函数和lambda函数的使用详解
2022/02/28 Python