__slots__

1.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}

2.__slots__类属性

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

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

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

2.1__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'

2.2无法使用__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__'?

2.3类定义__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}

2.4__slots__继承

python只会关注各个类的__slots__,继承父类的__slots__是不会在子类中生效的。

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

class B(A):
    pass

b = B(1, 2)
print(b.x)
print(b.y)

b.z = 1

print(b.__dict__)
print(b.__slots__)
1
2
{'z': 1}
['x', 'y']

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

posted @ 2024-01-07 01:34  lxd670  阅读(2)  评论(0编辑  收藏  举报