• 1.2 如何使用特殊方法


    如何使用特殊方法:

    首先明确一点,特殊方法的存在是为了被 Python 解释器调用的,你自己并不需要调用它们。也就是说没有 my_object.__len__() 这种写法, 而应该使用 len(my_object)。在执行 len(my_object) 的时候,如果 my_object 是一个自定义类的对象,那么 Python 会自己去调用其中由你实现的 __len__ 方法。 

    然而如果是 Python 内置的类型,比如列表(list)、字符串(str)、 字节序列(bytearray)等,那么 CPython 会抄个近路,__len__ 实际 上会直接返回 PyVarObject 里的 ob_size 属性。PyVarObject 是表示内存中长度可变的内置对象的 C 语言结构体。直接读取这个值比调用一个方法要快很多。

    背后的原因是 CPython 会直 接从一个 C 结构体里读取对象的长度,完全不会调用任何方法。获取一个集合中元素的数量是一个很常见的操作,在 str、list、memoryview 等类型上,这个操作必须高效。 

    很多时候,特殊方法的调用是隐式的,比如 for i in x: 这个语句, 背后其实用的是 iter(x),而这个函数的背后则是 x.__iter__() 方 法。当然前提是这个方法在 x 中被实现了。

    通过内置的函数(例如 len、iter、str,等等)来使用特殊方法是最 好的选择。这些内置函数不仅会调用特殊方法,通常还提供额外的好 处,而且对于内置的类来说,它们的速度更快。

    不要自己想当然地随意添加特殊方法,比如 __foo__ 之类的,因为虽然现在这个名字没有被 Python 内部使用,以后就不一定了。 

    字符串表示形式:

    Python 有一个内置的函数叫 repr,它能把一个对象用字符串的形式表 达出来以便辨认,这就是“字符串表示形式”。repr 就是通过 __repr__ 这个特殊方法来得到一个对象的字符串表示形式的。如果没有实现 __repr__,当我们在控制台里打印一个向量的实例时,得到的字符串可能会是 <Vector object at 0x10e100070>。 交互式控制台和调试程序(debugger)用 repr 函数来获取字符串表示形式;在老的使用 % 符号的字符串格式中,这个函数返回的结果用来代替 %r 所代表的对象;同样,str.format 函数所用到的新式字符串格式化语法也是利用了 repr,才把 !r 字段变成字符串。

    __repr__ 和 __str__ 的区别在于,后者是在 str() 函数被使用,或 是在用 print 函数打印一个对象的时候才被调用的,并且它返回的字符串对终端用户更友好。

    如果你只想实现这两个特殊方法中的一个,__repr__ 是更好的选择, 因为如果一个对象没有 __str__ 函数,而 Python 又需要调用它的时候,解释器会用 __repr__ 作为替代。

    自定义的布尔值:

    尽管 Python 里有 bool 类型,但实际上任何对象都可以用于需要布尔值 的上下文中(比如 if 或 while 语句,或者 and、or 和 not 运算 符)。为了判定一个值 x 为真还是为假,Python 会调用 bool(x),这个 函数只能返回 True 或者 False。
    默认情况下,我们自己定义的类的实例总被认为是真的,除非这个类对 __bool__ 或者 __len__ 函数有自己的实现。bool(x) 的背后是调用 x.__bool__() 的结果;如果不存在 __bool__ 方法,那么 bool(x) 会 尝试调用 x.__len__()。若返回 0,则 bool 会返回 False;否则返回 True

  • 相关阅读:
    看过设计模式第一章的心得
    支付宝支付过程填坑
    C# 合并只要有交集的所有集合
    C#中的反射 Reflection
    动态更改配置文件
    六种弹窗
    Respone弹窗
    Aspose是一个很强大的控件,可以用来操作word,excel,ppt等文件
    使用ECharts报表统计公司考勤加班,大家加班多吗?
    排污许可管理条例-中华人民共和国国务院令第736号
  • 原文地址:https://www.cnblogs.com/wjw2018/p/10624199.html
Copyright © 2020-2023  润新知