美文网首页
30.3-魔术方法—bool和可视化

30.3-魔术方法—bool和可视化

作者: BeautifulSoulpy | 来源:发表于2019-12-23 21:30 被阅读0次

    任何事,任何人,都会成为过去,不要跟它过不去!

    总结:

    1. 直接作为str()函数、format()函数、print()函数参数调用时,调用_str_方法; 被间隔作为参数被调用时,调用_repr_方法;
    2. print 打印不作数;数据类型需要判断,打印的不做数;注意不能通过判断是否带引号判断输出值的类型,类型判断要使用type或isinstance

    面向对象中,任何一个实例对象都可以hash,因为object实现了,用它的内存地址参与进来做这事;
    这个对象我们需要特殊的去构造这个hash值;我们能不能hash函数设定一个你想指定的hash值呢?

    set、dict中用到hash;

    魔术方法(Magic Methods),顾名思义,就是可以为代码中的类赋予某种“魔力”的方法(methods)。有了它,你可以构造出非常巧妙、优雅的代码。

    1. _bool_

    class A:pass
    
    print(A)  # 类有字符串的表达形式;
    print(bool(A))
    
    # 等价形式
    if A:
        print(1,'True')
    if A():
        print(2,'True')
    print(bool(A),bool(A()))
    
    print(dir(A))  # A,A() 内没有__bool__,默认它是真;
    #---------------------------------------------------------------------
    <class '__main__.A'>
    True
    1 True
    2 True
    True True
    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
    

    _bool_ 和 _len_

    方法 意义
    _bool_ 内建函数bool(),或者对象放在逻辑表达式的位置,调用这个函数返回布尔值。没有定义 bool (),就找 len ()返回长度,非0为真。如果 len ()也没有定义,那么所有实例都返回真
    _len_ 尝试调用len()时触发,可用来检测对象参数的信息。self表示当前对象,返回值必须时整型。
    class B:
        def __bool__(self):   # B真; B()实例 return False;
            return False
    if B:
        print('True')
        
    if B():
        print('True')
    else:
        print('False')
    print('-'*40)
    class C:
        def __len__(self):
            return False
    if C:
        print(True)
    if C():
        print(True)
    else:
        print(False)
    print(C.__dict__)
    #--------------------------------------------------------------------------------------------------------------------------
    True
    False
    ----------------------------------------
    True
    False
    {'__module__': '__main__', '__len__': <function C.__len__ at 0x000001E41D1559D8>, '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None}
    
    
    # 同时存在bool和len;
    print('-'*40)
    class C:
        def __bool__(self):
            return False
        def __len__(self):
            return 5
    if C:
        print(True)
    if C():
        print(True)
    else:
        print(False)
    print(C.__dict__)
    #------------------------------------------------------------------------------------
    True
    False
    {'__module__': '__main__', '__bool__': <function C.__bool__ at 0x000001E41D14AE18>, '__len__': <function C.__len__ at 0x000001E41D14A400>, '__dict__': <attribute '__dict__' of 'C' objects>, '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None}
    
    真值测试的运行机制

    了解了两种魔术方法后,我们对真值测试的流程做一个介绍。假设我们要对一个Python对象进行真值测试:

    1. 如果该对象定义了bool方法,则依bool方法返回的真值作为该对象的真值。
    2. 否则,如果该对象定义了len方法,则根据len方法返回的整数进行判断,返回值为0则真值为False,不为0则真值为True;
    3. 否则,该对象的真值为True;
    内置函数bool()

    Python有一个内置函数bool(),它接受一个对象作为参数,返回的就是该对象在Python下进行真值测试的结果,即该函数返回一个bool变量,该变量的值的判断方法与上面介绍的真值测试完全一致。

    2. 可视化

    方法 意义
    _repr_ 内建函数repr()对一个对象获取字符串表达。调用 _repr_ 方法返回字符串表达,如果 repr 也没有定义,就直接返回object的定义;就是显示内存地址信息
    _str_ str()函数、format()函数、print()函数调用,需要返回对象的字符串表达。如果没有定义,就去调用 repr 方法返回字符串表达,如果 repr 没有定义,就直接返回对象的内存地址信息
    _bytes_ bytes()函数调用,返回一个对象的bytes表达,即返回bytes对象
    class A:
        def __init__(self,name):
            self.name = name
        
        def __repr__(self):
            return 'repr name={}'.format(self.name)
        
        def __str__(self):
            return 'str name={}'.format(self.name)
        
    print(A)
    
    
    # 三种方法找 __str__:
    print(A('tom'))  # str: 找str
    print(str(A('ben')))  # 同上;
    print('{}'.format(A('jerry')))
    
    print('-'*30)
    print(repr(A('tom')))  # 找repr;
    print(repr('{}'.format(A('jerry'))))  # str(str); 先求format(str),,
    #-----------------------------------------------------------------------------------------------------------------------------
    <class '__main__.A'>
    str name=tom
    str name=ben
    str name=jerry
    ------------------------------
    repr name=tom
    'str name=jerry'
    
    
    
    import json
    class A:
        def __init__(self,name):
            self.name = name
        
        def __repr__(self):
            return 'repr name={}'.format(self.name)
        
        def __str__(self):
            return 'str name={}'.format(self.name)
        
        def __bytes__(self):
            #return 'abc'.encode()
            #return self.name.encode()
            return json.dumps(self.__dict__).encode()
    a = A('tom')
    print([a, a])  # print 与实例对象a 隔了一层打印 repr;
    print(str({a,a}))  # str 与 a 隔了一层;
    print('{}'.format(*{a,a}))   # 解构不是 {},中间没有隔层;
    
    print(bytes(a))
    #------------------------------------------------------------------------------------------
    [repr name=tom, repr name=tom]
    {repr name=tom}
    str name=tom
    b'{"name": "tom"}'
    

    总结:

    1. 同时存在_str_ _repr_ ;直接作为str()函数、format()函数、print()函数参数调用时,调用_str_; 被间隔作为参数被调用时,调用_repr_参数;
    2. 只存在 _repr_ ;打印repr方法;只存在str,打印内存地址;都不存在,打印地址;
    3. print 打印不作数;数据类型需要判断,打印的不做数;注意不能通过判断是否带引号判断输出值的类型,类型判断要使用type或isinstance

    相关文章

      网友评论

          本文标题:30.3-魔术方法—bool和可视化

          本文链接:https://www.haomeiwen.com/subject/ogvfoctx.html