Python进阶:魔法函数

Python进阶:魔法函数(Magic Methods)

1. 什么是魔法函数?

所谓魔法函数(Magic Methods),是Python的一种高级语法,允许你在类中自定义函数(函数名格式一般为__xx__),并绑定到类的特殊方法中。比如在类A中自定义__str__()函数,则在调用str(A())时,会自动调用__str__()函数,并返回相应的结果。在我们平时的使用中,可能经常使用__init__函数和__del__函数,其实这也是魔法函数的一种。

2. 魔法函数有什么作用

魔法函数可以为你写的类增加一些额外功能,方便使用者理解。举个简单的例子,我们定义一个“人”的类People,当中有属性姓名name、年龄age。让你需要利用sorted函数对一个People的数组进行排序,排序规则是按照name和age同时排序,即name不同时比较name,相同时比较age。由于People类本身不具有比较功能,所以需要自定义,你可以这么定义People类:

class People(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        return

    def __str__(self):
        return self.name + ":" + str(self.age)

    def __lt__(self, other):
        return self.name < other.name 
    			if self.name != other.name else self.age < other.age

print(
    "\t".join(
        [
            str(item) for item in sorted(
                [
                    People("abc", 18), 
                    People("abe", 19), 
                    People("abe", 12), 
                    People("abc", 17)]
            )
        ]
    )
)

上个例子中的__lt__函数即less than函数,即当比较两个People实例时自动调用。

再举个例子,实现一个可以任意深度赋值的字典类,如a[0] = ‘value1’; a[1][2] = ‘value2’; a[3][4][5] = ‘value3’。这个和Python自带的defaultdict还有些区别。简单分析一下这个题目:普通的dict可以实现a[0]赋值,但是无法给a[1][2]直接赋值;后者赋值的过程大概为a.get(1).set(2, value),但我们不确定a[1]是否存在,所以很自然会想到要改写dict类中的__getitem__()函数,当a[1]不存在时,声明一个dict,并赋值给a[1]。代码如下:

class MyDict(dict):
    def __setitem__(self, key, value):  # 该函数不做改动,只是为了输出
        print("setitem:", key, value, self)
        super().__setitem__(key, value)
        return

    def __getitem__(self, item):                # 主要技巧在该函数
        print("getitem:", item, self)
        # 基本思路: a[1][2]赋值时 需要先取出a[1] 然后给a[1]的[2]赋值
        if item not in self:                    # 如果a[1]不存在
            temp = MyDict()                     # 则需要新建一个dict
            super().__setitem__(item, temp)     # 并使得a[1] = dict
            return temp                         # 返回a[1] 使得a[1][2] = value有效
        return super().__getitem__(item)        # 如果a[1]存在 则直接返回a[1]

# 使用例子:
test = MyDict()
test[0] = 'test'
test[1][2] = 'test1'
test[3][4][5] = 'test2'

3. Python有哪些魔法函数

Python中每个魔法函数都对应了一个Python内置函数或操作,比如__str__对应str函数,__lt__对应小于号<等。Python中的魔法函数可以大概分为以下几类:

3.1 类的构造、删除

object.__new__(self, ...)
object.__init__(self, ...)
object.__del__(self)

3.2 二元操作符

+		object.__add__(self, other)
-		object.__sub__(self, other)
*		object.__mul__(self, other)
//		object.__floordiv__(self, other)
/		object.__div__(self, other)
%		object.__mod__(self, other)
**		object.__pow__(self, other[, modulo])
<<		object.__lshift__(self, other)
>>		object.__rshift__(self, other)
&		object.__and__(self, other)
^		object.__xor__(self, other)
|		object.__or__(self, other)

3.3 扩展二元操作符

+=		object.__iadd__(self, other)
-=		object.__isub__(self, other)
*=		object.__imul__(self, other)
/=		object.__idiv__(self, other)
//=		object.__ifloordiv__(self, other)
%=		object.__imod__(self, other)
**=		object.__ipow__(self, other[, modulo])
<<=		object.__ilshift__(self, other)
>>=		object.__irshift__(self, other)
&=		object.__iand__(self, other)
^=		object.__ixor__(self, other)
|=		object.__ior__(self, other)

3.4 一元操作符

-			object.__neg__(self)
+			object.__pos__(self)
abs()		object.__abs__(self)
~			object.__invert__(self)
complex()	object.__complex__(self)
int()		object.__int__(self)
long()		object.__long__(self)
float()		object.__float__(self)
oct()		object.__oct__(self)
hex()		object.__hex__(self)
round()		object.__round__(self, n)
floor()		object__floor__(self)
ceil()		object.__ceil__(self)
trunc()		object.__trunc__(self)

3.5 比较函数

<		object.__lt__(self, other)
<=		object.__le__(self, other)
==		object.__eq__(self, other)
!=		object.__ne__(self, other)
>=		object.__ge__(self, other)
>		object.__gt__(self, other)

3.6 类的表示、输出

str()				object.__str__(self) 
repr()				object.__repr__(self)
len()				object.__len__(self)
hash()				object.__hash__(self) 
bool()				object.__nonzero__(self) 
dir()				object.__dir__(self)
sys.getsizeof()		object.__sizeof__(self)

3.7 类容器

len()	object.__len__(self)
self[key]	object.__getitem__(self, key)
self[key] = value	object.__setitem__(self, key, value)
del[key] object.__delitem__(self, key)
iter()	object.__iter__(self)
reversed()	object.__reversed__(self)
in操作	object.__contains__(self, item)
字典key不存在时	object.__missing__(self, key)

bject.delitem(self, key)
iter() object.iter(self)
reversed() object.reversed(self)
in操作 object.contains(self, item)
字典key不存在时 object.missing(self, key)


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值