__slots__

发布时间 2024-01-07 01:37:30作者: lxd670

python类

类本质是一个字典(本质使用空间换时间)

class A:
    def __init__(self, x) -> None:
        self.x = x

a = A(1)
print(a.x)	# 1

# 添加y属性
a.y = 2
print(a.y) # 2
print(a.__dict__)

# 添加z属性
a.__dict__['z'] = 3
print(a.z)	# 3
print(a.__dict__)
1
2
{'x': 1, 'y': 2}
3
{'x': 1, 'y': 2, 'z': 3}

__slots__类属性

限制python类属性,使用__slots__, 以显著的节省内存

使用__slots__后,python中对象的属性不能通过 object.__dict__来查看

使用__slots__后,如果想要新增对象的属性,属性名称必须在指定的__slots__中, 否则会抛异常

__slots__案例

class A:
    __slots__ = ['x', 'y']
    def __init__(self, x) -> None:
        self.x = x

a = A(1)
print(a.x)

# 添加y属性
a.y = 2
print(a.y) # 2

# 添加z属性(不在__slots__中)
a.z = 3
1
2
Traceback (most recent call last):
  File "/Users/lxd670/code/python_code/asyncio_test/python类/private.py", line 14, in <module>
    a.z = 3
AttributeError: 'A' object has no attribute 'z'

无法使用__dict__查看类信息

class A:
    __slots__ = ['x', 'y']
    def __init__(self, x) -> None:
        self.x = x

a = A(1)
print(a.x)
print((a.__dict__))
1
Traceback (most recent call last):
  File "/Users/lxd670/code/python_code/asyncio_test/python类/private.py", line 8, in <module>
    print((a.__dict__))
AttributeError: 'A' object has no attribute '__dict__'. Did you mean: '__dir__'?

类定义__slots__前后变化

定义了类的__slots__属性后, 默认生成的类的__dict____weakref__属性没有自动生成。

定义了类的__slots__属性后, 类中新增了__slots__属性,并新增了__slots__属性中的成员(member)

class A:
    __slots__ = ['x', 'y']
    def __init__(self, x) -> None:
        self.x = x
class B:
    pass
print("A", A.__dict__)
print("B", B.__dict__)
A {
  '__module__': '__main__', 
  '__slots__': ['x', 'y'], 
  '__init__': <function A.__init__ at 0x1049e7490>, 
  'x': <member 'x' of 'A' objects>, 
  'y': <member 'y' of 'A' objects>, 
  '__doc__': None}
B {
  '__module__': '__main__', 
  '__dict__': <attribute '__dict__' of 'B' objects>, 
  '__weakref__': <attribute '__weakref__' of 'B' objects>, 
  '__doc__': None}

切记: 不要过早的使用__slots__, 只有当你的实例化对象达到数百万个的时候,才有必要使用__slots__进行优化。