您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Python

每个程序员都应该知道的11个Python魔术方法

时间:2023-12-27 14:02:48  来源:51CTO  作者:

译者 | 布加迪

审校 | 重楼

每个程序员都应该知道的11个Python魔术方法

Python/ target=_blank class=infotextkey>Python中,魔术方法(Magic Method)可以帮助您模拟Python类中内置函数的行为。这些方法有前后双下划线(__),因此也被称为Dunder方法。

这些魔术方法还可以帮助您在Python中实现操作符重载。您可能见过这样的例子,就像两个整数与乘法运算符*一起使用得到乘积一样。当它与字符串和整数k一起使用时,字符串会重复k次:

>>> 3 * 4
12
>>> 'code' * 3
'codecodecode'

我们在本文中将通过创建一个简单的二维向量Vector2D类来探索Python中的魔术方法。

我们将从您可能熟悉的方法入手,逐步构建更有帮助的魔术方法。

不妨开始编写一些魔术方法!

1. __init__

考虑下面的Vector2D类:

class Vector2D:
 pass

一旦您创建了类,并实例化对象,就可以添加如下属性:obj_name.attribute_name = value。

然而,您需要在实例化对象时初始化这些属性,而不是手动向创建的每个实例添加属性(当然,这一点也不有趣!)。

为此,您可以定义__init__方法。不妨为Vector2D类定义__init__方法:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

v = Vector2D(3, 5)

2. __repr__

当您尝试检查或打印输出实例化的对象时,您将发现没有得到任何有帮助的信息。

 

v = Vector2D(3, 5)
print(v)

Output >>> <__mAIn__.Vector2D object at 0x7d2fcfaf0ac0>

这就是为什么您应该添加一个表示字符串,一个对象的字符串表示。为此,添加__repr__方法,如下所示:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

v = Vector2D(3, 5)
print(v)


Output >>> Vector2D(x=3, y=5)

__repr__应该包含创建类实例所需的所有属性和信息。__repr__方法通常用于调试目的。

3. __str__

__str__也用于添加对象的字符串表示。通常,__str__方法用于为类的最终用户提供信息。

不妨给我们的类添加一个__str__方法:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __str__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

v = Vector2D(3, 5)
print(v)


Output >>> Vector2D(x=3, y=5)

如果没有__str__的实现,它就返回到__repr__。因此对于您创建的每个类,您至少应该添加__repr__方法。

4. __eq__

接下来,不妨添加一个方法来检查Vector2D类的任意两个对象是否相等。如果两个向量有相同的x和y坐标,它们是相等的。

现在创建两个具有相等x和y值的Vector2D对象,并比较它们是否相等:

v1 = Vector2D(3, 5)
v2 = Vector2D(3, 5)
print(v1 == v2)

结果为False,因为默认情况下比较会检查内存中对象ID是否相等。

Output >>> False

不妨添加__eq__方法来检查是否相等:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __eq__(self, other):
 return self.x == other.x and self.y == other.y

检查相等性现在应该按预期工作:

v1 = Vector2D(3, 5)
v2 = Vector2D(3, 5)
print(v1 == v2)


Output >>> True 

5. __len__

Python的内置len()函数可以帮助您计算内置可迭代对象(iterable)的长度。比如说,就向量而言,length应该返回该向量所包含的元素的个数。

所以不妨为Vector2D类添加一个__len__方法:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __len__(self):
 return 2

v = Vector2D(3, 5)
print(len(v))

Vector2D类的所有对象长度为2:

Output >>> 2

6. __add__

现在不妨考虑对向量执行的常见运算。不妨添加魔术方法来加减任意两个向量。

如果您直接尝试添加两个向量对象,就会遇到错误。所以您应该添加一个__add__方法:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __add__(self, other):
 return Vector2D(self.x + other.x, self.y + other.y)

您现在可以像这样添加任意两个向量:

