一、什么是魔法函数(网络用语)

以双下划线开始,双下滑线结尾。魔法函数是为了增强一个类的特性。
魔法函数可以随意定义某个类的特性,这些方法在进行特定的操作时会自动被调用。

1 需求:封装一个员工列表,并遍历查看

(1)不使用魔法函数方法

class Company(object):def __init__(self, employee_list):self.employee = employee_listcompany = Company(["tom", "bob", "jane"])
employee = company.employee
for em in employee:print(em)

(2)使用__getitem__(self, item)魔法函数

class Company(object):def __init__(self, employee_list):self.employee = employee_listdef __getitem__(self, item):return self.employee[item]company = Company(["tom", "bob", "jane"])
for em in company:print(em)"""
在解释器执行到for语句时,解释器首先寻找对象的迭代器。
虽然company对象没有迭代器,
但是解释器会尝试去寻找__getitem__()这一魔法函数,
有了这个魔法函数的对象就是一个可迭代的类型,即便没有迭代器,
解释器会调用该魔法函数,直到其抛出异常结束。
若注释__getitem__代码片段,则会抛出不可迭代异常。
"""

注意:在案例中,魔法函数既不是属于<class ‘Company’>,也不是从<class ‘object’>基继承过来。是一个独立的存在,往类里放入魔法函数之后,会增强类的一些类型。魔法函数不需要我们显示调用。Python会识别对象或自定义类的魔法函数,并隐式调用。

2 Python的数据模型以及数据模型对Python的影响

实际上魔法函数是网络上通常的叫法,其实魔法函数只不过是Python数据类型的一个概念而已。

当实现了__getitem__(self, item)魔法函数,就可以使用for循环去遍历。魔法函数实际上会影响python语法的,或可以理解为Python语法实际上会识别一个对象或者说自定义类里的魔法函数。

# 使用__getitem__(self, item)魔法函数
class Company(object):def __init__(self, employee_list):self.employee = employee_listdef __getitem__(self, item):return self.employee[item]company = Company(["tom", "bob", "jane"])  # __getitem__(self, item) 实际上也是序列类型
company1 = company[:2]
print(company1)"""
['tom', 'bob']"""

如果不实现__getitem__(self, item)就会报错

