Python Slots To Dict
Next Chapter: Classes and Class Creation
Is there some way to tell a dictionary object that I am going to load 1M objects into it and have it pre-allocate enought slots to hold all of the entries? Not according to the manual. Not according to the source as at 2.4.3. In any case, if there were a back-door undocumented arg for the dict constructor, somebody would have.
Slots
- Python老鸟都应该看过那篇非常有吸引力的 Saving 9 GB of RAM with Python’s slots 文章,作者使用了slots让内存占用从25.5GB降到了16.2GB。在当时来说,这相当于用一个非常简单的方式就降低.
- Instead of having a dynamic dict that allows adding attributes to objects dynamically, slots provide a static structure which prohibits additions after the creation of an instance.
Slots in Python is a special mechanism that is used to reduce memory of the objects. In Python, all the objects use a dynamic dictionary for adding an attribute. Slots is a static type method in this no dynamic dictionary are required for allocating attribute. しかし! この dict は原則として使うべきではない機能です。理由は2つあります。 slots を定義しているクラスでは使えない; dict は内部情報に直接アクセスし、クラスのインターフェースを無視する; 1.の slots についてはこちらを参照下さい。.
Avoiding Dynamically Created Attributes
The attributes of objects are stored in a dictionary __dict__
. Like any other dictionary, a dictionary used for attribute storage doesn't have a fixed number of elements. In other words, you can add elements to dictionaries after they are defined, as we have seen in our chapter on dictionaries. This is the reason, why you can dynamically add attributes to objects of classes that we have created so far:
Python Get Dict Keys
The dictionary containing the attributes of 'a' can be accessed like this:
You might have wondered that you can dynamically add attributes to the classes, we have defined so far, but that you can't do this with built-in classes like 'int', or 'list':
Using a dictionary for attribute storage is very convenient, but it can mean a waste of space for objects, which have only a small amount of instance variables. The space consumption can become critical when creating large numbers of instances. Slots are a nice way to work around this space consumption problem. Instead of having a dynamic dict that allows adding attributes to objects dynamically, slots provide a static structure which prohibits additions after the creation of an instance.
When we design a class, we can use slots to prevent the dynamic creation of attributes. To define slots, you have to define a list with the name __slots__
. The list has to contain all the attributes, you want to use. We demonstrate this in the following class, in which the slots list contains only the name for an attribute 'val'.
If we start this program, we can see, that it is not possible to create dynamically a new attribute. We fail to create an attribute 'new'.
We mentioned in the beginning that slots are preventing a waste of space with objects. Since Python 3.3 this advantage is not as impressive any more. With Python 3.3 Key-Sharing Dictionaries are used for the storage of objects. The attributes of the instances are capable of sharing part of their internal storage between each other, i.e. the part which stores the keys and their corresponding hashes. This helps reducing the memory consumption of programs, which create many instances of non-builtin types.
Python String To Dict
Next Chapter: Classes and Class Creation
Python 3 Dict Methods
17 Nov 2013 by BenWe’ve mentioned before how Oyster.com’s Python-based web servers cache huge amounts of static content in huge Python dicts (hash tables). Well, we recently saved over 2 GB in each of four 6 GB server processes with a single line of code — using __slots__
on our Image
class.
Here’s a screenshot of RAM usage before and after deploying this change on one of our servers:
We allocate about a million instances of a class like the following:
By default Python uses a dict to store an object’s instance attributes. Which is usually fine, and it allows fully dynamic things like setting arbitrary new attributes at runtime.
However, for small classes that have a few fixed attributes known at “compile time”, the dict is a waste of RAM, and this makes a real difference when you’re creating a million of them. You can tell Python not to use a dict, and only allocate space for a fixed set of attributes, by settings __slots__
on the class to a fixed list of attribute names:
Note that you can also use collections.namedtuple, which allows attribute access, but only takes the space of a tuple, so it’s similar to using __slots__
on a class. However, to me it always feels weird to inherit from a namedtuple class. Also, if you want a custom initializer you have to override __new__
rather than __init__
.
Warning: Don’t prematurely optimize and use this everywhere! It’s not great for code maintenance, and it really only saves you when you have thousands of instances.