python魔法方法学不懂_Python中魔法方法的学习

本文深入探讨了Python中的魔法方法,包括构造器、解构器、字符串表示、长度计算等,并通过示例展示了如何使用这些方法来自定义类的行为。

概念解析

魔法方法是python的一种高级语法,他们是可以给你的类增加“magic”的特殊方法,比如:增加一些额外的功能。函数格式为_ xx _(被双下划线包围的函数)。

魔法方法

基本定制

object.__init__(self, *args, **kwargs) # 构造器,创建完对象后调用,进行当前实例的初始化

object.__new__(cls, *args, **kwargs) # 构造器,创建对象时调用,返回值是一个对象

object.__del__(self) # 解构器,删除对象时调用

object.__str__(self) # 若类C中实现此方法,当str(C())时此方法被调用

object.__len__(self) # 若类C中实现此方法,当len(C())时此方法被调用

测试代码如下:

# coding=utf-8

class MagicDemo(object):

def __init__(self):

"""对当前对象的实例的一些初始化"""

print "call me second"

self.value = [1, 2, 3]

def __new__(cls, *args, **kwargs):

"""

真正的构造函数,先于__init__调用,

返回创建的对象

"""

print "call me first"

return super(MagicDemo, cls).__new__(cls, *args, **kwargs)

def __del__(self):

print "call __del__"

del self

def __len__(self):

print "call __len__"

return len(self.value)

def __str__(self):

return "call __str__"

if __name__ == '__main__':

mag = MagicDemo()

print mag.value

print len(mag)

print str(mag)

del mag

运行结果如下:

call me first

call me second

[1, 2, 3]

call __len__

3

call __str__

call __del__

比较函数

object.__lt__(self, obj) # 小于比较 <

object.__le__(self, obj) # 小于或等于 <=

object.__gt__(self, obj) # 大于 >

object.__ge__(self, obj) # 大于多等于 >=

object.__eq__(self, obj) # 等于 ==

object.__ne__(self, obj) # 不等于 !=

测试代码如下:

# coding=utf-8

class MagicDemo(object):

def __init__(self, value):

self.value = value

def __lt__(self, obj):

print "call the __lt__"

return self.value < obj.value

def __le__(self, obj):

print "call the __le__"

return self.value <= obj.value

def __gt__(self, obj):

print "call the __gt__"

return self.value > obj.value

def __ge__(self, obj):

print "call the __ge__"

return self.value >= obj.value

def __eq__(self, obj):

print "call the __eq__"

return self.value == obj.value

def __ne__(self, obj):

print "call the __ne__"

return self.value != obj.value

if __name__ == '__main__':

mag1 = MagicDemo(5)

mag2 = MagicDemo(6)

print mag1 < mag2

print mag1 <= mag2

print mag1 > mag2

print mag1 >= mag2

print mag1 == mag2

print mag1 != mag2

运行结果如下:

call the __lt__

True

call the __le__

True

call the __gt__

False

call the __ge__

False

call the __eq__

False

call the __ne__

True

属性操作

object.__getattr__(self, attr) # 获取属性,仅当属性找不到时被调用

object.__setattr__(self, attr, val) # 设置属性,当设置属性的值时被调用

object.__delattr__(self, attr) # 删除属性时被调用

object.__getattribute__(self, attr) # 获取属性,总是被调用,发生异常时调用__getattr__

object.__get__(self, attr) #(描述符)获取属性

object.__set__(self, attr, val) #(描述符)设置属性

object.__delete__(self, attr) #(描述符)删除属性

测试代码(描述符的三个属性暂不说明)

# coding=utf-8

class MagicDemo(object):

def __init__(self, value):

self.value = value

def __getattr__(self, attr):

"""找不到属性时被调用"""

print "call __getattr__"

return "%s no found" % attr

def __setattr__(self, attr, value):

print "call __setattr__"

self.__dict__[attr] = value

def __delattr__(self, attr):

print "call __delattr__"

del self.__dict__[attr]

def __getattribute__(self, attr):

"""此方法只适用于新式类"""

print "call __getattribute__"

# return self.__dict__[name]

# 为了避免陷入死循环

return object.__getattribute__(self, attr)

if __name__ == '__main__':

mag = MagicDemo(5)

print "_______________"

mag.value = 6

print "_______________"

print mag.value

print "_______________"

print mag.xxx

测试结果如下:

call __setattr__

call __getattribute__

_______________

call __setattr__

call __getattribute__

_______________

call __getattribute__

6

_______________

call __getattribute__

call __getattr__

xxx no found

可以看出,当访问对象的属性时,__getattribute__总是被调用(新式类中有效),当找不到属性时,将调用__getattr__。其中__getattribute__调用基类的方法是为了陷入死循环,因为__getattribute__总是无条件的被调用。

自定义序列

object.__getitem__(self, key) # 得到单个序列元素

object.__setitem__(self, key, val) # 设置单个序列元素

object.__delitem__(self, key) # 删除单个序列元素

object.__contains__(self, key) # 测试序列元素,使用in时调用

object.__iter__(self) # 返回一个迭代器

测试代码:

# coding=utf-8

class MagicDemo(object):

def __init__(self):

self.value = dict()

def __getitem__(self, key):

print "call the __getitem__"

return self.value[key]

def __setitem__(self, key, val):

print "call the __setitem__"

self.value[key] = val

def __delitem__(self, key):

print "call the __delitem__"

del self.value[key]

def __contains__(self, key):

print "call the __contains__"

return key in self.value

if __name__ == '__main__':

mag = MagicDemo()

mag["name"] = "hello"

print "_______________"

print mag["name"]

print "_______________"

print "xxx" in mag

测试结果如下:

call the __setitem__

_______________

call the __getitem__

hello

_______________

call the __contains__

False

需要注意的是当属性为dict时通过键值对进行赋值,当为list时,通过下标进行赋值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值