class Company(object):def __init__(self, employee_list):self.employee = employee_list# def __getitem__(self, item):#     return self.employee[item]company = Company(["tom", "bob", "jane"])
company1 = company[:2]
print(company1)"""
Traceback (most recent call last):File "E:/projects/vue-django/myproject/sample/chapter02/company03.py", line 14, in <module>company1 = company[:2]
TypeError: 'Company' object is not subscriptable"""
class Company(object):def __init__(self, employee_list):self.employee = employee_list# def __getitem__(self, item):#     return self.employee[item]company = Company(["tom", "bob", "jane"])
print(len(company))  # 没有定义__len__(self)或__getitem__(self, item)魔法函数时,这个语句会报错"""
Traceback (most recent call last):File "E:/projects/vue-django/myproject/sample/chapter02/company03.py", line 14, in <module>print(len(company))
TypeError: object of type 'Company' has no len()
"""

两种方式实现对象可len()
(1)getitem(self, item) + 切片 实现
(2)len(self, item) 实现
在调用内置函数len()时,解释器首先会调用魔法函数__len__(self),若没有,则退一步,去不断调用__getitem__(self, item)直到抛出异常,len()函数返回执行次数。

# 使用__getitem__(self, item)魔法函数 + 切片
class Company(object):def __init__(self, employee_list):self.employee = employee_listdef __getitem__(self, item):return self.employee[item]company = Company(["tom", "bob", "jane"])
company1 =company[:]
print(len(company1))"""
3
"""
# 使用__len__(self)魔法函数
class Company(object):def __init__(self, employee_list):self.employee = employee_listdef __len__(self):return len(self.employee)company = Company(["tom", "bob", "jane"])
print(len(company))"""
3
"""

魔法函数会影响Python语法和其内置函数本身的。

二、魔法函数一览

1 非数学运算

字符串表示 魔法函数提供了两个来应对开发模式的不同
(1)repr 用于命令行模式,作用:输入对象名即可调用repr方法

  # jupyter或ipython 命令行终端运行class Company(object):def __init__(self, employee_list):self.employee = employee_listdef __repr__(self):return ','.join(self.employee)company = Company(['tom', 'bob', 'jane'])company"""tom,bob,jane"""

(2)__str__用于脚本,作用:print(对象名)即可调用str方法

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''class Company(object):def __init__(self, employee_list):self.employee = employee_listdef __str__(self):return ','.join(self.employee)company = Company(['tom', 'bob', 'jane'])print(company)  """tom,bob,jane"""

魔法函数只要定义了,就不需要开发者调用,Python解释器自己知道什么时候调用它。

集合、序列相关__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

2 数学运算

数学运算在一般开发使用不多,在数据处理是用的比较多,这里简单举几个例子。

# ============== __abs__ Demo start ============
class Nums(object):def __init__(self, num):self.num = numdef __abs__(self):return abs(self.num)num = Nums(-1)
print(abs(num))  # 结果:1
# ============== __abs__ Demo end ============# ============== __add__ Demo start ============
class MyVector(object):def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other_instance):re_vector = MyVector(self.x+other_instance.x, self.y+other_instance.y)return re_vectordef __str__(self):return "x:{x}, y:{y}".format(x=self.x, y=self.y)first_vec = MyVector(1, 2)
second_vec = MyVector(2, 3)
print(first_vec+second_vec)  # 结果:x:3,y:5
# ============== __add__ Demo end ============一元运算符__neg__    -__pos__    +__abs__   |x|二元运算符__lt__    <__le__    <=__eq__    ==__ne__    != __gt__    > __ge__    >=算术运算符__add__         +__sub__         -__mul__         * __truediv__     /__floordiv__    // __mod__         % __divmod__      divmod() __pow__         ** 或 pow()__round__       round()反向算术运算符__radd__ __rsub__ __rmul__ __rtruediv__ __rfloordiv__ __rmod__ __rdivmod__ __rpow__增量赋值算术运算符__iadd__ __isub__ __imul__ __itruediv__ __ifloordiv__ __imod__ __ipow__位运算符__invert__    ~ __lshift__    << __rshift__    >> __and__       & __or__        | __xor__       ^反向位运算符__rlshift__ __rrshift__ __rand__ __rxor__ __ror__增量赋值位运算符__ilshift__ __irshift__ __iand__ __ixor__ __ior__

四、len函数的特殊性

len函数不仅仅调用__len__方法这么简单,len函数对于set dict list等Python原生数据结构做了内部的优化,其性能是非常高的。应为原生数据结构中,会有一个专门的字段来储存数据长度,那么len函数会直接去读取这个字段,而不会去遍历它。

Python学习:魔法函数相关推荐

  1. 零基础学python:魔法函数都有了解吗

    python中常见的内置类型 什么是魔法函数? python的魔法函数总被双下划线包围,它们可以给你的类增加特殊的方法.如果你的对象实现了这些方法中的一个,那么这个方法就会在特殊情况下被调用,你可以定 ...

  2. python中魔法函数_Python魔法函数

    python中定义的以__开头和结尾的的函数.可以随意定制类的特性.魔法函数定义好之后一般不需要我们自己去调用,而是解释器会自动帮我们调用. __getitem__(self, item) 将类编程一 ...

  3. Python学习之函数返回多个值

    Python学习之函数返回多个值 问题的引出 Python中,一个函数能不能一次返回多个值? 在C语言中,函数最多返回一个值,如果要返回多个值,可以把这些值封装在一个结构体中.注意,C语言不允许函数返 ...

  4. gj3 Python数据模型(魔法函数)

    3.1 什么是魔法函数 类里面,实现某些特性的内置函数,类似 def __xx__(): 的形式. 不要自己定义XX,并不是和某个类挂钩的 class Company(object):def __in ...

  5. python判断特殊字符的函数,python学习--quote()函数,,屏蔽特殊的字符、比如

    python学习--quote()函数,,屏蔽特殊的字符.比如 屏蔽特殊的字符.比如如果url里面的空格!url里面是不允许出现空格的. 在 Python2.x 中的用法是: urllib.quote ...

  6. python学习 字符串函数

    python学习 字符串函数 字符串不能被改变,以下和函数,只是 原字符串初始化后不能改变,函数只是将改变后的值返回赋给新的变量(当然可以赋给原来的变量) 大小写函数 capitalize()函数 大 ...

  7. Python深度学习 魔法函数2

    对于魔法函数__repr__来说,他是可以把一个对象用字符串表达出来,以便于更好的区分,对于__str__来说,它也是返回字符串,只是对于终端用户更友好一些. class Person:def __i ...

  8. python常用魔法函数

    1.__init__(): 所有类的超类object,有一个默认包含pass的__init__()实现,这个函数会在对象初始化的时候调用,我们可以选择实现,也可以选择不实现,一般建议是实现的,不实现对 ...

  9. python 魔法函数 运行时_16个python常用魔法函数

    ==,is的使用 ·is是比较两个引用是否指向了同一个对象(引用比较). ·==是比较两个对象是否相等 1.__ init__(): 所有类的超类object,有一个默认包含pass的__ init ...

  10. python常用函数-python常用魔法函数

    1.__init__(): 所有类的超类object,有一个默认包含pass的__init__()实现,这个函数会在对象初始化的时候调用,我们可以选择实现,也可以选择不实现,一般建议是实现的,不实现对 ...

最新文章

  1. 百度地图搜索返回地址中经纬度为null
  2. segformer 使用笔记
  3. 党建信息发布服务器要求,党建云服务器繁忙
  4. BD云20MB/s不限速,随时下架!
  5. 面向对象(匿名内部类在开发中的应用)
  6. 苹果收购人工智能初创公司Voysis以改善语音助手Siri功能
  7. 为什么macOS比Windows快那么多,是硬件的缘故么?
  8. 大智慧公式系统:语法
  9. c语言scanf中输入根号2,C语言格式输入函数scanf()详解
  10. 对面板数据模型中的一些理解
  11. FlinkX配置文件解析
  12. 使用Qt实现阿里云API签名
  13. HTML初学者--列表的简单制作
  14. 一篇搞懂OOA/OOD/OOP的区别
  15. 网络发现自动关闭不能启用、无法启用文件和打印共享的解决办法
  16. 中位数的应用—士兵站队问题
  17. CT时间与当前时间的大小比较
  18. Quill编辑器操作实例详解
  19. BurpSuite学习:在火狐浏览器使用foxyproxy添加代理127.0.0.1后无法正常上网
  20. 台达JAVA_java开发方向面试-台达电子-数码视讯

热门文章

  1. matlab从无到有系列(七):GUI程序设计
  2. 微信小程序调用数据库增删改查
  3. 提取四位数的千位,百位,十位,个位
  4. 张艾迪(创始人):第一个实习生精英团队
  5. 灰度变换及dithering抖动算法
  6. (建议收藏)一文多图,彻底搞懂Floyd算法(多源最短路径)
  7. 安排电影院座位--贪心算法
  8. VUE/使用echarts格式化浮窗自定义按钮及事件
  9. stm32的几种读保护措施讲解
  10. 关于DHT网络及其缺陷的初步了解