v1 = Vector2D(3, 5)
v2 = Vector2D(1, 2)
result = v1 + v2
print(result)


Output >>> Vector2D(x=4, y=7)

7. __sub__

接下来,不妨添加一个__sub__方法来计算Vector2D类的任意两个对象之间的差异:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __sub__(self, other):
 return Vector2D(self.x - other.x, self.y - other.y)


v1 = Vector2D(3, 5)
v2 = Vector2D(1, 2)
result = v1 - v2
print(result)


Output >>> Vector2D(x=2, y=3)

8. __mul__

我们还可以定义__mul__方法来定义对象之间的乘法。

不妨来处理:

  • 标量乘法:向量与标量的乘法
  • 内积:两个向量的点积
class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __mul__(self, other):
 # Scalar multiplication
 if isinstance(other, (int, float)):
 return Vector2D(self.x * other, self.y * other)
 # Dot product
 elif isinstance(other, Vector2D):
 return self.x * other.x + self.y * other.y
 else:
 raise TypeError("Unsupported operand type for *")

现在我们将举几个例子,看看__mul__方法是如何实际工作的。

v1 = Vector2D(3, 5)
v2 = Vector2D(1, 2)

# Scalar multiplication
result1 = v1 * 2
print(result1) 
# Dot product
result2 = v1 * v2
print(result2)


Output >>>

Vector2D(x=6, y=10)
13

9. __getitem__

__getitem__魔术方法让您可以索引对象,并使用熟悉的方括号[]语法访问属性或属性切片。

对于Vector2D类的对象v:

  • v [0]:x坐标
  • v [1]:y坐标

如果您尝试通过索引访问,您会遇到错误:

v = Vector2D(3, 5)
print(v[0],v[1])


---------------------------------------------------------------------------

TypeError  Traceback (most recent call last)

 in ()
----> 1 print(v[0],v[1])

TypeError: 'Vector2D' object is not subscriptable
 

不妨实现__getitem__ 方法:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __getitem__(self, key):
 if key == 0:
 return self.x
 elif key == 1:
 return self.y
 else:
 raise IndexError("Index out of range")

现在您可以使用索引访问这些元素,如下所示:

v = Vector2D(3, 5)
print(v[0]) 
print(v[1])


Output >>>

3
5

10. __call__

借助__call__方法的实现,您可以像调用函数一样调用对象。

在Vector2D类中,我们可以实现__call__,按给定因子缩放向量:

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __call__(self, scalar):
 return Vector2D(self.x * scalar, self.y * scalar)

如果您现在调用3,会得到缩放3倍的向量:

v = Vector2D(3, 5)
result = v(3)
print(result)


Output >>> Vector2D(x=9, y=15)

11. __getattr__

__getattr__方法用于获取对象的特定属性的值。

就这个例子而言,我们可以添加一个__getattr__ dunder方法,一旦被调用可计算向量的量值(L2-norm):

class Vector2D:
 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __repr__(self):
 return f"Vector2D(x={self.x}, y={self.y})"

 def __getattr__(self, name):
 if name == "magnitude":
 return (self.x ** 2 + self.y ** 2) ** 0.5
 else:
 raise AttributeError(f"'Vector2D' object has no attribute '{name}'")

不妨验证这是否像预期的那样工作:

v = Vector2D(3, 4)
print(v.magnitude)


Output >>> 5.0

结论

这就是本教程的全部内容!希望您已经学会了如何为您的类添加魔术方法,以模拟内置函数的行为。

我们已介绍了一些最有用的魔术方法,但这并非详尽的清单。为了进一步理解,您可以创建一个所选择的Python类,根据所需的功能添加魔术方法。最后祝编程愉快!

原文标题:Harness the Power of AI for Business,作者:Bala Priya C



