python魔术方法详解_python编程中魔术方法详解,需要避免的那些坑!

原标题:python编程中魔术方法详解,需要避免的那些坑!

python作为一门高级编程语言,它的定位是优雅、明确和简单。阅读Python编写的代码感觉像在阅读英语一样,这让使用者可以专注于解决问题而不是去搞明白语言本身。Python虽然是基于C语言编写,但是摒弃了C中复杂的指针,使其变得简明易学。并且作为开源软件,Python允许对代码进行阅读,拷贝甚至改进。这些性能成就了Python的高效率,有“人生苦短,我用Python”之说,是一种十分精彩又强大的语言。

魔术方法是 Python 类中那些定义名称类似__XXX__的函数,使用 Python 的魔术方法的优势在于可以使用 Python 提供的内置方法,比如len()、str(),或者重载运算符,让自定义对象类型可以表现得像内置类型一样。

Python 语言参考手册中一共列出了 83 个特殊方法的名字,其中 47 个用于实现算术运算、位运算和比较操作,概览如下。

跟运算符无关的特殊方法:

跟运算符相关的特殊方法:

有一份文档详细的介绍了所有的魔术方法的使用方式,本文只整理了常用魔术方法以及常见的坑methods.html

构造与析构

Python 对象通过__init__进行初始化,但是在执行__init__之前,首先被执行的是__new__函数。在初始化一个对象时,会先调用__new__方法,该方法是一个类方法,执行完相关逻辑之后调用__init__并将初始化参数传递给后者。

而__del__函数是 Python 对象的析构函数,无论是垃圾回收还是手动删除,都是执行这个方法:

class Model(object): def __init__(self): print("Run: __init__") def __del__(self): print("Run: __del__")if __name__ == "__main__": m = Model() del m

结果:

Run: __init__ Run: __del__

打印

在 Python 魔术方法中,有两个和打印有关,__repr__和__str__。

如果在 Python 直接打印一个类,将会获得一个内存

如果在解释器中想获得一个更友好的显示,__repr__是一个非常好的选择。另外,在不把 object 当做字符串处理的场合,也是会使用该方法。

而在把 object 当做字符串处理或者转换为字符串的场合,比如print(object)、"{}".format(object)、str(object)等,__str__将会被使用。

class Model(object): def __init__(self): self.id = uuid.uuid4() self.content = "fluent python demo" def __str__(self): return self.content def __repr__(self): return "".format(self.id)

一般在__str__中展现更人性化的信息,可能直接返回给用户;而__repr__更多为了在调试中使用方便(解释器中等)。

另外,如果__str__没有定义,那么将会直接使用__repr__方法,因此如果不需要太多差别,只定义后者即可。

数组与字典

如果需要定义一个类似列表的自定义类,为了支持通过下标访问,可以覆写__getitem__。

class Model(object): def __init__(self): self.content = [r for r in range(0, 3)] def __getitem__(self, item): return self.content[item]

该类从此支持了下标访问,并且还支持切片,排序等 Python 内置方法:

if __name__ == "__main__": m = Model() print(m[1:], sorted(m, reverse=True))

结果:

[1, 2] [2, 1, 0]

对于赋值操作,只需要覆写__setitem__方法:

def __setitem__(self, key, value): self.content[key] = value

同理,对于将自定义对象进行类似字典的操作,可以这样实现:

class Model(object): def __init__(self): self.content = { "key": "value" } def __getitem__(self, item): return self.content[item] def __setitem__(self, key, value): self.content[key] = value

类成员变量

类成员方法__getattr__、__getattribute__、__setattr__是三个方便且危险的方法,可以用来定义类成员属性,前两个是用来获取,最后一个是用来赋值。

前两个的区别是会被首先调用,只有找不到的时候,才会调用。

因为本身的类属性操作也是基于这几个方法,因此在覆写时应该避免循环调用最后栈溢出。

总结

简单讲了几种常见的魔术方法,魔术方法可以使得自定义类型支持 Python 原生、内置方法,因而使得代码风格更加简洁和一致。但是,也容易写出难以调试的魔法代码,简洁(或者说 geek)和可维护性可能本身就是两个极端,在使用魔术方法时还需要考虑后继维护者是否能理解自己的行为。python学习交流裙:588+090+942返回搜狐,查看更多

责任编辑:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值