首页 > 其他分享 >(第八篇)__format__、__hash__、__init_subclass__、__reduce_ex__、__reduce__、__sizeof__、__setstate__、__getsta

(第八篇)__format__、__hash__、__init_subclass__、__reduce_ex__、__reduce__、__sizeof__、__setstate__、__getsta

时间:2023-04-10 12:22:08浏览次数:45  
标签:__ name format 对象 第八篇 self reduce age

一、__format__(self, format_spec)

当我们使用format()方法对一个对象进行格式化时,如果这个对象有__format__方法,那么这个方法就会被调用。它接受一个变量作为参数,并返回一个格式化后的字符串。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __format__(self, format_spec):
        if format_spec == "info":
            return f"{self.name}, {self.age} years old"
        else:
            return f"{self.name} ({self.age})"

person = Person("Alice", 25)
print("{:info}".format(person))  # Alice, 25 years old。冒号:表示分隔符,指格式化对象的info
print("{!s}".format(person))    # 强制调用__str__,打印对象自身,若自定义,则调用自定义的__str__,不会调用__format__方法

"""

在格式规范中,我们可以通过使用 : 分隔符来指定格式化选项。例如,我们可以使用 {:.2f} 来将一个浮点数保留两位小数并格式化为字符串。


另外,我们可以使用 ! 符号来指定类型转换,例如:


    • !s:调用对象的 __str__() 方法,将对象转换为字符串;
    • !r:调用对象的 __repr__() 方法,将对象转换为字符串,以表示对象的形式显示;
    • !a:调用对象的 __format__() 方法,将对象转换为 ASCII 码表示的字符串。
"{!s}".format(person) 会调用 person 对象的 __str__() 方法,将其转换为字符串后插入到占位符中。
"""

# 具体的format格式化冒号:中选项有很多,具体可以查阅资料。
例如{:8}将文本格式化为至少8个字符的宽度,如果输出不足8个字符,则使用空格进行填充

二、__hash__(self)

当我们使用hash()函数对一个对象进行哈希时,如果这个对象有__hash__方法,那么这个方法就会被调用。用于计算Python对象的哈希值。哈希值可以用于比较对象是否相等,并且可以被用作字典的键。

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __hash__(self):
        return hash((self.name, self.age))

person1 = Person("Alice", 25)
person2 = Person("Alice", 25)
person3 = Person("Ali", 25)

print(hash(person1))  # 7694926712467326889
print(hash(person2))  # 7694926712467326889  相同对象
print(hash(person3))  # 4723851031937723218

"""
哈希值是一种可用于快速比较对象的值,相同的对象应该有相同的哈希值。该方法应该返回一个整数(否则报错)。
"""

三、__init_subclass__(cls,**kwargs)

用于在子类创建时自动调用。当我们定义一个类时,如果这个类有__init_subclass__方法,那么这个方法就会在这个类的任何子类创建时自动调用。__init_subclass__方法可以用于在子类创建时做一些初始化操作。也可以用于为所有子类添加公共的属性或方法。cls参数是子类的类对象,kwargs参数是传递给子类创建时的关键字参数。

class Base:
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.name = kwargs.get("name", "Base")

class Child1(Base, name="Child1"):
    pass

class Child2(Base):
    pass

print(Child1.name)  # Child1
print(Child2.name)  # Base

四、__reduce_ex__(self, protocol)

用于自定义对象的序列化方式。当我们使用pickle模块将一个对象序列化时,如果这个对象有__reduce_ex__方法,那么这个方法就会被调用。__reduce_ex__方法需要返回一个元组,元组的第一个元素是一个可调用对象,用于反序列化对象,第二个元素是一个元组,包含了可调用对象的参数。protocol参数指定了序列化协议的版本号。

import pickle

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __reduce_ex__(self, protocol):
        return (self.__class__, (self.name, self.age))

person = Person("Alice", 25)
data = pickle.dumps(person)
new_person = pickle.loads(data)

print(new_person.name)  # Alice
print(new_person.age)   # 25

五、__reduce__(self)

__reduce_ex__方法类似,也是定义对象在使用pickle模块序列化时的行为,但不支持指定协议版本。


import pickle
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def __reduce__(self):
        return (Person, (self.name, self.age))
        
p = Person('Alice', 25)
b = pickle.dumps(p)   # 将p对象序列化为包含二进制的字节流:b'\x80\x04\x95%\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x06Person\x94\x93\x94\x8c\x05Alice\x94K\x19\x86\x94R\x94.'
new_p = pickle.loads(b)  # 要想查看数据,进行反序列化
print(new_p.name)   # Alice
print(new_p.age)    # 25

六、__sizeof__(self)

 用于返回对象所占用的内存大小。当我们使用sys.getsizeof()函数获取一个对象的大小时,如果这个对象有__sizeof__方法,那么这个方法就会被调用。__sizeof__方法需要返回一个整数,表示对象所占用的内存大小。
