<jupyter_start><jupyter_text>魔术方法  `__slots__` 参考：* [使用__slots__ - 廖雪峰的官方网站](https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868200605560b1bd3c660bf494282ede59fee17e781000)* [python __slots__ 详解（上篇） - CSDN博客](https://blog.csdn.net/sxingming/article/details/52892640)* [Python__slots__详解 - rainfd - 博客园](https://www.cnblogs.com/rainfd/p/slots.html) 正常情况下，当我们定义了一个class，创建了一个class的实例后，我们可以给该实例绑定任何属性和方法，这就是动态语言的灵活性。定义类：<jupyter_code>class Person:
    pass<jupyter_output><empty_output><jupyter_text>绑定属性：<jupyter_code>p = Person()
p.name = 'Tom'
print(p.name)<jupyter_output>Tom<jupyter_text>但是对另外一个实例是不起作用的：<jupyter_code>q = Person()
try:
    print(q.name)
except AttributeError as e:
    print(e)<jupyter_output>'Person' object has no attribute 'name'<jupyter_text>但是如果我们想限制类的属性，不允许随便添加属性，可以使用`__slots__`类变量。<jupyter_code>class Person2:
    __slots__ = ('name', 'age')
    
p2 = Person2()
p2.name = 'Alan'
p2.age = 32
print(p2.name, p2.age, sep=' ')<jupyter_output>Alan 32<jupyter_text>由于weight没有被放到`__slots__`中，所以不能绑定weight属性，试图绑定weight将得到AttributeError的错误。<jupyter_code>try:
    p2.weight = 120
except AttributeError as e:
    print(e)<jupyter_output>'Person2' object has no attribute 'weight'<jupyter_text>使用__slots__要注意，__slots__定义的属性仅对当前类起作用，对继承的子类是不起作用的：<jupyter_code>class Student(Person2):
    pass

s = Student()
s.score = 100
print(s.score)<jupyter_output>100<jupyter_text>`__slots__`的另一个作用是阻止实例化类的时候分配`__dict__`，这样可以达到节省内存的目的。<jupyter_code>print(p.__dict__)
try:
    print(p2.__dict__)
except AttributeError as e:
    print(e)
%load_ext memory_profiler<jupyter_output><empty_output><jupyter_text>在类中不定义`__slots__`，分配10万个实例，使用约14MB内存。<jupyter_code>from slots_test import test
%mprun -f test test()<jupyter_output>Filename: F:\ABao\work\github\my.summary\python\slots_test.py

Line #    Mem usage    Increment   Line Contents
================================================
     9     73.3 MiB     73.3 MiB   @profile
    10                             def test():
    11     87.3 MiB     14.0 MiB       f = [A(523825) for i in range(100000)]<jupyter_text>在类中定义`__slots__`，分配10万个实例，使用约2MB内存。<jupyter_code>from slots_test2 import test2
%mprun -f test2 test2()<jupyter_output>Filename: F:\ABao\work\github\my.summary\python\slots_test2.py

Line #    Mem usage    Increment   Line Contents
================================================
    11     73.6 MiB     73.6 MiB   @profile
    12                             def test2():
    13     75.8 MiB      2.2 MiB       f = [A(523825) for i in range(100000)]
{'fraction_non_alphanumeric': 0.15146771037181997, 'fraction_numerical': 0.07045009784735812, 'mean_word_length': 5.100238663484487, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 30, 'https://': 3, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '344582', 'license': 'MIT', 'n_tokens_mistral': 1266, 'n_tokens_neox': 1207, 'n_words': 143, 'path': 'python/python_magic_method.ipynb', 'repo_name': 'icescut/my.summary', 'size': '2555'}