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模拟登陆阿里妈妈生成商品推广链接
Apr 03 Python
1 行 Python 代码快速实现 FTP 服务器
Jan 25 Python
django使用LDAP验证的方法示例
Dec 10 Python
想学python 这5本书籍你必看!
Dec 11 Python
对python中不同模块(函数、类、变量)的调用详解
Jul 16 Python
Django如何简单快速实现PUT、DELETE方法
Jul 24 Python
详解Python self 参数
Aug 30 Python
python打印直角三角形与等腰三角形实例代码
Oct 20 Python
利用Python绘制有趣的万圣节南瓜怪效果
Oct 31 Python
利用Python代码实现一键抠背景功能
Dec 29 Python
PyCharm2020.1.2社区版安装,配置及使用教程详解(Windows)
Aug 07 Python
Python配置pip国内镜像源的实现
Aug 20 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 IN_ARRAY 函数使用注意事项
2010/07/24 PHP
PHP连接和操作MySQL数据库基础教程
2014/09/29 PHP
Zend Framework框架路由机制代码分析
2016/03/22 PHP
解决Laravel blade模板转义html标签的问题
2019/09/03 PHP
你需要知道的JavsScript可以做什么?
2007/06/29 Javascript
JavaScript中的集合及效率
2010/01/08 Javascript
javascript 获取图片尺寸及放大图片
2013/09/04 Javascript
jquery选择器-根据多个属性选择示例代码
2013/10/21 Javascript
javascript 上下banner替换具体实现
2013/11/14 Javascript
JS实现简单的顶部定时关闭层效果
2014/06/15 Javascript
JavaScript实现从数组中选出和等于固定值的n个数
2014/09/03 Javascript
DOM基础教程之事件对象
2015/01/20 Javascript
javascript实现带节日和农历的日历特效
2015/02/01 Javascript
Bootstrap Validator 表单验证
2016/07/25 Javascript
JS正则截取两个字符串之间及字符串前后内容的方法
2017/01/06 Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
2017/09/11 Javascript
js数据类型检测总结
2018/08/05 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
2019/05/27 Javascript
微信小程序实现下拉加载更多商品
2020/12/29 Javascript
[01:03:41]完美世界DOTA2联赛PWL S3 DLG vs Phoenix 第一场 12.17
2020/12/19 DOTA
python通过定义一个类实例作为ftp回调方法
2015/05/04 Python
使用PyInstaller将Python程序文件转换为可执行程序文件
2016/07/08 Python
Python3 jupyter notebook 服务器搭建过程
2018/11/30 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
pytorch下的unsqueeze和squeeze的用法说明
2021/02/06 Python
KEETSA环保床垫:更好的睡眠,更好的生活!
2016/11/24 全球购物
攀岩、滑雪、徒步旅行装备:Black Diamond Equipment
2019/08/16 全球购物
Python里面如何拷贝一个对象
2014/02/17 面试题
劳资人员岗位职责
2013/12/19 职场文书
服装电子商务创业计划书
2014/01/30 职场文书
销售员岗位职责
2014/06/09 职场文书
知识竞赛拉拉队口号
2014/06/16 职场文书
初中英语教师个人工作总结2015
2015/07/21 职场文书
《我的伯父鲁迅先生》教学反思
2016/02/16 职场文书
2016个人廉洁自律承诺书
2016/03/25 职场文书
Win11局域网共享权限在哪里设置? Win11高级共享的设置技巧
2022/04/05 数码科技