python高阶3:魔法函数

    Python作为一种动态的语言,底部采用的是鸭子模型的机制,即:当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。

    从具体实现上就是采用魔法函数来实现各种各样的附加功能或者属性。不支持自定义,只能使用Python自带的已编写好的。

主要分成:1.非数学运算;2.数学运算。

1.非数学运算:

  1.1字符串表示:__repr__,__str__

  1.2集合序列相关:__len__,__getitem__,__setitem__,__delitem__,__contains__

  1.3迭代相关:__iter__,__next__

  1.4可调用:__call__

  1.5with上下文管理器:__enter__,__exit__

  1.6数值转换:__abs__,__bool__,__int__,__float__,__hash__,__index__

  1.7元类相关:__new__,__init__

  1.8属性相关:__getattr__、 __setattr__,__getattribute__、setattribute__,__dir__

  1.9属性描述符:__get__、__set__、 __delete__

  1.10协程:__await__、__aiter__、__anext__、__aenter__、__aexit__

2.数学运算:

  2.1一元运算符:__neg__(-)、__pos__(+)、__abs__

2.2二元运算符:__lt__(<)、 __le__ <= 、 __eq__ == 、 __ne__ != 、 __gt__ > 、 __ge__ >=

  2.3算术运算符:__add__ + 、 __sub__ - 、 __mul__ * 、 __truediv__ / 、 __floordiv__ // 、 __mod__ % 、 __divmod__ divmod() 、 __pow__ ** 或 pow() 、 __round__ round()

  2.4反向算术运算符:__radd__ 、 __rsub__ 、 __rmul__ 、 __rtruediv__ 、 __rfloordiv__ 、 __rmod__ 、__rdivmod__ 、 __rpow__

  2.5增量赋值算术运算符:__iadd__ 、 __isub__ 、 __imul__ 、 __itruediv__ 、 __ifloordiv__ 、 __imod__ 、__ipow__

  2.6位运算符:__invert__ ~ 、 __lshift__ << 、 __rshift__ >> 、 __and__ & 、 __or__ | 、 __xor__ ^

  2.7反向位运算符:__rlshift__ 、 __rrshift__ 、 __rand__ 、 __rxor__ 、 __ror__

  2.8增量赋值位运算符:__ilshift__ 、 __irshift__ 、 __iand__ 、 __ixor__ 、 __ior__


具体源码解析:本质是for循环是一个迭代器,类本身没有迭代器,如果拿不到迭代器,就会尝试获取相关方法,例如iter,getitem等,直到没有对应可以迭代的函数或者方法,才会抛出异常。本质getitem是为类赋予了可迭代遍历的功能,解释器自己帮我们进行的,不需要特殊干预。

class Person(object):

    def __init__(self, boys):

        self.p_boys = boys

    def __len__(self):

        return len(self.p_boys)

    def __getitem__(self, item):

    # 魔法函数本身不是类的方法,任意类都可以添加,魔法函数和专属类不挂钩,只是增强类的属性或者方法。增加后变成可迭代的类型。

            return self.p_boys[item]

if __name__ =='__main__':

    boys = ['hzb1','hzb2','hzb3']

    p1 = Person(boys)

    p1_boys = p1.p_boys

    # 直接访问类对象,去寻找遍历。不添加的话会报:TypeError: 'Person' object is not iterable

    for onein p1:

        print(one)

    print(p1[1])   # 支持切片  # 背后的原理是__getitem__这个魔法函数在起作用。

    print(len(p1))# 支持统计长度

本身魔法函数使用的不多,本身只是数据模型的概念而已,不属于继承,也不属于这个类对象,可以认为是独立的存在,增加后丰富了这个类的类型。了解魔法函数的使用和数据模型对于了解Python的设计理念非常重要。


    再比如:

class Cat(object):

"""字符串格式化。"""

    def __init__(self, color):

        self.name ="猫咪"

        self.color = color

    def __str__(self):

        return ",".join(self.color)

    def __repr__(self):

        return ",".join(self.color)

    if __name__ =='__main__':

        c1 = Cat(['red','green','blue'])

        print(c1)   # => c1 本来只会打印内存地址。 red,green,blue

你可能感兴趣的:(python高阶3:魔法函数)