古之立大事者,不惟有超世之才,亦必有坚忍不拔之志。

Python高级编程和异步I/O并发编程笔记 2 魔法函数

Python admin 596℃ 0评论

魔法函数的概念

python中以“__”(双下划线)开头和结尾的函数,如“__getitem__()”可以使类成为可迭代的类型,可以直接使用for循环对类对象(含有可迭代属性)进行遍历。一般不要自己命名魔法函数(一般也无效),尽量使用python自带的魔法函数。魔法函数并不是和类挂钩,也不归属于Object类,只是设计用来增强类的类型,是一种独立的存在,在任何对象中都可以定义。

如上例,python中的迭代类型就是实现了对应迭代魔法函数的类,for语句其实就是拿到一个对象的迭代器(实现__iter__()魔法方法),在python中,做的优化是,如果拿不到迭代器,解释器会查找有没有实现__getitem__()方法。

python的数据模型和数据模型对python的影响

魔法函数其实就是python数据模型的概念,理解数据模型对理解python的设计理念很重要。魔法函数会影响python的语法。如上例,实现了__getitem__()魔法函数,使得对象称为迭代类型,可以实现for遍历,同时也使对象成为序列类型,可以进行切片操作。魔法函数也会影响python的内置函数,如对company1做len()计算,得到结果为2。原因在于内置函数len()会优先调用__len__()魔法函数,如果没有,则会查找__getitem__()函数。

魔法函数的划分

python的魔法函数可以从两个维度划分,即“非数学运算”和“数学运算”,前者包括字符串表示、集合序列相关、迭代相关、可调用、with上下文管理器、数值转换、元类相关、属性相关、属性描述符、协程;后者包括一元运算符、二元运算符、算术运算符、反向算术运算符、增量赋值算术运算符、位运算符、反向位运算符、增量赋值位运算符。

  • 字符串表示:__repr__、__str__;
  • 集合、序列相关:__len__、__getitem__、__setitem__、__delitem__、__contains__;
  • 迭代相关:__iter__、__next__;
  • 可调用:__call__;
  • with上下文管理器:__enter__、__exit__;
  • 数值转换:__abs__、__bool__、__int__、__float__、__hash__、__index__;
  • 元类相关:__new__、__init__;
  • 属性相关:__getattr__、__setattr__、__getattribute__、__setattribute__、__dir__;
  • 属性描述符:__get__、__set__、__delete__;
  • 协程:__await__、__aiter__、__anext__、__aenter__、__aexit__;

__str__:对字符串进行格式化时调用的,__repr__:开发模式调用的,与python语言做了紧密关联,如下例,直接调用company会输出abc,其他魔法函数也类似,此处其实是company.__repr__()自动调用,魔法函数不需要显示调用,只需要定义即可。

len函数的特性

python中的len()方法对内置类型(如list、dict、set)进行计算时,性能会很高,因为这时候会走捷径,原因在于这些内置类型都是使用C语言实现的,在使用cpython解释器时,会直接读取这些类型内在维护的“长度”数据,而不是遍历这个对象,所以在python中尽量使用python原生的类型。以此为例,说明python内部,python解释器会尽可能的去提高语言的性能,同时,解释器在内部做了很多优化,如for语句会从__iter__退化到__getitem__,很灵活,在__getitem__中也小心的处理了异常。

转载请注明:北凉柿子 » Python高级编程和异步I/O并发编程笔记 2 魔法函数

喜欢 (0)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址