python中的魔法函数

python中的魔法函数以双下划线开头、结尾,不能自定义。下面介绍一些:

0、特殊属性

序号名称意义备注
(1)__doc__该函数的文档字符串,没有则为 None;不会被子类继承。可写
(2)__name__该函数的名称。可写
(3)__qualname__一个以点号分隔的名称,显示从模块的全局作用域到该模块中定义的某个类、函数或方法的“路径”可写
(4)__module__该函数所属模块(包)的名称,没有则为 None可写
(5)__defaults__由具有默认值的参数的默认参数值组成的元组,如无任何参数具有默认值则为 None。可写
(6)__code__表示编译后的函数体的代码对象。可写
(7)__globals__对存放该函数中全局变量的字典的引用 — 函数所属模块的全局命名空间。只读
(8)__dict__命名空间支持的函数属性。可写
(9)__closure__None 或包含该函数可用变量的绑定的单元的元组。只读
(10)__annotations__包含参数标注的字典。字典的键是参数名,如存在返回标注则为 ‘return’。可写
(11)__kwdefaults__仅包含关键字参数默认值的字典。可写

(3) __qualname__

class A:
  class B:
    def test(self):
      pass
print(A.__qualname__)
# A
print(A.B.__qualname__)
# A.B
print(A.B.test.__qualname__)
# A.B.test

(5) __defaults__

class A:
  def test(self,id=10,name='name'):
    pass
print(A.test.__defaults__)
print(A.test.__code__)
# (10, 'name')
# <code object test at 0x00000224ECB6F5D0, file "E:/WorkSpacepy/leetcode/test.py", line 2>

1、基本定制

序号名称意义备注
(1)__new__(self)静态方法,调用以创建一个 cls 类的新实例,返回对象实例。返回对象之后自动调用__init__()方法,如果没有返回值,则不会调用__init__()相关讲解1相关讲解2
(2)__init__(self)在实例被创建后,如果基类有__init__()方法,则显式的调用,以确保基类部分正确的初始化因为对象是由 __new__() 和 __init__() 协作构造完成的 (由 __new__() 创建,并由 __init__() 定制),所以 __init__() 返回的值只能是 None
(3)__del__(self)在实例将被销毁时调用del x 并不直接调用 x.__del__(), 前者会将 x 的引用计数减一,而后者仅会在 x 的引用计数变为零时被调用.
(4)__repr__(self)由内置函数repr()调用,以输出一个对象的字符串表示相关讲解1相关讲解2
(5)__str__(self)通过 str() 以及内置函数 format() 和 print() 调用以生成一个对象的字符串表示。返回值必须为一个 字符串对象。内置object会默认调用__repr__
(6)__bytes__(self)通过内置函数bytes()调用生成一个对象的字符串表示,返回一个bytes对象
(7)__format__(self,format_spec)通过 format() 内置函数、扩展、格式化字符串字面值 的求值以及 str.format() 方法调用以生成一个对象的“格式化”字符串表示。 format_spec 参数为包含所需格式选项描述的字符串。
(8)__lt__(self, other)x<y 调用 x.__lt__(y)
(9)__le__(self, other)x<=y 调用 x.__le__(y)
(10)__eq__(self, other)x==y 调用 x.__eq__(y)
(11)__ne__(self, other)x!=y 调用 x.__ne__(y)
(12)__gt__(self, other)x>y 调用 x.__gt__(y)
(13)__ge__(self, other)x>=y 调用 x.__ge__(y)
(14)__hash__(self, other)通过内置函数 hash() 调用以对哈希集的成员进行操作,属于哈希集的类型包括 set、frozenset 以及 dict。__hash__() 应该返回一个整数。对象比较结果相同所需的唯一特征属性是其具有相同的哈希值
(15)__bool__(self, other)调用此方法以实现真值检测以及内置的 bool() 操作;应该返回 False 或 True。如果未定义此方法,则会查找并调用 __len__() 并在其返回非零值时视对象的逻辑值为真。如果一个类既未定义 __len__() 也未定义 __bool__() 则视其所有实例的逻辑值为真。

2、自定义属性访问

