1.__getstate__
和__setstate__
__getstate__
和__setstate__
是 Python 中用于对象序列化和反序列化的特殊方法。这些方法通常与pickle
模块一起使用,以控制对象在序列化(保存)和反序列化(加载)过程中的行为。
1.1 __getstate__
- 作用:定义对象被序列化时的状态。
- 返回值:返回一个表示对象状态的字典或其他可序列化的对象。
- 默认行为:如果没有定义
__getstate__
,pickle 会自动使用对象的__dict__
属性作为状态。
1. 2 __setstate__
- 作用:定义对象从序列化状态恢复时的行为。
- 参数:接收一个表示对象状态的对象(通常是字典)。
- 默认行为:如果没有定义
__setstate__
,pickle 会自动将传入的状态赋值给对象的__dict__
属性。
import pickle
class Person:
def __init__(self, name, age, secret):
self.name = name
self.age = age
self.secret = secret # 希望在序列化时不保存这个属性
def __getstate__(self):
state = self.__dict__.copy()
del state['secret'] # 删除不希望序列化的属性
return state
def __setstate__(self, state):
state['secret'] = 'Unknown' # 在反序列化时设置默认值
self.__dict__.update(state)
# 创建一个 Person 对象
person = Person('Alice', 30, 'This is a secret')
# 序列化对象
serialized_person = pickle.dumps(person)
print("Serialized:", serialized_person)
# 反序列化对象
deserialized_person = pickle.loads(serialized_person)
print("Deserialized:", deserialized_person.name, deserialized_person.age, deserialized_person.secret)
2. __all__
属性
在 Python 中,
__all__
列表用于定义一个模块的公共接口。当一个模块被导入时,__all__
列表指定了哪些符号(变量、函数、类等)应该被视为模块的公开部分。然而,__all__
并不会限制其他文件对模块内容的访问,它只是提供了一种约定和建议。
2.1 具体表现
from module import *
语句:
当使用from module import *
时,只有__all__
列表中列出的符号会被导入到当前命名空间。
如果__all__
未定义,则默认导入模块中所有不以下划线开头的符号。- 直接导入:
使用import module
或from module import specific_symbol
不受__all__
的影响。
即使某个符号不在__all__
中,也可以通过module.symbol
的方式访问。
2.2 示例
# mymodule.py
__all__ = ['public_function', 'PublicClass']
def public_function():
print("This is a public function.")
def _private_function():
print("This is a private function.")
class PublicClass:
pass
class _PrivateClass:
pass
- 第一种引用方式
# main.py
from mymodule import *
public_function() # 正常工作
PublicClass() # 正常工作
_private_function() # 报错:NameError: name '_private_function' is not defined
_PrivateClass() # 报错:NameError: name '_PrivateClass' is not defined
- 第二种引用方式
# main.py
import mymodule
mymodule.public_function() # 正常工作
mymodule.PublicClass() # 正常工作
mymodule._private_function() # 正常工作
mymodule._PrivateClass() # 正常工作
2.3 总结
__all__
主要影响from module import *
语句的行为。- 直接导入模块或特定符号不受
__all__
的限制。 __all__
提供了一种约定,帮助用户了解模块的公共接口,但不是强制性的访问控制机制。
因此,即使定义了 __all__
列表,其他文件仍然可以通过模块名直接访问模块中的所有符号。