• 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)
  • 相关阅读:
    关于初学者Could not find action or result :No result defined for action com.lyw.action.LoginAction and result success
    tomcat运行时候出现java.net.BindException: Address already in use: JVM_Bind错误解决方法
    关于jQuery中环境配置中的问题
    myeclicps开发web时候复制一个工程改名字后执行出现404错误
    非正常关闭myeclicps后,出现错误Errors occurred during the build.的解决方法
    【软件工程】读《人月神话》有感
    【软件工程】一个学期软件工程课的感想
    【软件工程】“谁是卧底”之NABC分析
    [软件工程] 查找二维数组最大子数组的之和 郭莉莉&李亚文
    【软件工程】软件开发方法综述
  • 原文地址:https://www.cnblogs.com/leiziv5/p/7501531.html
Copyright © 2020-2023  润新知