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 作为第一个参数

  • 相关阅读:
    C# 文件类的操作---删除
    C#实现Zip压缩解压实例
    UVALIVE 2431 Binary Stirling Numbers
    UVA 10570 meeting with aliens
    UVA 306 Cipher
    UVA 10994 Simple Addition
    UVA 696 How Many Knights
    UVA 10205 Stack 'em Up
    UVA 11125 Arrange Some Marbles
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/onenoteone/p/12441774.html
Copyright © 2011-2022 走看看