python特殊方法(魔法方法)

写过python项目的同学一定非常熟悉__init__这个函数,我们经常在类中实现这个方法来初始化其成员变量,乍一看起来有点像java中的构造函数。实际上__new__才是一个类的构造函数,并且__new__方法都是在__init__之前执行,__new__返回的当前类的实例self是__init__的入参。

在python中,像__new__、__init__这样两边都有双下划线的方法,叫做魔法方法或者特殊方法,也叫双下方法(dunder method)。特殊方法在Python的语言设计中扮演着举足轻重的角色,是Python程序员进阶绕不开的知识点。Python语言参考手册中的"Data Model"(https://docs.python.org/3/reference/datamodel.html)一章中列出了83个特殊方法的名字,其中47个用于实现算数运算、位运算和比较操作。今天我们就来看下涉及到特殊方法常见的几个场景。

一、make custom types pythonic

在我们自定义的类中,我们去实现特定的双下方法,就可以使用相应的内置函数来操作我们的自定义类。

举个例子:

使用namedtuple定义一个纸牌类Card,rank代表大小,suit代表花色。

自定义FrenchDeck代表一副牌,保护变量(python中保护变量用单下划线开头)_cards代表13种大小和四种花色所组合成的52张不同的牌(这里不包含大小王)

复制代码
import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])         #具名元组

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')       #range左闭右开
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits
                                        for rank in self.ranks] #列表生成式求两个原列表的笛卡尔积

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, position):
        return self._cards[position]
复制代码

 首先新建一个FrenchDeck的实例(生成了一副牌):deck = FrenchDeck()

这时我们就可以用len(deck)返回一副牌的数量,因为len方法会调用类的__len__方法;我们可以用deck[0]、deck[1]直接获取一张牌,因为这实际调用的是__getitem__;更高级的,我们还可以对deck进行切片,对deck进行for循环迭代,这都得益于__getitem__。

二、operator overloading

常见算数运算符和对应特殊方法一览表:

+                  __add__

-                   __sub__

*                   __mul__

/                   __truedive__

//                  __floordive__

%                 __mod__

**                 __pod__

 

posted @   方山客  阅读(196)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示