zoukankan      html  css  js  c++  java
  • python-魔法方法

    http://blog.51cto.com/leejia/2132061?source=dra

    构造方法

    1.__init__:指明一个对象初始化的行为,它获取任何传给构造器的参数

    2.调用x = SomeClass() 的时候, __init__ 并不是第一个被调用的方法,事实上,第一个被调用的是 __new__ 

    3.对象的生命周期结束的时候, __del__ 会被调用


    比较

    __eq__(self, other)定义等于操作符(==)的行为。

    def __eq__(self, other): # 定义内置方法 ,判定类相等
    
        return self.__dict__ == other.__dict__ # 判断的是两对象空间的属性值是否相等

    __ne__(self, other)定义不等于操作符(!=)的行为。

    __lt__(self, other)定义小于操作符(<)的行为。

    __gt__(self, other)定义大于操作符(>)的行为。

    __le__(self, other)定义小于等于操作符(<)的行为。

    __ge__(self, other)定义大于等于操作符(>)的行为。


    一元操作

    __pos__(self)实现取正操作,例如 +some_object

    __neg__(self)实现取负操作,例如 -some_object

    __abs__(self)实现内建绝对值函数 abs() 操作。

    __invert__(self)实现取反操作符 ~

    __round__(self, n)实现内建函数 round() ,n 是近似小数点的位数。

    __floor__(self)实现 math.floor() 函数,即向下取整。

    __ceil__(self)实现 math.ceil() 函数,即向上取整。

    __trunc__(self)实现 math.trunc() 函数,即距离零最近的整数。


    算数操作

    __add__(self, other)实现加法操作。

    __sub__(self, other)实现减法操作。

    __mul__(self, other)实现乘法操作。

    __floordiv__(self, other)实现使用 // 操作符的整数除法。

    __div__(self, other)实现使用 / 操作符的除法。

    __truediv__(self, other)实现 _true_ 除法,这个函数只有使用 from __future__ import division 时才有作用。

    __mod__(self, other)实现 % 取余操作。

    __divmod__(self, other)实现 divmod 内建函数。

    __pow__实现 ** 操作符。

    __lshift__(self, other)实现左移位运算符 <<;

    __rshift__(self, other)实现右移位运算符>> 。

    __and__(self, other)实现按位与运算符 & 。

    __or__(self, other)实现按位或运算符 | 。

    __xor__(self, other)实现按位异或运算符 ^ 。


    反射算数运算

    some_object + other:是“常见”的加法;

    反射是一样的意思,只不过是运算符交换了一下位置:other + some_object;

    __radd__(self, other)实现反射加法操作。

    __rsub__(self, other)实现反射减法操作。

    __rmul__(self, other)实现反射乘法操作。

    __rfloordiv__(self, other)实现使用 // 操作符的整数反射除法

    .............


    增强赋值运算

    a += b

    __iadd__(self, other)实现加法赋值操作。

    __isub__(self, other)实现减法赋值操作。

    ..........


    类型转换操作

    __int__(self)实现到int的类型转换。

    __long__(self)实现到long的类型转换。

    __float__(self)实现到float的类型转换。

    __complex__(self)实现到complex的类型转换。

    __oct__(self)实现到八进制数的类型转换。

    __hex__(self)实现到十六进制数的类型转换。


    类的表示

    __str__(self)定义对类的实例调用 str() 时的行为, 产生人类可读的输出。

    __repr__(self)repr() 函数将对象转化为供解释器读取的形式,产生机器可读的输出(大部分情况下,其输出可以作为有效的Python代码)。


    访问控制

    __getattr__(self, name)当用户试图访问一个根本不存在(或者暂时不存在)的属性时,你可以通过这个魔法方法来定义类的行为。这个可以用于捕捉错误的拼写并且给出指引,使用废弃属性时给出警告,只有当试图访问不存在的属性时它才会被调用,所以这不能算是一个真正的封装的办法。

    __setattr__(self, name, value)它允许你自定义某个属性的赋值行为。

    __delattr__(self, name)这个魔法方法和 __setattr__ 几乎相同,只不过它是用于处理删除属性时的行为。

    使用注意

    def __setattr__(self, name. value):
        self.name = value
        # 因为每次属性幅值都要调用 __setattr__(),所以这里的实现会导致递归
        # 这里的调用实际上是 self.__setattr('name', value)。因为这个方法一直
        # 在调用自己,因此递归将持续进行,直到程序崩溃
    
    #正确形式
    def __setattr__(self, name, value):
        self.__dict__[name] = value # 使用 __dict__ 进行赋值
        # 定义自定义行为

    自定义序列

    可以让你的Python类表现得像是内建序列类型(字典,元组,列表,字符串等)

    Python中实现自定义容器类型需要用到一些协议。

    首先,不可变容器类型有如下协议:想实现一个不可变容器,你需要定义 __len__ 和 __getitem__ (后面会具体说明)。可变容器的协议除了上面提到的两个方法之外,还需要定义 __setitem__ 和 __delitem__ 。最后,如果你想让你的对象可以迭代,你需要定义 __iter__ ,这个方法返回一个迭代器。迭代器必须遵守迭代器协议,需要定义 __iter__ (返回它自己)和 next 方法。

    __len__(self)返回容器的长度,可变和不可变类型都需要实现。

    __getitem__(self, key)定义对容器中某一项使用 self[key] 的方式进行读取操作时的行为。这也是可变和不可变容器类型都需要实现的一个方法。它应该在键的类型错误式产生 TypeError 异常,同时在没有与键值相匹配的内容时产生 KeyError 异常。

    __setitem__(self, key)定义对容器中某一项使用 self[key] 的方式进行赋值操作时的行为。它是可变容器类型必须实现的一个方法,同样应该在合适的时候产生 KeyError 和 TypeError 异常。

    __iter__(self, key)它应该返回当前容器的一个迭代器。迭代器以一连串内容的形式返回,最常见的是使用 iter() 函数调用,以及在类似 for x in container: 的循环中被调用。迭代器是他们自己的对象,需要定义 __iter__方法并在其中返回自己。

    __reversed__(self)定义了对容器使用 reversed() 内建函数时的行为。它应该返回一个反转之后的序列。当你的序列类是有序时,类似列表和元组,再实现这个方法,

    __contains__(self, item)定义了使用 in 和 not in 进行成员测试时类的行为。你可能好奇为什么这个方法不是序列协议的一部分,原因是,如果 __contains__ 没有定义,Python就会迭代整个序列,如果找到了需要的一项就返回 True 。

    __missing__(self ,key)它定义了当试图访问一个字典中不存在的键时的行为(目前为止是指字典的实例,例如我有一个字典 d , "george" 不是字典中的一个键,当试图访问 d["george'] 时就会调用 d.__missing__("george") )

    例子:实现了一些函数式结构的列表

    class FunctionalList:
        '''一个列表的封装类,实现了一些额外的函数式
        方法,例如head, tail, init, last, drop和take。'''
    
        def __init__(self, values=None):
            if values is None:
                self.values = []
            else:
                self.values = values
    
        def __len__(self):
            return len(self.values)
    
        def __getitem__(self, key):
            # 如果键的类型或值不合法,列表会返回异常
            return self.values[key]
    
        def __setitem__(self, key, value):
            self.values[key] = value
    
        def __delitem__(self, key):
            del self.values[key]
    
        def __iter__(self):
            return iter(self.values)
    
        def __reversed__(self):
            return reversed(self.values)
    
        def append(self, value):
            self.values.append(value)
    
        def head(self):
            # 取得第一个元素
            return self.values[0]
    
        def tail(self):
            # 取得除第一个元素外的所有元素
            return self.valuse[1:]
    
        def init(self):
            # 取得除最后一个元素外的所有元素
            return self.values[:-1]
    
        def last(self):
            # 取得最后一个元素
            return self.values[-1]
    
        def drop(self, n):
            # 取得除前n个元素外的所有元素
            return self.values[n:]
    
        def take(self, n):
            # 取得前n个元素
            return self.values[:n]

     反射

    __instancecheck__(self, instance)检查一个实例是否是你定义的类的一个实例(例如 isinstance(instance, class) )。

    __subclasscheck__(self, subclass)检查一个类是否是你定义的类的子类(例如 issubclass(subclass, class) )。


    上下文管理器

    with open('foo.txt') as bar:
        # 使用bar进行某些操作

    with 声明创建时,上下文管理器允许类做一些设置和清理工作。上下文管理器的行为由下面两个魔法方法所定义:

    __enter__(self)定义使用 with 声明创建的语句块最开始上下文管理器应该做些什么。 __enter__ 的返回值会赋给 with 声明的目标,也就是 as 之后的名字。

    __exit__(self, exception_type, exception_value, traceback)定义当 with 声明语句块执行完毕(或终止)时上下文管理器的行为。它可以用来处理异常,进行清理,或者做其他应该在语句块结束之后立刻执行的工作。如果语句块顺利执行, exception_type , exception_value 和 traceback 会是 None 。否则,你可以选择处理这个异常或者让用户来处理。如果你想处理异常,确保 __exit__ 在完成工作之后返回 True 


    拷贝 

    copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。

    copy.deepcopy 深拷贝 拷贝对象及其子对象

    __copy__(self)返回一个对象的浅拷贝,这意味着拷贝出的实例是全新的,然而里面的数据全都是引用的。也就是说,对象本身是拷贝的,但是它的数据还是引用的(所以浅拷贝中的数据更改会影响原对象)。

    __deepcopy__(self, memodict=)实例使用 copy.deepcopy() 时的行为。 copy.deepcopy() 返回一个对象的深拷贝,这个对象和它的数据全都被拷贝了一份。当你想深拷贝一个单独的属性时,在那个属性上调用 copy.deepcopy() ,使用 memodict 作为第一个参数

  • 相关阅读:
    矩阵树定理
    随机乱搞算法
    数学
    BZOJ——3412: [Usaco2009 Dec]Music Notes乐谱
    BZOJ—— 3402: [Usaco2009 Open]Hide and Seek 捉迷藏
    洛谷—— P2884 [USACO07MAR]每月的费用Monthly Expense
    洛谷—— P2417 课程
    洛谷—— P1577 切绳子
    COGS 2598. 美丽的感觉
    10.23 模拟赛
  • 原文地址:https://www.cnblogs.com/onenoteone/p/12441774.html
Copyright © 2011-2022 走看看