zoukankan      html  css  js  c++  java
  • python 魔法方法(学习过程的笔记)

    有小伙伴会问,什么是python的魔法方法,python的魔法方法有什么用呢,

    它们在面向对象的Python的处处皆是。它们是一些可以让你对类添加“魔法”的特殊方法。 它们经常是两个下划线包围来命名的。

    我感觉魔法方法很牛逼的,

    目前我们常见的魔法方法大致可分为以下几类:

    • 构造与初始化
    • 类的表示
    • 访问控制
    • 比较操作
    • 容器类操作
    • 可调用对象
    • Pickling序列化 

    在我们写python中最常见的就是__init__,这是python的构造方法,这是初始化对象,定义一个对象的初始化的值,__new__  这个我们在实际的很少用到吧, 不过在一些开源的框架到我们能用到这个,__new__返回值是一个实例,

    __del__这个方法代表析构方法,也就是在对象被垃圾回收时被调用。但是请注意,执行del x不一定会执行此方法

    __str__/__repr__

    这两个魔法方法一般会放到一起进行讲解,它们的主要差别为:

    • __str__强调可读性,而__repr__强调准确性/标准性
    • __str__的目标人群是用户,而__repr__的目标人群是机器,它的结果是可以被执行的
    • %s调用__str__方法,而%r调用__repr__方法

    __setattr__

    通过此方法,对象可在在对属性进行赋值时进行控制,所有的属性赋值都会经过它。

    一般常用于对某些属性赋值的检查校验逻辑,例如age不能小于0,否则认为是非法数据等等。

    __getattr__

    很多同学以为此方法是和__setattr__完全对立的,其实不然!

    这个方法只有在访问某个不存在的属性时才会被调用,看上面的例子,由于gender属性在赋值时,忽略了此字段的赋值操作,所以此属性是没有被成功赋值给对象的。当访问这个属性时,__getattr__被调用,返回unknown

    __del__

    删除对象的某个属性时,此方法被调用。一般常用于某个属性必须存在,否则无法进行后续的逻辑操作,会重写此方法,对删除属性逻辑进行检查和校验。

    __getattribute__

    这个方法我们很少用到,它与__getattr__很容易混淆。它与前者的区别在于:

    • __getattr__访问某个不存在的属性被调用,__getattribute__访问任意属性被调用

    __getattr__只针对属性访问,__getattribute__不仅针对所有属性访问,还包括方法调用

    __iter__

    执行for x in obj时触发执行,用于迭代容器内的元素。

    __contains__

    执行x in obj时触发执行,用于判断某个元素是否存在于容器中。

    __reversed__

    执行reversed(obj)时触发执行,用于反转容器的元素,具体的反转逻辑可自己实现。

    反射

    __nstancecheck__(self, instance):检查一个实例是否是你定义类中的一个实例
    __ubclasscheck__(self, subclass):检查一个类是否是你定义类的子类

    数值操作符

    就像你可以使用比较操作符来比较类的实例,你也可以定义数值操作符的行为。固定好你的安全带,这样的操作符真的有很多。看在组织的份上,我把它们分成了五类:一元操作符,常见算数操作符,反射算数操作符,增强赋值操作符,和类型转换操作符。

    一元操作符

    一元操作符只有一个操作符。

    • __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)

      实现按位异或运算符 ^

    class DictDemo:
        def __init__(self,key,value):
            self.dict={}
            self.dict[key]=value
        def __getitem__(self,key):
            return self.dict[key]
        def __setitem__(self,key,value):
            self.dict[key]="key's value is %s"%value
        def __len__(self):
            return (len(self.dict))
    dictDemo=DictDemo('key0','value1')
    print(dictDemo['key0'])
    dictDemo['key1']='beijing'
    print(dictDemo['key1'])
    print(len(dictDemo))
    class word(str):
        def __eq__(self,other):
            return len(self)==len(other)
    
    w1=word('idshfisdojf')
    w2=word('sadsadas')
    print(w1==w2)
    print(len(w1))
    class Apple(object):
        def __init__(self,name,size):
            self.name=name
            self.size=size
        def __str__(self):
            return 'name is {}: size is {}'.format(self.name,self.size)
    print(Apple('liwanlei','100'))
    class Person(object):
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def __str__(self):
            return 'name :%s, age:%s'%(self.name,self.age)
        def __repr__(self):
            return "Person( '%s'%s)"%(self.name,self.age)
    person=Person('leizi','18')
    print(str(person))#name :leizi, age:18
    print(repr(person))#Person( 'leizi'18)
  • 相关阅读:
    使用javap分析Java的字符串操作
    使用javap深入理解Java整型常量和整型变量的区别
    分享一个WebGL开发的网站-用JavaScript + WebGL开发3D模型
    Java动态代理之InvocationHandler最简单的入门教程
    Java实现 LeetCode 542 01 矩阵(暴力大法,正反便利)
    Java实现 LeetCode 542 01 矩阵(暴力大法,正反便利)
    Java实现 LeetCode 542 01 矩阵(暴力大法,正反便利)
    Java实现 LeetCode 541 反转字符串 II(暴力大法)
    Java实现 LeetCode 541 反转字符串 II(暴力大法)
    Java实现 LeetCode 541 反转字符串 II(暴力大法)
  • 原文地址:https://www.cnblogs.com/leiziv5/p/7501531.html
Copyright © 2011-2022 走看看