Tags:Python   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Python 可视化:Plotly 库使用基础
当使用 Plotly 进行数据可视化时,我们可以通过以下示例展示多种绘图方法,每个示例都会有详细的注释和说明。1.创建折线图import plotly.graph_objects as go# 示例1: 创建简单...【详细内容】
2024-04-01  Search: Python  点击:(8)  评论:(0)  加入收藏
Python 办公神器:教你使用 Python 批量制作 PPT
介绍本文将介绍如何使用openpyxl和pptx库来批量制作PPT奖状。本文假设你已经安装了python和这两个库。本文的场景是:一名基层人员,要给一次比赛活动获奖的500名选手制作奖状,并...【详细内容】
2024-03-26  Search: Python  点击:(15)  评论:(0)  加入收藏
Python实现工厂模式、抽象工厂,单例模式
工厂模式是一种常见的设计模式,它可以帮助我们创建对象的过程更加灵活和可扩展。在Python中,我们可以使用函数和类来实现工厂模式。一、Python中实现工厂模式工厂模式是一种常...【详细内容】
2024-03-07  Search: Python  点击:(31)  评论:(0)  加入收藏
不可不学的Python技巧:字典推导式使用全攻略
Python的字典推导式是一种优雅而强大的工具,用于创建字典(dict)。这种方法不仅代码更加简洁,而且执行效率高。无论你是Python新手还是有经验的开发者,掌握字典推导式都将是你技能...【详细内容】
2024-02-22  Search: Python  点击:(32)  评论:(0)  加入收藏
如何进行Python代码的代码重构和优化?
Python是一种高级编程语言,它具有简洁、易于理解和易于维护的特点。然而,代码重构和优化对于保持代码质量和性能至关重要。什么是代码重构?代码重构是指在不改变代码外部行为的...【详细内容】
2024-02-22  Search: Python  点击:(32)  评论:(0)  加入收藏
Python开发者必备的八个PyCharm插件
在编写代码的过程中,括号几乎无处不在,以至于有时我们会拼命辨别哪个闭合括号与哪个开头的括号相匹配。这款插件能帮助解决这个众所周知的问题。前言在PyCharm中浏览插件列表...【详细内容】
2024-01-26  Search: Python  点击:(84)  评论:(0)  加入收藏
Python的Graphlib库,再也不用手敲图结构了
Python中的graphlib库是一个功能强大且易于使用的工具。graphlib提供了许多功能,可以帮助您创建、操作和分析图形对象。本文将介绍graphlib库的主要用法,并提供一些示例代码和...【详细内容】
2024-01-26  Search: Python  点击:(85)  评论:(0)  加入收藏
大语言模型插件功能在携程的Python实践
作者简介成学,携程高级安全研发工程师,关注Python/Golang后端开发、大语言模型等领域。一、背景2023年初,科技圈最火爆的话题莫过于大语言模型了,它是一种全新的聊天机器人模型,...【详细内容】
2024-01-26  Search: Python  点击:(72)  评论:(0)  加入收藏
如何使用Python、Apache Kafka和云平台构建健壮的实时数据管道
译者 | 李睿审校 | 重楼在当今竞争激烈的市场环境中,为了生存和发展,企业必须能够实时收集、处理和响应数据。无论是检测欺诈、个性化用户体验还是监控系统,现在都需要接近即时...【详细内容】
2024-01-26  Search: Python  点击:(46)  评论:(0)  加入收藏
Python分布式爬虫打造搜索引擎
简单分布式爬虫结构主从模式是指由一台主机作为控制节点负责所有运行网络爬虫的主机进行管理,爬虫只需要从控制节点那里接收任务,并把新生成任务提交给控制节点就可以了,在这个...【详细内容】
2024-01-25  Search: Python  点击:(58)  评论:(0)  加入收藏
▌简易百科推荐
Python 可视化:Plotly 库使用基础
当使用 Plotly 进行数据可视化时,我们可以通过以下示例展示多种绘图方法,每个示例都会有详细的注释和说明。1.创建折线图import plotly.graph_objects as go# 示例1: 创建简单...【详细内容】
2024-04-01  Python技术    Tags:Python   点击:(8)  评论:(0)  加入收藏
Python 办公神器:教你使用 Python 批量制作 PPT
介绍本文将介绍如何使用openpyxl和pptx库来批量制作PPT奖状。本文假设你已经安装了python和这两个库。本文的场景是:一名基层人员,要给一次比赛活动获奖的500名选手制作奖状,并...【详细内容】
2024-03-26  Python技术  微信公众号  Tags:Python   点击:(15)  评论:(0)  加入收藏
Python实现工厂模式、抽象工厂,单例模式
工厂模式是一种常见的设计模式,它可以帮助我们创建对象的过程更加灵活和可扩展。在Python中,我们可以使用函数和类来实现工厂模式。一、Python中实现工厂模式工厂模式是一种常...【详细内容】
2024-03-07  Python都知道  微信公众号  Tags:Python   点击:(31)  评论:(0)  加入收藏
不可不学的Python技巧:字典推导式使用全攻略
Python的字典推导式是一种优雅而强大的工具,用于创建字典(dict)。这种方法不仅代码更加简洁,而且执行效率高。无论你是Python新手还是有经验的开发者,掌握字典推导式都将是你技能...【详细内容】
2024-02-22  子午Python  微信公众号  Tags:Python技巧   点击:(32)  评论:(0)  加入收藏
如何进行Python代码的代码重构和优化?
Python是一种高级编程语言,它具有简洁、易于理解和易于维护的特点。然而,代码重构和优化对于保持代码质量和性能至关重要。什么是代码重构?代码重构是指在不改变代码外部行为的...【详细内容】
2024-02-22  编程技术汇    Tags:Python代码   点击:(32)  评论:(0)  加入收藏
Python开发者必备的八个PyCharm插件
在编写代码的过程中,括号几乎无处不在,以至于有时我们会拼命辨别哪个闭合括号与哪个开头的括号相匹配。这款插件能帮助解决这个众所周知的问题。前言在PyCharm中浏览插件列表...【详细内容】
2024-01-26  Python学研大本营  微信公众号  Tags:PyCharm插件   点击:(84)  评论:(0)  加入收藏
Python的Graphlib库,再也不用手敲图结构了
Python中的graphlib库是一个功能强大且易于使用的工具。graphlib提供了许多功能,可以帮助您创建、操作和分析图形对象。本文将介绍graphlib库的主要用法,并提供一些示例代码和...【详细内容】
2024-01-26  科学随想录  微信公众号  Tags:Graphlib库   点击:(85)  评论:(0)  加入收藏
Python分布式爬虫打造搜索引擎
简单分布式爬虫结构主从模式是指由一台主机作为控制节点负责所有运行网络爬虫的主机进行管理,爬虫只需要从控制节点那里接收任务,并把新生成任务提交给控制节点就可以了,在这个...【详细内容】
2024-01-25  大雷家吃饭    Tags:Python   点击:(58)  评论:(0)  加入收藏
使用Python进行数据分析,需要哪些步骤?
Python是一门动态的、面向对象的脚本语言,同时也是一门简约,通俗易懂的编程语言。Python入门简单,代码可读性强,一段好的Python代码,阅读起来像是在读一篇外语文章。Python这种特...【详细内容】
2024-01-15  程序员不二    Tags:Python   点击:(161)  评论:(0)  加入收藏
Python语言的特点及应用场景, 同其它语言对比优势
Python语言作为一种高级编程语言,具有许多独特的特点和优势,这使得它在众多编程语言中脱颖而出。在本文中,我们将探讨Python语言的特点、应用场景以及与其他语言的对比优势。一...【详细内容】
2024-01-09    今日头条  Tags:Python语言   点击:(250)  评论:(0)  加入收藏
站内最新
站内热门
站内头条