序号名称意义备注
(1)__getattr__(self,name)当默认属性访问因引发 AttributeError 而失败时被调用请注意如果属性是通过正常机制找到的,__getattr__() 就不会被调用
(2)__getattribute__(self,name)此方法会无条件地被调用以实现对类实例属性的访问。如果类还定义了 __getattr__(),则后者不会被调用,除非 __getattribute__() 显式地调用它或是引发了 AttributeError。在查找属性时,先会调用__getattribute__(),如果__getattribute__()异常,就去调用__getattr__() 相关参考
(3)__setattr__(self,name,value)此方法在一个属性被尝试赋值时被调用。
(4)__delattr__(self,name)删除一个属性
(5)__dir__(self)此方法会在对相应对象调用 dir() 时被调用。返回值必须为一个序列。dir() 会把返回的序列转换为列表并进行字典排序。
(6)__class__()
(7)__get__(self,instance,owner)调用此方法以获取所有者类的属性(类属性访问)或该类的实例的属性(实例属性访问)使用描述器时必须作为一个类变量存储在另一个类中,属性查找时会根据描述器实例__get__方法识别出来
(8)__set__(self, instance, value)调用此方法以设置 instance 指定的所有者类的实例的属性为新值 value。
(9)__delete__(self, instance)调用此方法以删除 instance 指定的所有者类的实例的属性描述器介绍1
(10)__set_name__(self,owner,name)在所有者类 owner 创建时被调用。描述器会被赋值给 name。描述器介绍2
(11)__slots__类中的一个特殊属性参考
(12)__init_subclass___(cls)当所在的类派生子类时此方法就会被调用(默认什么都不做)参考
(13)__prepare__(name, bases, **kwds)一旦确定了适当的元类,则将准备好类命名空间。 如果元类具有 prepare 属性,它会以 namespace = metaclass.prepare(name, bases, **kwds) 的形式被调用(其中如果有任何额外的关键字参数,则应当来自类定义)。prepare(创建命名空间)-> 依次执行类定义语句 -> new(创建类)-> init(初始化类)参考
(14)__instancecheck__(self,instance)如果 instance 应被视为 class 的一个(直接或间接)实例则返回真值。如果定义了此方法,则会被调用以实现 isinstance(instance, class)
(15)__subclasscheck__(self,subclass)Return true 如果 subclass 应被视为 class 的一个(直接或间接)子类则返回真值。如果定义了此方法,则会被调用以实现 issubclass(subclass, class)。
(16)__class_getitem__(cls,key)按照 key 参数指定的类型返回一个表示泛型类的专门化对象
(17)__call__(self,args)此方法会在实例作为一个函数被“调用”时被调用直接将一个对象当做一个函数调用时,调用改函数
(18)__len__(self)调用此方法以实现内置函数 len()返回一个>=0的数,不过可以自定义
(19)__length_hint__(self)调用此方法以实现 operator.length_hint()。 应该返回对象长度的估计值(可能大于或小于实际长度,比如有些迭代器不知道实际长度)。 此长度应为一个 >= 0 的整数。参考
(20)__getitem__(self,key)调用此方法以实现 self[key] 的求值。对于序列类型,接受的键应为整数和切片对象。不合法应该引发KeyError
(21)__setitem__(self,key)调用此方法以实现向 self[key] 赋值。注意事项与 __getitem__() 相同。为对象实现此方法应该仅限于需要映射允许基于键修改值或添加键,或是序列允许元素被替换时。不合法与__getitem__异常相同
(22)__delitem__(self,key)调用此方法以实现 self[key] 的删除。不合法与__getitem__异常相同
(23)__missing__(self,key)如果有一个类继承了dict,然后这个继承类提供了 __missing__方法,那么在 __getitem__碰到找不到的键的时候,Python就会自动调用它,而不是抛出一个KeyError异常。只会被__getitem__调用,对get或者__contains__这些方法的使用是没有影响的
(24)__iter__(self)此方法在需要为容器创建迭代器时被调用。此方法应该返回一个新的迭代器对象,它能够逐个迭代容器中的所有对象。对于映射,它应该逐个迭代容器中的键。当同时定义了__iter__和__getitem__的时候,iter()函数优先选择__iter__,只有在__iter__不存在的时候才会选择__getitem__
(25)__reversed__(self)此方法(如果存在)会被 reversed() 内置函数调用以实现逆向迭代。
(26)__contains__(self,item)调用此方法以实现成员检测运算符。如果 item 是 self 的成员则应返回真,否则返回假。对于映射类型,此检测应基于映射的键而不是值或者键值对。对于未定义__contains__() 的对象,成员检测将首先尝试通过 __iter__() 进行迭代,然后再使用 __getitem__() 的旧式序列迭代协议
class Count(object):
  def __init__(self, mymin, mymax):
    self.mymin = mymin
    self.mymax = mymax
obj1 = Count(1, 10)
print(dir(obj1))
#['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'mymax', 'mymin']
# 这个输出按照字典排序了

3、模拟数字类型

序号名称意义备注
(1)__add__(self,other)+
(2)__sub__(self,other)-
(3)__mul__(self,other)*
(4)__matmul__(self,other)@
(5)__truediv__(self,other)/
(6)__floordiv__(self,other)//
(7)__mod__(self,other)%
(8)__divmod__(self,other)divmod(a,b)返回一个包含商和余数的元组(a/b,a%b)
(9)__pow__(self,other)pow(),**
(10)__lshift__(self,other)<<
(11)__rshift__(self,other)>>
(12)__and__(self,other)&
(13)__xor__(self,other)^
(14)__or__(self,other)|

