一、__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