Python中类的初始化特殊方法
作者:laozhang 发布时间:2021-05-26 14:50:01
什么是特殊方法?当我们在设计一个类的时候,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__$。
来源:https://segmentfault.com/a/1190000012223818
猜你喜欢
- Python中多线程使用到Threading模块。Threading模块中用到的主要的类是Thread,我们先来写一个简单的多线程代码:#
- 1、远程登录到linux上,使用到的模块paramiko#远程登陆操作系统def ssh(sys_ip,username,password,
- 从 Google 的一个细节说起:整个虚线框都是“Next”的可点击区域。看似不经意,却直接提升了细节的可用性。其它页码也巧妙地和上面的字母
- 在学习和使用各种数据库的过程中,我们常常会遇到聚族索引、非聚族索引、组合索引的概念,这些索引对我们使用数据库,特别是查询的速度的
- 重置oracle序列从指定数字开始 代码如下:declare n number(10); v_startnum number(10):=1
- var a= new Array(new Array(1,2),new Array('b','c')); d
- jQuery的选择器是CSS 1-3,XPath的结合物。jQuery提取这二种查询语言最好的部分,融合后创造出了最终的jQuery表达式查
- 上次学会了爬取图片,这次就想着试试爬取商家的联系电话,当然,这里纯属个人技术学习,爬取过后及时删除,不得用于其它违法用途,一切后果自负。首先
- 求英文字母、数字、下划线、汉字的js正则表达式英文字母或数字或下划线,英文字母数字下划线是:/^\w+$/汉字的是:/^[\u0391-\u
- 废话不多说,直接看问题,使用过 Python 中的标准库 zipfile 解压过 zip&
- 在浏览器 IE6 、IE7、Firefox2+、Firefpx3+、Opera9.6+、Safari3.1+中测试以下代码:<!DOC
- 英文原文:http://www.456bereastreet.com/archive/200601/css_3_selectors_expl
- WxPython界面用pubsub实现多线程控制用WxPython做界面时, 如果数据操作时间比较长,会使 WxPython 界面处于假死状
- python3 manage.py makemigrations # 生成数据库迁移文件python3 manage.py migrate
- 运动模糊:由于相机和物体之间的相对运动造成的模糊,又称为动态模糊Opencv+Python实现运动模糊,主要用到的函数是cv2.filter
- 1. 数据类型 type()#!/usr/bin/env python# -*- coding: utf-8 -*-# Yongqiang
- 需求:1.用户输入密码正确登录2.用户输入密码错误退出并调用函数继续输入3.用户输入密码符合原先给定的一个值时,允许用户重置密码,并且可以用
- 安装 SQL2000 时,系统经常会提示:操作被挂起,要求重新启动计算机,如图1: 图1重新启动后,再次安装时问题仍然存在。解决办
- 不可否认,阿里巴巴走得越来越快也越来越好。技术的成熟让很多B2B B2C网站都在跟风学习它们。在这里我就来说一说它的搜索效果吧。如图所示:&
- <body oncontextmenu="return false" onselectstart="re