以下表示实现具有反射操作数的二进制运算(即正向走不通走反向)。

序号名称意义备注
(1)__radd__(self,other)+
(2)__rsub__(self,other)-
(3)__rmul__(self,other)*
(4)__rmatmul__(self,other)@
(5)__rtruediv__(self,other)/
(6)__rfloordiv__(self,other)//
(7)__rmod__(self,other)%
(8)__rdivmod__(self,other)divmod(a,b)返回一个包含商和余数的元组(a/b,a%b)
(9)__rpow__(self,other)pow(),**
(10)__rlshift__(self,other)<<
(11)__rrshift__(self,other)>>
(12)__rand__(self,other)&
(13)__rxor__(self,other)^
(14)__ror__(self,other)|
class A:
    def __add__(self,other):
        print('this is add')
    def __radd__(self, other):
        print('this is radd')
class B:
    pass
a = A() 
b = B() 
c = B()
a+b # this is add
b+a # this is radd
b+c # TypeError: unsupported operand type(s) for +: 'B' and 'B'

原地操作

序号名称意义备注
(1)__iadd__(self,other)+=
(2)__isub__(self,other)-=
(3)__imul__(self,other)*=
(4)__imatmul__(self,other)@=
(5)__itruediv__(self,other)/=
(6)__ifloordiv__(self,other)//=
(7)__imod__(self,other)%=
(8)__idivmod__(self,other)divmod(a,b)返回一个包含商和余数的元组(a/b,a%b)
(9)__ipow__(self,other)pow(),**=
(10)__ilshift__(self,other)<<=
(11)__irshift__(self,other)>>=
(12)__iand__(self,other)&=
(13)__ixor__(self,other)^=
(14)__ior__(self,other)=

如果某个方法未被定义,相应的扩展算术赋值将回退到普通方法。例如,如果 x 是具有 __iadd__() 方法的类的一个实例,则 x += y 就等价于 x = x.__iadd__(y)。否则就如 x + y 的求值一样选择 x.__add__(y) 和 y.__radd__(x)
其他

序号名称意义备注
(1)__neg__(self)一元运算符 -
(2)__pos__(self)一元运算符 +
(3)__abs__(self)一元运算符 abs()
(4)__invert__(self)一元运算符 ~
(5)__complex__(self)complex()
(6)__int__(self)int()
(7)__float__(self)float()
(8)__index__(self)调用此方法以实现 operator.index() 以及 Python 需要无损地将数字对象转换为整数对象的场合(例如切片或是内置的 bin(), hex() 和 oct() 函数)。 存在此方法表明数字对象属于整数类型。 必须返回一个整数。如果未定义 __int__(), __float__() 和 __complex__() 则相应的内置函数 int(), float() 和 complex() 将回退为 __index__()。
(9)__round__(self)round()
(10)__trunc__(self)trunc
(11)__floor__(self)floor()
(12)__ceil__(self)ceil()
class A:
    def __init__(self,num):
        self.num = num
    def __neg__(self):
        return self.num[::-1]
a = A([1,2,3,4])
print(-a)
# [4, 3, 2, 1]

4、其他

序号名称意义备注
(1) __enter__(self)进入与此对象相关的运行时上下文。 with 语句将会绑定这个方法的返回值到 as 子句中指定的目标,如果有的话with 语句上下文管理器
(2) __exit__(self,exc_type,exc_value,traceback)退出关联到此对象的运行时上下文。 各个参数描述了导致上下文退出的异常如果上下文是无异常地退出的,三个参数都将为 None。 with 语句上下文管理器
(3) __await__(self)必须返回一个 iterator。 应当被用来实现 awaitable 对象。 例如,asyncio.Future 实现了此方法以与 await 表达式相兼容协程,可等待对象
(4) __aiter__(self)必须返回一个 异步迭代器 对象。异步迭代器
(5) __anext__(self)必须返回一个 可迭代对象 输出迭代器的下一结果值。 当迭代结束时应该引发 StopAsyncIteration 错误异步迭代器
(6) __aenter__(self)在语义上类似于 enter(),仅有的区别是它必须返回一个 可等待对象。异步上下文管理器
(7) __aexit__(self)在语义上类似于 exit(),仅有的区别是它必须返回一个 可等待对象。异步上下文管理器

主要参考python文档,表格内主要是由文档整理得来,辅以代码解释和大佬的介绍。对所有引用过的大佬表示衷心的感谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值