import sys

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __sizeof__(self):
        return sys.getsizeof(self.name) + sys.getsizeof(self.age)

person = Person('Alice', 25)
print(sys.getsizeof(person))  # 输出 64

"""
注意这里返回的值并不一定等于对象实际占用的内存大小,因为Python的内存管理机制比较复杂,涉及到了垃圾回收、内存对齐等问题。
"""

七、__setstate__、__getstate__

这两个方法只有在对象要被序列化或反序列化时才会被调用。

import pickle

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __getstate__(self):
        return {'x': self.x}
    
    def __setstate__(self, state):
        self.x = state['x']
        self.y = 0

# 序列化一个 MyClass 实例,调用__getstate__
obj = MyClass(1, 2)
data = pickle.dumps(obj)

# 反序列化该 MyClass 实例,调用__setstate__
new_obj = pickle.loads(data)
print(new_obj.x)  # 输出 1
print(new_obj.y)  # 输出 0

 

 

标签:__,name,format,对象,第八篇,self,reduce,age
From: https://www.cnblogs.com/hechengQAQ/p/17302542.html

相关文章

  • 「解题报告」P9169 [省选联考 2023] 过河卒
    挺套路的博弈论,实际上就是GameonGraph与GameonGraph,但是考场上多测没清空挂了。寄。并且不过ABC那个官方题解好像给的是\(O(m\logn)\)的做法,放这题是过不去的啦x首先显然三个棋子压状态大概是\(10^6\)级别的,多测\(T=10\),那么猜测是一个\(O(Tn^6)\)的做法。......
  • 用 Go 剑指 Offer 42. 连续子数组的最大和
    输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。 示例1:输入:nums=[-2,1,-3,4,-1,2,1,-5,4]输出:6解释: 连续子数组 [4,-1,2,1]的和最大,为 6。 提示:1<= arr.length<=10^5-100<=arr[i]<=100......
  • 禁用 DevTools 源映射功能, 隐藏 "DevTools failed to load SourceMap" 报错
    警告DevToolsfailedtoloadsourcemap:Couldnotloadcontentforchrome-extension://cofdbpoegempjloogbagkncekinflcnj/build/content.js.map:系统错误:net::ERR_BLOCKED_BY_CLIENT这个问题可能是因为浏览器的版本不同,所以设置的位置也会略有不同。以下是几个常见浏......
  • 画坦克
    大概结构图          接 ......
  • ls命令
    在linux系统中,使用ls命令按时间排序文件,其实很简单,如下:ls-altr即可按时间排序当前目录下的文件。lscommandsortbytime附,ls命令的参数中文详解:-a列出目录下的所有文件,包括以.开头的隐含文件。-b把文件名中不可输出的字符用反斜杠加字符编号(就象在C语言里一样)的形式列出......
  • Python异常处理模块——retrying
    https://zhuanlan.zhihu.com/p/420964250安装pipinstallretrying使用retrying提供一个装饰器函数retry,被装饰的函数会在运行失败的情况下重新执行,默认一直报错就一直重试。importrandomfromretryingimportretry@retrydefdo_something_unreliable():ifrand......
  • 只有一个人说了真话!通解代码——python
    不管几个人说了这话,代码逻辑都是一样的,无非参数不同。例大老鼠发现家里的奶酪少了一大块,审问四只小老鼠ABCD,其实只有一只老鼠偷吃了奶酪。A说:我没吃。B说:是C吃的。C说:肯定是D吃的。D说:C在冤枉我。己知四只小老鼠中有一只说的是真话,三只说的是假话。到底是谁偷吃了......
  • Python 小型项目大全 61~65
    六十一、ROT13密码原文:http://inventwithpython.com/bigbookpython/project61.htmlROT13密码是最简单的加密算法之一,代表“旋转13个空格”密码将字母A到Z表示为数字0到25,加密后的字母距离明文字母13个空格:A变成N,B变成O,以此类推。加密过程和解密过程是一样的,这使得......
  • OpenTiny 跨端、跨框架组件库升级TypeScript,10万行代码重获新生
    摘要:一份精心准备的《JS项目改造TS指南》文档供大家参考,顺便介绍TS基础知识和TS在Vue中的实践。本文分享自华为云社区《历史性的时刻!OpenTiny跨端、跨框架组件库正式升级TypeScript,10万行代码重获新生!》,作者:Kagol。根据TheSoftwareHouse发布的《2022前端开发市场状......
  • 第5章 使用路由将URL映射到Razor Pages(ASP.NET Core in Action, 2nd Edition)
    本章包括(请点击这里阅读其他章节)将URL映射到Razor页面使用约束和默认值匹配URL从路由参数生成URL在第4章中,您了解了MVC设计模式,以及ASP.NETCore如何使用它为使用RazorPages的应用程序生成UI。RazorPages包含类似小型控制器的页面处理程序。页面处理程序......