Python进阶学习之特殊方法实例详析

最近在学习python,学习到了一个之前没接触过的--特殊方法。

什么是特殊方法?当我们在设计一个类的时候,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进阶学习之特殊方法实例详析的更多相关文章

  1. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  2. C#操作SQLite方法实例详解

    用 C# 访问 SQLite 入门(1) CC++C#SQLiteFirefox  用 C# 访问 SQLite 入门 (1) SQLite 在 VS C# 环境下的开发,网上已经有很多教程.我也是从 ...

  3. Python深入学习之特殊方法与多范式

    Python深入学习之特殊方法与多范式 Python一切皆对象,但同时,Python还是一个多范式语言(multi-paradigm),你不仅可以使用面向对象的方式来编写程序,还可以用面向过程的方式来 ...

  4. 魔法方法推开Python进阶学习大门

    热爱Python Python是Guido van Rossum设计出来的让使用者觉得如沐春风的一门编程语言.2020年11月12日,64岁的Python之父宣布由于退休生活太无聊,自己决定加入Mic ...

  5. python进阶学习笔记(一)

    python进阶部分要学习的内容: 学习目标: 1.函数式编程 1.1,什么是函数式编程 函数式编程是一种抽象计算的编程模式 不同语言的抽象层次不同: 函数式编程的特点: python支持的函数式编程 ...

  6. python进阶学习笔记(三)

    3.类的继承 3.1,python中什么是类的继承 答案是肯定的. 也就是说,如果一个实例是一个子类,那么它也是一个父类 总是从某各类继承,如果没有合适的类,就要从object类继承:super(). ...

  7. Python进阶 学习笔记(三)

    (涉及内容:定制类) __str__和__repr__ 如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class Person(object): def __init__( ...

  8. python进阶之类常用魔法方法和魔法属性

    前言 前面我们总结过了python的关键字.运算符.内置函数.语法糖等与python魔法方法之间的关系,现在我们更细一点,看看python的面向对象编程有哪些常用的魔法属性和魔法方法. 魔法属性 对于 ...

  9. Python学习day07 - Python进阶(1) 内置方法

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

随机推荐

  1. 第11章 Spring Boot使用Actuator

    在生产环境中,需要实时或定期监控服务的可用性,spring-Boot的Actuator 功能提供了很多监控所需的接口. Actuator是Spring Boot提供的对应用系统的自省和监控的集成功能, ...

  2. BZOJ 1006 完美消除序列&最大势算法&弦图

    K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系 ...

  3. HDU - 6435 Problem J. CSGO (曼哈顿距离变换)

    题目大意:有两类武器(主武器和副武器),每类有若干把,每把武器都有一个基础属性S,以及k个附加属性,让你选一把主武器M和一把副武器S,使得最大. 显然后面的和式是一个k维的曼哈顿距离,带绝对值符号不好 ...

  4. pycharm运行程序,总是出现IPthony界面(IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. PyDev console: using IPython 6.2.1)

    解决方式如下: 取消即可.

  5. jquery实现在光标位置(input、textarea)插入内容的方法

    通过扫码枪扫码.按钮点击事件在光标处插入文本,这是前台js常用的功能.但是在input输入框和textarea文本框定位光标,插入数据是有点不同的 首先最简单的,适用于input输入框的方法 HTML ...

  6. Ubuntu 16.04安装docker详细步骤

    1. 卸载之前的旧版本 sudo apt-get remove docker docker-engine docker-ce docker.io 2. 更新apt包 sudo apt-get upda ...

  7. Spring Boot 中application.yml与bootstrap.yml的区别(转)

    yml与properties其实yml和properties文件是一样的原理,且一个项目上要么yml或者properties,二选一的存在. 推荐使用yml,更简洁. bootstrap与applic ...

  8. 读狼书,重温flask

    最近做个简单的MIS系统, 趁机读<flask web 开发实战 入门.进阶与原理解析> 李辉.  由于是flask官方团队的人写的.方方面面都很细致. 很多写法.配置,和之前0.X时代也 ...

  9. hdu 5723 Abandoned country 最小生成树+子节点统计

    Abandoned country Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  10. CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)D

    题面 一开始想到一个 O(N^2) 做法,先把x排序,然后顺次枚举x最大的点,看向前最多可以保留多少点 (也就是先不管正方形的上下长度限制,先考虑左右的限制).然后再对这些点做一遍类似的..(等等这么 ...