[PYTHON] To make a dict type property read-only

If the created class has a property of type dict, and you do not want to change the property element without permission, we will explain how to prevent the property element from being changed using MappingProxyType.

For example, assume the following code.

python


class Foo:
    
    def __init__(self):
        self._bar = {'a': 1, 'b': 2}

    @property
    def bar(self):
        return self._bar

    def add_item(self, key, value):
    #I want the user to add the element only through this method
        self._bar[key] = value

In this code, the Foo class property bar does not have a setter defined, so the user cannot change bar to another object. Attempting to set a different value for bar will result in an error, as follows:

python


>>> foo = Foo()
>>> foo.bar
{'b': 2, 'a': 1}
>>> foo.bar = 1
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    foo.bar = 1
AttributeError: can't set attribute

However, since foo.bar itself is a dict, you can add elements.

python


>>> foo.bar['c'] = 3
>>> foo.bar
{'b': 2, 'a': 1, 'c': 3}

In order to prevent unintentional changes of the creator of such a class, there is a way to use the MappingProxyType type of the types library in Python Ver 3.3 or later. If you use the MappingProxyType constructor and return the returned dictionary as a mapping proxy object, the user will not be able to modify the returned object. If you change the sample earlier, it will look like this.

python


from types import MappingProxyType

class Foo:
    
    def __init__(self):
        self._bar = {'a': 1, 'b': 2}

    @property
    def bar(self):
        return MappingProxyType(self._bar)

    def add_item(self, key, value):
        self._bar[key] = value

If the user tries to add an element to bar as follows, an error will occur.

python


>>> foo = Foo()
>>> foo.bar
mappingproxy({'a': 1, 'b': 2})
>>> foo.bar['c'] = 3 #Attempting to add an element will result in an error.
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    foo.bar['c'] = 3
TypeError: 'mappingproxy' object does not support item assignment
>>> foo.add_item('c', 3) #The user adds an element using a method.
>>> foo.bar
mappingproxy({'a': 1, 'c': 3, 'b': 2})

mappingproxy can be used as a read-only dictionary because you can get elements in the same way as dict.

Recommended Posts

To make a dict type property read-only
How to make a Japanese-English translation
How to make a slack bot
How to make a crawler --Advanced
How to make a recursive function
python / Make a dict from a list.
How to make a deadman's switch
[Blender] How to make a Blender plugin
How to make a crawler --Basic
[Python] How to make a class iterable
I tried to make a Web API
How to make a Backtrader custom indicator
How to make a Pelican site map
How to make a dialogue system dedicated to beginners
A memorandum to make WebDAV only with nginx
Would you like to make a Twitter resume?
How to make a dictionary with a hierarchical structure.
I want to make a game with Python
Try to make a "cryptanalysis" cipher with Python
How to make a QGIS plugin (package generation)
I want to create a plug-in type implementation
I read "How to make a hacking lab"
Try to make a dihedral group with Python
I tried to make a ○ ✕ game using TensorFlow
Lark Basics (Python, Lark to make a shell-like guy)
I tried to make a "fucking big literary converter"
Try to make a Python module in C language
Try to make a command standby tool with python
How to make a shooting game with toio (Part 1)
How to write a list / dictionary type of Python3
Make a function to describe Japanese fonts with OpenCV
How to make a Python package using VS Code
[Python] I want to make a nested list a tuple
Machine learning beginners try to make a decision tree
Basics of PyTorch (2) -How to make a neural network-
Convert Webpay Entity type to Dict type (recursively in Python)
Make a function decorator
Use a Property Decorator?
Make a distance matrix
dict in dict Makes a dict a dict
Convert dict to array
I'll make a password!
Make a Nyan button
Make a Tetris-style game!
Make a Base64 decoder
How to make a Cisco Webex Teams BOT with Flask
[Python] How to make a list of character strings character by character
How to make a multiplayer online action game on Slack
I want to make a blog editor with django admin
How to make a hacking lab-Kali Linux (2020.1) VirtualBox 64-bit Part 2-
Experiment to make a self-catering PDF for Kindle with Python
I want to make a click macro with pyautogui (desire)
How to make a hacking lab-Kali Linux (2020.1) VirtualBox 64-bit edition-
Put the lists together in pandas to make a DataFrame
How to make a simple Flappy Bird game with pygame
I want to make a click macro with pyautogui (outlook)
I tried to make a stopwatch using tkinter in python
[Introduction to Tensorflow] Understand Tensorflow properly and try to make a model
I want to make input () a nice complement in python
I tried to make a simple text editor using PyQt