<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Raven Note</title><description>Right here, may you find the knowledge you need</description><link>https://blog.ravenote.me/</link><language>en</language><item><title>Setting up Tailscale and configuring HTTPS on Synology NAS: A practical guide</title><link>https://blog.ravenote.me/en/posts/synology_tailscale_and_https/</link><guid isPermaLink="true">https://blog.ravenote.me/en/posts/synology_tailscale_and_https/</guid><description>Building secure remote access to Synology NAS with Tailscale, compatible with DSM 7.x</description><pubDate>Wed, 31 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;To enhance Synology NAS security (especially EOL models), and enable remote access without a public IP address, Tailscale can be used to build a secure private network.&lt;/p&gt;
&lt;section&gt;&lt;h2 id=&quot;setting-up-tailscale&quot;&gt;Setting up Tailscale&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/synology_tailscale_and_https/#setting-up-tailscale&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For Synology NAS models outside the mainland China market, Tailscale is available directly through Package Center. Otherwise, download the appropriate SPK package for your DSM version and CPU architecture from &lt;a href=&quot;https://pkgs.tailscale.com/stable/#spks&quot;&gt;Tailscale Packages&lt;/a&gt;, and then manually install it in Package Center (if you’re unsure about the architecture, check &lt;a href=&quot;https://github.com/SynoCommunity/spksrc/wiki/Synology-and-SynoCommunity-Package-Architectures&quot;&gt;Synology and SynoCommunity Package Architectures&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;You can automate updates with a scheduled task. In DSM, open Control Panel, find Scheduled Task, and create a new scheduled task with a user-defined script. Set the running user to root, schedule it to run once a month, and use the following script:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:22ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;tailscale&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;update&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--yes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote class=&quot;admonition bdm-note&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;NOTE&lt;/span&gt;&lt;p&gt;Per the official recommendation, Tailscale should be kept up to date automatically via a scheduled task even when installed through Package Center&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;On DSM 7, stricter restrictions on package behavior mean Tailscale doesn’t have permission to create TUN devices, so by default external devices can connect to the NAS, but applications running on the NAS itself cannot initiate network connections through Tailscale. If you need that, open Control Panel in DSM, find Scheduled Task, create a new triggered task, select Boot as the event, set the user to root, and use the following script:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:107ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;/var/packages/Tailscale/target/bin/tailscale&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;configure-host&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;synosystemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;restart&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;pkgctl-Tailscale.service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Make sure you’re running Tailscale v1.22.2 or later&lt;/p&gt;&lt;p&gt;You’ll need to run the command above again after upgrading the Tailscale package&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;setting-up-https-and-automating-it&quot;&gt;Setting up HTTPS and automating it&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/synology_tailscale_and_https/#setting-up-https-and-automating-it&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Open the Tailscale admin console, go to the DNS tab, find HTTPS Certificates, and click Enable HTTPS.&lt;/p&gt;&lt;p&gt;Make sure MagicDNS is enabled before turning this on&lt;/p&gt;&lt;p&gt;Once enabled, machine names and Tailnet DNS names become publicly visible (this doesn’t affect security)&lt;/p&gt;&lt;p&gt;Next, open Control Panel in DSM, go to Terminal &amp;amp; SNMP, and enable SSH.&lt;/p&gt;&lt;p&gt;Once connected to the NAS over SSH, switch to the root account (a small shortcut) and run:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:28ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;tailscale&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;cert&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [Your &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Domain]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This command generates two files. Find a way to get them onto your computer (there are plenty of options — e.g., move them to a shared folder and download them via File Station, or use SCP).&lt;/p&gt;&lt;p&gt;Then open Control Panel in DSM, go to Security, switch to the Certificate tab, click New, and follow the wizard to import the certificate. Set the description to &lt;code&gt;Tailscale&lt;/code&gt; and leave the intermediate certificate blank.&lt;/p&gt;&lt;p&gt;Make sure the description is exactly &lt;code&gt;Tailscale&lt;/code&gt; — otherwise the automation script won’t be able to locate the certificate path later.&lt;/p&gt;&lt;p&gt;The automation script has only been tested on DSM 7. Before relying on it, verify that the &lt;code&gt;jq&lt;/code&gt; command resolves correctly when run as root. If it doesn’t, adjust the jq query based on the structure of &lt;code&gt;/usr/syno/etc/certificate/_archive/INFO&lt;/code&gt;, or pin down the fixed certificate directory by comparing sha256 hashes (you can quickly list the sha256 of every cert.pem — i.e., the sha256 of the crt files — with &lt;code&gt;find /usr/syno/etc/certificate/_archive -type f -name cert.pem -exec sha256sum {} \;&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;If you modify the script to use a fixed directory, be aware that the path changes whenever you delete and re-import the certificate — remember to update it then.&lt;/p&gt;&lt;p&gt;Once the import is done, don’t forget to go to Settings and switch the certificates used by the relevant services to the Tailscale certificate you just imported. HTTPS is actually fully configured at this point — but every time the certificate expires, you’d have to repeat the whole process manually, which is a pain, especially since certificate validity is being shortened to 45 days starting in 2028.&lt;/p&gt;&lt;p&gt;Write the following script, remembering to replace &lt;code&gt;[Your Domain]&lt;/code&gt; with your full Tailscale domain:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:133ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;DOMAIN&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;[Your Domain]&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_DIR&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;jq&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-r&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--arg&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Tailscale&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;to_entries[] | select(.value.desc == $desc) | .key&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/usr/syno/etc/certificate/_archive/INFO&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;/usr/syno/etc/certificate/_archive/${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_DIR&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [ &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-f&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/cert.pem&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ]; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;then&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;EXPIRY_DATE&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;openssl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;x509&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-enddate&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-noout&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/cert.pem&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;cut&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-f2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;EXPIRY_EPOCH&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;date&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;EXPIRY_DATE&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;+%s&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CURRENT_EPOCH&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;date&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;+%s&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;DAYS_REMAINING&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$(( (&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;EXPIRY_EPOCH&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;CURRENT_EPOCH&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;86400&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;else&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;exit&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;fi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [ ${DAYS_REMAINING} &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-gt&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;14&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ]; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;then&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;exit&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;fi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;tailscale&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;cert&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;DOMAIN&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [ &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-f&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;DOMAIN&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}.crt&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ]; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;then&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;exit&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;fi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;cp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;DOMAIN&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}.crt&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/cert.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;mv&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;DOMAIN&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}.key&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/privkey.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;mv&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;DOMAIN&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}.crt&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/fullchain.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;chmod&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/cert.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;chmod&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/privkey.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;chmod&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/fullchain.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;chown&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;root:root&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/cert.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;chown&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;root:root&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/privkey.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;chown&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;root:root&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;${&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;CERT_ARCHIVE_PATH&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}/fullchain.pem&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;synosystemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;restart&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;nginx&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Save the content above as &lt;code&gt;refresh_tailscale_cert.sh&lt;/code&gt; and place it in any shared folder. Then open Control Panel in DSM, find Scheduled Task, and create a new scheduled task with a user-defined script. Set the running user to root, schedule it to run weekly, and use the following script:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:38ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/[Your&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Volume]/[Your&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Shared&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Folder]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;bash&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;refresh_tailscale_cert.sh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If you’re not sure what &lt;code&gt;/[Your Volume]/[Your Shared Folder]&lt;/code&gt; should be, right-click your script in DSM and check its properties.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;references&quot;&gt;References&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/synology_tailscale_and_https/#references&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.xfelix.com/2020/04/issue-synology-lets-encrypt-cert-by-acme-sh-docker/&quot;&gt;Issue Synology Let’s Encrypt Cert by acme.sh docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;</content:encoded></item><item><title>Python from Beginner to Advanced: Classes, Objects, and Object-Oriented Programming</title><link>https://blog.ravenote.me/en/posts/python_classes_and_oop/</link><guid isPermaLink="true">https://blog.ravenote.me/en/posts/python_classes_and_oop/</guid><description>An introduction to classes and objects in Python and the core concepts of object-oriented programming</description><pubDate>Wed, 18 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h2 id=&quot;oop-a-prologue&quot;&gt;OOP: A Prologue&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#oop-a-prologue&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When requirements grow complex, programming purely in a procedural style starts to hurt code readability and maintainability. Suppose you’re developing a library management program. At first, you might record book information in the most straightforward way possible:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:35ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book1_title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Python Crash Course&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book1_author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Eric Matthes&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book1_isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-7115613639&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book1_stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book2_title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book2_author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book2_isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book2_stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Before long you realize that every new book means redefining a whole pile of variables. Then a lightbulb goes off: pull each book’s data out and store it in a list:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:65ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;books &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Python Crash Course&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Eric Matthes&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-7115613639&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;But now every lookup relies on indexes like &lt;code&gt;books[0][0]&lt;/code&gt; or &lt;code&gt;books[2][3]&lt;/code&gt;, which is hardly intuitive — read this code in isolation and you have no idea what those indexes refer to. Luckily, you remember that Python has something called a dictionary:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:39ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;books &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Python Crash Course&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Eric Matthes&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;isbn&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-7115613639&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;stock&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;isbn&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;stock&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;OK, that feels good enough, so you start writing the features:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:95ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;borrow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(book: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;stock&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;stock&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&apos;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;title&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos; borrowed successfully! Remaining stock: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;stock&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Insufficient stock!&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;show_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(book: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot; by &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; (ISBN: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;isbn&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;), stock: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;stock&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;find_book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(isbn: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; book &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; books:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; book[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;isbn&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; book&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;book &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; find_book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; book:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;show_info(book)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;borrow(book)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Book not found!&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Not bad — you’ve taken your first step. But a mature library management system doesn’t just manage books. It also has to record who borrowed which book, track each book’s loan history including borrow and return dates, calculate fines for overdue books, and support queries about any user’s borrowing status. If you keep going procedural, you’ll find yourself adding a user dict that nests a list of dicts for borrowed books, while each book dict nests a list of who borrowed it plus a loan history. Your code ends up crammed with loops, conditionals, and nested lookups — touch one thing and everything else moves. The code runs, sure, but readability and maintainability take a serious hit.&lt;/p&gt;&lt;p&gt;At this point you might be thinking: wouldn’t it be nice to bundle data and its related operations together? That’s exactly when classes step onto the stage.&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;conventions&quot;&gt;Conventions&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#conventions&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;This article targets Python 3.12; any feature introduced after Python 3.12 will be explicitly noted.&lt;/li&gt;
&lt;li&gt;For freshness, every reference is labeled with its year.&lt;/li&gt;
&lt;li&gt;For freshness, any reference older than two years must be verified by hands-on testing.&lt;/li&gt;
&lt;li&gt;Code blocks default to the contents of &lt;code&gt;main.py&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Comments starting with &lt;code&gt;Output:&lt;/code&gt; show what that line prints.&lt;/li&gt;
&lt;li&gt;Comments starting with &lt;code&gt;Raise:&lt;/code&gt; show the exception that line will raise.&lt;/li&gt;
&lt;li&gt;This article assumes you’re already comfortable with basic procedural Python.&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;basic-concepts&quot;&gt;Basic Concepts&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#basic-concepts&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In case you haven’t come across these concepts yet, let’s briefly go over some fundamentals before we start.&lt;/p&gt;&lt;section&gt;&lt;h3 id=&quot;magic-methods&quot;&gt;Magic Methods&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#magic-methods&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Every method surrounded by double underscores is a magic method, the most common being &lt;code&gt;__init__()&lt;/code&gt;. We won’t dig into magic methods here — that comes in later chapters. One thing to keep in mind: never define your own methods with names that start and end with double underscores. They may not have a special meaning today, but there’s no guarantee that will stay true.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;decorators&quot;&gt;Decorators&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#decorators&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This is also covered in a later chapter. In short, a decorator modifies the behavior of a function or method, and it’s usually written as &lt;code&gt;@xxxx&lt;/code&gt;.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;namespaces&quot;&gt;Namespaces&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#namespaces&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Say you’re looking for a friend named Zhang Wei — but there are 294,282 people named Zhang Wei in the country (2019). How do you know which Zhang Wei you mean? You need more than just the name: which city they live in, which company they work for, and so on.&lt;/p&gt;&lt;p&gt;Similarly, if methods or variables with the same name are defined in multiple places, the Python interpreter can’t tell which one you mean. That’s where the concept of namespaces comes in. A namespace groups names: the same name in different namespaces points to different objects. When you write code, you just prefix the method or variable name with its module name, and the interpreter knows exactly which one to call.&lt;/p&gt;&lt;p&gt;Here’s an example from computer systems: a folder (directory) can contain many folders. Within a single folder, no two files can share the same name, but files in different folders can have the same name.&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_1&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;544&quot; height=&quot;372&quot; src=&quot;https://blog.ravenote.me/_astro/1.B7C5sKXV_2r1Vge.webp&quot; /&gt;
(Image source: Runoob Tutorial)&lt;/p&gt;&lt;p&gt;Here’s a code example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame has-title&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;module1.py&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:26ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;from module 1&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame has-title&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;module2.py&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:26ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;from module 2&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame has-title&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;main.py&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:46ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; module1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; module2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(module1.echo())  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: from module 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(module2.echo())  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: from module 2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;In Python, the &lt;code&gt;.&lt;/code&gt; operator accesses an object’s attributes and methods. For instance, in &lt;code&gt;module1.echo()&lt;/code&gt;, &lt;code&gt;module1&lt;/code&gt; is a module object and &lt;code&gt;echo&lt;/code&gt; is one of its methods, invoked via &lt;code&gt;.&lt;/code&gt;. With &lt;code&gt;module1.echo()&lt;/code&gt; and &lt;code&gt;module2.echo()&lt;/code&gt;, we’ve explicitly told the interpreter which module’s method to call.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;scope-and-closures&quot;&gt;Scope and Closures&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#scope-and-closures&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Now let’s talk about scope in Python. As the name suggests, scope is the region where a name is effective — in other words, “where this name can be used”. Python’s scoping follows the LEGB rule, which looks up a variable in this order:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Local&lt;/strong&gt;: the local scope of the current function.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enclosing&lt;/strong&gt;: the scope of the enclosing function that contains the current one (if nested functions are involved).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Global&lt;/strong&gt;: the current module’s global scope.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Builtin&lt;/strong&gt;: Python’s built-in scope.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;The diagram below makes it more intuitive:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_2&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;317&quot; height=&quot;219&quot; src=&quot;https://blog.ravenote.me/_astro/2.UmO2AY6U_Z1OTQWz.webp&quot; /&gt;
(Image source: Runoob Tutorial)&lt;/p&gt;&lt;p&gt;Lookup proceeds one level at a time from the innermost scope outward, and an inner variable with the same name shadows the outer one. For example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:35ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;global variable&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;local variable&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;main()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: local variable&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: global variable&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Every time a function is called, it creates its own local scope. Arguments passed in are copied into the function’s parameters, which are only accessible inside the function’s local scope. Once the function finishes, its local variables are released from memory by the garbage collector:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:57ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(a, b):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Inside the function: a = &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; a &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; b&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result1 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; add(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Inside the function: a = 2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result2 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; add(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Inside the function: a = 5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(a)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: NameError: name &apos;a&apos; is not defined&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;So you could say scope has a kind of “enclosure”. You may have already realized that namespaces are an abstraction of scopes: they exploit scope’s ability to “seal names inside” in order to achieve grouping.&lt;/p&gt;&lt;p&gt;When you define a function inside another function, the inner function belongs to the outer function’s local scope:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:57ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;outer&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Outer function executed&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;inner&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Inner function executed&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;inner()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;outer()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;inner()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: NameError: name &apos;inner&apos; is not defined.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Calling it from inside the outer function’s local scope works fine, but trying to call it from the global scope raises a &lt;code&gt;NameError&lt;/code&gt;, because &lt;code&gt;inner&lt;/code&gt; isn’t defined there.&lt;/p&gt;&lt;p&gt;However, there is a way to access the function from outside its local scope: return the inner function object instead of calling it, and assign the returned function to a variable:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:47ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;outer&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;inner&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Inner function called&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; inner&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; outer()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func())   &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Inner function called&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;outer&lt;/code&gt; function has already finished running, so its local scope should have been destroyed — why does &lt;code&gt;inner&lt;/code&gt; still work? Because the Python interpreter keeps any object in memory as long as there’s still a reference to it.&lt;/p&gt;&lt;p&gt;What if the inner function references a variable from the outer function’s scope? Here’s an example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:39ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;power&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(exponent):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;inner&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(base):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; base &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; exponent&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; inner&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;power_of_two &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; power(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;power_of_three &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; power(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(power_of_two(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;))  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 25&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(power_of_three(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;))  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 125&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Theoretically, when &lt;code&gt;power&lt;/code&gt; finishes executing, its local scope — including local variables like &lt;code&gt;exponent&lt;/code&gt; — should be gone. But at runtime, &lt;code&gt;power_of_two&lt;/code&gt; still accesses &lt;code&gt;exponent&lt;/code&gt; and gets the right answer. That’s because Python handles this case specially. Variables defined in an enclosing scope rather than the function’s own local scope are called non-local variables. When an inner function references variables from an outer function, Python stores those free variables (variables used inside a function but not defined there) in a special attribute, &lt;code&gt;__closure__&lt;/code&gt;. Such variables — &lt;code&gt;exponent&lt;/code&gt; in this example — are called non-local free variables. That way they stay in memory even after the enclosing function’s local scope is destroyed. A function that carries its defining environment around with it like this is called a closure.&lt;/p&gt;&lt;p&gt;Even though a closure can read non-local variables, trying to assign to one directly just creates a local variable — it won’t modify the non-local one. That’s where &lt;code&gt;nonlocal&lt;/code&gt; comes in. It tells the interpreter that a variable refers to a name already bound in the nearest enclosing scope, rather than creating a new local variable:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:116ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;nonlocal&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: UnboundLocalError: cannot access local variable &apos;x&apos; where it is not associated with a value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;a()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;b()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;main()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;You might wonder why &lt;code&gt;x += 3&lt;/code&gt; raises &lt;code&gt;UnboundLocalError&lt;/code&gt;. Because &lt;code&gt;x += 3&lt;/code&gt; is equivalent to &lt;code&gt;x = x + 3&lt;/code&gt;; Python first needs to read the value of &lt;code&gt;x&lt;/code&gt; to do the addition, but since direct assignment only creates a local variable, &lt;code&gt;x&lt;/code&gt; is marked as local — and a local &lt;code&gt;x&lt;/code&gt; was never assigned, so the interpreter raises &lt;code&gt;UnboundLocalError&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Of course, if you don’t rebind the variable (for example, you only mutate a mutable object), you can use it directly:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:27ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x.append(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: []&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;a()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: [1]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;main()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If you want to modify a global-scope variable instead, use &lt;code&gt;global&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:21ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;global&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;a()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;a-first-look-at-classes-and-objects&quot;&gt;A First Look at Classes and Objects&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#a-first-look-at-classes-and-objects&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;At the heart of object-oriented programming is abstraction — distilling things from the real world into objects, and using objects as the basic unit that encapsulates data and behavior to build programs.&lt;/p&gt;&lt;p&gt;Think about how you interact with everyday objects. You watch TV using the remote for power, volume, and channels — you never need to understand how the circuits inside work. OOP works the same way: related data and the methods that operate on that data are packaged together into a class. Callers only need to know what interfaces are available; they don’t care about the implementation details.&lt;/p&gt;&lt;p&gt;We use classes to create objects — this is called instantiation, and the objects produced are called instances of the class. Many languages describe classes as blueprints. In Python, though, a class is less like a blueprint and more like a factory, with instances as the products rolling off the line. Normally — unless you have a specific reason to do otherwise — you work with the products (instances), not the factory (class) itself.&lt;/p&gt;&lt;p&gt;In Python, the &lt;code&gt;class&lt;/code&gt; keyword defines a class. For instance, let’s define a &lt;code&gt;Book&lt;/code&gt; class:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:11ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;To instantiate it, just call it:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:16ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_book &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This creates a new instance of &lt;code&gt;Book&lt;/code&gt; and assigns it to the local variable &lt;code&gt;my_book&lt;/code&gt;. You can use the magic attribute &lt;code&gt;__class__&lt;/code&gt; to find out which class an instance belongs to, and the magic attribute &lt;code&gt;__name__&lt;/code&gt; to get the class’s name.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:53ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;__main__.Book&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__name__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Book&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;A factory that produces nothing isn’t much use — we want products with real information. For instance, every book should have its own title, author, and ISBN:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:86ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;python_crash_course &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Python Crash Course&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Eric Matthes&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-7115613639&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(python_crash_course.title)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Python Crash Course&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(fluent_python.title)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Fluent Python&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;__init__()&lt;/code&gt; is a magic method that’s called automatically when a new instance is created, saving you from calling it manually.&lt;/p&gt;&lt;p&gt;Every instance has its own independent copy of the data. &lt;code&gt;python_crash_course&lt;/code&gt;’s &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;fluent_python&lt;/code&gt;’s &lt;code&gt;title&lt;/code&gt; don’t affect each other. Attributes bound to a specific instance are called instance attributes. Usually you can inspect all the attributes of an instance created from a custom class via &lt;code&gt;__dict__&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:143ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(python_crash_course.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__dict__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: {&apos;title&apos;: &apos;Python Crash Course&apos;, &apos;author&apos;: &apos;Eric Matthes&apos;, &apos;isbn&apos;: &apos;978-7115613639&apos;, &apos;stock&apos;: 5}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(fluent_python.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__dict__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: {&apos;title&apos;: &apos;Fluent Python&apos;, &apos;author&apos;: &apos;Luciano Ramalho&apos;, &apos;isbn&apos;: &apos;978-1492056355&apos;, &apos;stock&apos;: 3}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Functions defined in a class are called methods. A method that needs to access or modify the instance’s own attributes should be an instance method. The first parameter of an instance method must receive the instance object itself; by convention, this parameter is named &lt;code&gt;self&lt;/code&gt;. Let’s add a method to &lt;code&gt;Book&lt;/code&gt; that displays book information:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:115ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;get_book_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot; by &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; (ISBN: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;), stock: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(fluent_python.get_book_info())  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &quot;Fluent Python&quot; by Luciano Ramalho (ISBN: 978-1492056355), stock: 3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Sometimes an attribute or behavior belongs to the whole class rather than to any particular instance. For example, a library needs to know how many distinct titles it holds. That information doesn’t belong to any single book — it belongs to the &lt;code&gt;Book&lt;/code&gt; class as a whole. Attributes shared by all instances are called class attributes.&lt;/p&gt;&lt;p&gt;Correspondingly, a method that operates on class attributes rather than instance attributes is usually defined as a class method. Class methods are marked with the &lt;code&gt;@classmethod&lt;/code&gt; decorator, and their first parameter must receive the class object itself; by convention, this parameter is named &lt;code&gt;cls&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:109ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;_all_isbns &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._add_isbn(isbn)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;get_book_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot; by &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;, stock: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;classmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;get_store_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to the library! We currently hold &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._all_isbns)&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; distinct titles.&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;classmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;_add_isbn&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, isbn: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._all_isbns.add(isbn)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;python_crash_course &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Python Crash Course&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Eric Matthes&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-7115613639&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(Book.get_store_info())  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Welcome to the library! We currently hold 2 distinct titles.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(fluent_python.get_store_info())  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Welcome to the library! We currently hold 2 distinct titles.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Class methods can be called directly on the class. Calling them through an instance also works and produces the same result, but it’s not recommended.&lt;/p&gt;&lt;p&gt;&lt;code&gt;self&lt;/code&gt; and &lt;code&gt;cls&lt;/code&gt; are just conventions — what matters is that they occupy the first parameter position. As long as they come first, the name doesn’t affect whether the code runs. You could even swap &lt;code&gt;self&lt;/code&gt; and &lt;code&gt;cls&lt;/code&gt; on a whim:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:99ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;_all_isbns &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._add_isbn(isbn)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;classmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;get_store_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to the library! We currently hold &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._all_isbns)&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; distinct titles.&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;classmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;_add_isbn&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, isbn: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._all_isbns.add(isbn)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;get_book_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot; by &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; (ISBN: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;), stock: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;It would run, sure — but if anyone else ever takes over the project, you’d better hope you can run even faster. That’s the whole point of conventions: the next person to touch the code shouldn’t have to pause and puzzle out what each parameter is for.&lt;/p&gt;&lt;p&gt;When a method needs neither instance attributes nor class attributes but is still functionally tied to the class, use a static method. For example, let’s add a method that validates ISBNs:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:112ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;_all_isbns &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;not&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._is_valid_isbn(isbn):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ValueError&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Invalid ISBN&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._add_isbn(isbn)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;get_book_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot; by &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;, stock: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;classmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;get_store_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to the library! We currently hold &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._all_isbns)&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; distinct titles.&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;classmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;_add_isbn&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, isbn: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._all_isbns.add(isbn)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;staticmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;_is_valid_isbn&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(isbn: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;bool&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;clean &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn.replace(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;-&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;).replace(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(clean) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;13&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;or&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;not&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; clean.isdigit():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;False&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;total &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;sum&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(d) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; i, d &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;enumerate&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(clean))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; total &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;123-4567890123&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: ValueError: Invalid ISBN&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Class attributes can be assigned via class methods or directly on the class, but not on an instance. An instance can read a class attribute, but trying to assign to it creates a new instance attribute instead of modifying the class attribute (mutating a mutable object is the exception):&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:380ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;_all_isbns &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;test &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._add_isbn(isbn)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;classmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;_add_isbn&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, isbn: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._all_isbns.add(isbn)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;python_crash_course &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Python Crash Course&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Eric Matthes&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-7115613639&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(Book.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__dict__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# {&apos;__module__&apos;: &apos;__main__&apos;, &apos;_all_isbns&apos;: {&apos;978-7115613639&apos;}, &apos;test&apos;: 1, &apos;__init__&apos;: &amp;lt;function Book.__init__ at 0x0000020EF37AD1C0&amp;gt;, &apos;_add_isbn&apos;: &amp;lt;classmethod(&amp;lt;function Book._add_isbn at 0x0000020EF37AD260&amp;gt;)&amp;gt;, &apos;__dict__&apos;: &amp;lt;attribute &apos;__dict__&apos; of &apos;Book&apos; objects&amp;gt;, &apos;__weakref__&apos;: &amp;lt;attribute &apos;__weakref__&apos; of &apos;Book&apos; objects&amp;gt;, &apos;__doc__&apos;: None}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(python_crash_course.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__dict__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# {&apos;title&apos;: &apos;Python Crash Course&apos;, &apos;author&apos;: &apos;Eric Matthes&apos;, &apos;isbn&apos;: &apos;978-7115613639&apos;, &apos;stock&apos;: 5}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;python_crash_course._all_isbns.add(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;python_crash_course.test &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;123&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(Book.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__dict__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# {&apos;__module__&apos;: &apos;__main__&apos;, &apos;_all_isbns&apos;: {&apos;978-7115613639&apos;, &apos;978-1492056355&apos;}, &apos;test&apos;: 1, &apos;__init__&apos;: &amp;lt;function Book.__init__ at 0x0000020EF37AD1C0&amp;gt;, &apos;_add_isbn&apos;: &amp;lt;classmethod(&amp;lt;function Book._add_isbn at 0x0000020EF37AD260&amp;gt;)&amp;gt;, &apos;__dict__&apos;: &amp;lt;attribute &apos;__dict__&apos; of &apos;Book&apos; objects&amp;gt;, &apos;__weakref__&apos;: &amp;lt;attribute &apos;__weakref__&apos; of &apos;Book&apos; objects&amp;gt;, &apos;__doc__&apos;: None}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(python_crash_course.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__dict__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# {&apos;title&apos;: &apos;Python Crash Course&apos;, &apos;author&apos;: &apos;Eric Matthes&apos;, &apos;isbn&apos;: &apos;978-7115613639&apos;, &apos;stock&apos;: 5, &apos;test&apos;: 123}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;section&gt;&lt;h3 id=&quot;reuse-through-inheritance&quot;&gt;Reuse Through Inheritance&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#reuse-through-inheritance&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When you write a class, you don’t always have to start from scratch. If the class you want is a specialized version of an existing class, use inheritance. When one class inherits from another, it automatically gets all of the parent’s attributes and methods. The original class is called the parent class, and the new class is the child class. A child class not only inherits everything from its parent — it can also define its own attributes and methods.&lt;/p&gt;&lt;p&gt;Say we have a &lt;code&gt;Vehicle&lt;/code&gt; class and we want to write a &lt;code&gt;Car&lt;/code&gt; class — inheritance fits perfectly. The syntax is straightforward: put the base class’s name in parentheses when defining the class.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:39ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Vehicle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; brand&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;drive&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;The vehicle is driving&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Car&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Vehicle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(brand)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;honk&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Beep beep&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;super()&lt;/code&gt; lets us call methods on the parent class. That line invokes &lt;code&gt;Vehicle&lt;/code&gt;’s &lt;code&gt;__init__()&lt;/code&gt;, so &lt;code&gt;Car&lt;/code&gt; instances get all the attributes defined there.&lt;/p&gt;&lt;p&gt;A child class can also provide a new implementation of a method with the same name as the parent’s — this is called overriding. It lets the child class tailor inherited behavior to its own needs:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:45ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Car&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Vehicle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(brand)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;drive&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; car is driving&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;honk&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Beep beep&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Suppose you accidentally spell &lt;code&gt;drive&lt;/code&gt; as &lt;code&gt;driv&lt;/code&gt; — a method that doesn’t exist in the parent. When you call &lt;code&gt;drive&lt;/code&gt; on the child, it would silently fall back to the parent’s &lt;code&gt;drive&lt;/code&gt;. To let type checkers catch this mistake, annotate the method with &lt;code&gt;@override&lt;/code&gt; to make the override relationship explicit:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:45ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; typing &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Vehicle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; brand&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;drive&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;The vehicle is driving&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Car&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Vehicle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(brand)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@override&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;driv&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; car is driving&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;honk&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Beep beep&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Python allows a class to inherit from multiple parent classes at once. For example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:61ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Radio&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;play_music&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, name):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Radio is playing: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;MusicCar&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Car&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Radio&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_music_car &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; MusicCar(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Unknown&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_music_car.drive()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# from Car&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_music_car.play_music(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Big Fish - Zhou Shen&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# from Radio&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;When a class has multiple parents that may define methods with the same name, Python follows a well-defined, predictable order to look up methods (including for &lt;code&gt;super()&lt;/code&gt;). That order is the MRO. Generally you don’t need to know how Python computes it — you can just inspect the result with &lt;code&gt;__mro__&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:159ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(MusicCar.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__mro__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: (&amp;lt;class &apos;__main__.MusicCar&apos;&amp;gt;, &amp;lt;class &apos;__main__.Car&apos;&amp;gt;, &amp;lt;class &apos;__main__.Vehicle&apos;&amp;gt;, &amp;lt;class &apos;__main__.Radio&apos;&amp;gt;, &amp;lt;class &apos;object&apos;&amp;gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;From the output, the order is MusicCar -&amp;gt; Car -&amp;gt; Vehicle -&amp;gt; Radio -&amp;gt; object.&lt;/p&gt;&lt;p&gt;You can use &lt;code&gt;isinstance()&lt;/code&gt; to check whether an object is an instance of a class or one of its subclasses:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:51ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Vehicle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; brand&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;drive&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;The vehicle is driving&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Car&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Vehicle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(brand)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;drive&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; car is driving&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Bike&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Vehicle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(brand)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;drive&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; bike is driving&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_bike &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Bike(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Unknown&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_car &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Car(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Unknown&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;isinstance&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(my_bike, Bike))  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: True&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;isinstance&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(my_bike, Vehicle))  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: True&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;isinstance&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(my_car, Vehicle))  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: True&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;isinstance&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(my_car, Bike))  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: False&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;do-we-really-need-inheritance&quot;&gt;Do We Really Need Inheritance?&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#do-we-really-need-inheritance&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Inheritance models an “is-a” relationship — a car is a vehicle, for instance. But we also run into “has-a” relationships: the &lt;code&gt;MusicCar&lt;/code&gt; in the earlier example &lt;em&gt;has a&lt;/em&gt; radio. In that case, instead of inheriting, it’s usually better to compose: use an instance of the other class as an attribute. Here’s a concrete example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:90ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Radio&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;play_music&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, name):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Radio is playing: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Car&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, brand):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; brand&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.radio &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Radio()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;drive&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.brand&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; car is driving&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;play_music&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, name):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.radio.play_music(name)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_car &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Car(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Unknown&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_car.drive()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Unknown car is driving&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;my_car.play_music(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Big Fish - Zhou Shen&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Radio is playing: Big Fish - Zhou Shen&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;In practice, whether to use inheritance or composition comes down to whether the two classes have a clear hierarchical relationship. If they don’t, composition is the better approach.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;customizing-class-behavior&quot;&gt;Customizing Class Behavior&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#customizing-class-behavior&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Sometimes we need to customize a class’s behavior. We can do this with magic methods (in most cases) or metaclasses (in rare cases).&lt;/p&gt;&lt;section&gt;&lt;h3 id=&quot;with-magic-methods&quot;&gt;With Magic Methods&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#with-magic-methods&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4 id=&quot;customizing-instantiation-with-__new__&quot;&gt;Customizing Instantiation with &lt;code&gt;__new__&lt;/code&gt;&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#customizing-instantiation-with-__new__&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The magic method we use most is &lt;code&gt;__init__()&lt;/code&gt;. But &lt;code&gt;__init__()&lt;/code&gt; isn’t the first thing called — &lt;code&gt;__new__()&lt;/code&gt; runs before it. By default, &lt;code&gt;__new__()&lt;/code&gt; creates the instance and passes it as the first argument to &lt;code&gt;__init__()&lt;/code&gt;, which receives the new instance and returns it. By overriding &lt;code&gt;__init__()&lt;/code&gt; we can automatically add attributes to newly created instances; by overriding &lt;code&gt;__new__()&lt;/code&gt; we can customize the instance creation process itself. For example, here’s the singleton pattern:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:48ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;_instance &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;_initialized &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;False&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;not&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._instance:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._instance &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._instance&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, test):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;not&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._initialized:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._initialized &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.test &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;a1 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; A(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;a2 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; A(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(a1 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;is&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; a2)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: True&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(a2.test)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Because we’ve overridden &lt;code&gt;__new__()&lt;/code&gt;, we must explicitly call the parent’s instantiation logic — that is, &lt;code&gt;super().__new__(cls)&lt;/code&gt; (the parent is &lt;code&gt;object&lt;/code&gt;, the root of all classes). We also must return an instance; otherwise the rest of the machinery never runs and instantiation is cut short. And if we returned an instance of some other class here, that’s the instance the rest of the process would use.&lt;/p&gt;&lt;p&gt;Also, since &lt;code&gt;__init__()&lt;/code&gt; runs on every instantiation, we need to limit how many times it takes effect — otherwise later instantiations would overwrite the existing singleton’s state, unless that’s the behavior you want.&lt;/p&gt;&lt;p&gt;There’s one more magic method tied to an instance’s lifecycle: &lt;code&gt;__del__()&lt;/code&gt;. I don’t recommend customizing it — the official Python docs advise against it too — and I won’t cover it here. Instead of customizing &lt;code&gt;__del__&lt;/code&gt;, just write a &lt;code&gt;close()&lt;/code&gt; method.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;custom-string-representations&quot;&gt;Custom String Representations&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#custom-string-representations&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;When we &lt;code&gt;print&lt;/code&gt; an object we defined, the output looks like &lt;code&gt;&amp;lt;__main__.Book object at 0x00000230AA7EA060&amp;gt;&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:77ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(fluent_python)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;__main__.Book object at 0x00000230AA7EA060&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If you want an easy-to-read string representation of the object, it might seem like the only option is a &lt;code&gt;get_book_info&lt;/code&gt; method — but is it really?&lt;/p&gt;&lt;p&gt;We can define an object’s string representation with the magic method &lt;code&gt;__str__()&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:100ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__str__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot; by &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; (ISBN: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;) - Stock: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(fluent_python)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &quot;Fluent Python&quot; by Luciano Ramalho (ISBN: 978-1492056355) - Stock: 3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Much clearer now, isn’t it? But there’s a catch: from this output you can’t tell what attributes the class has or what values they hold — in short, it’s not formal enough. That’s when you define a &lt;code&gt;__repr__()&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:110ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__str__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot; by &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; (ISBN: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;) - Stock: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__repr__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Book(title=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;, author=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;, isbn=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;, stock=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Book(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Fluent Python&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Luciano Ramalho&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;978-1492056355&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(fluent_python)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# &quot;Fluent Python&quot; by Luciano Ramalho (ISBN: 978-1492056355) - Stock: 3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!s&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# &quot;Fluent Python&quot; by Luciano Ramalho (ISBN: 978-1492056355) - Stock: 3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fluent_python&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!r&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Book(title=Fluent Python, author=Luciano Ramalho, isbn=978-1492056355, stock=3)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;When nothing is specified, printing shows what &lt;code&gt;__str__&lt;/code&gt; defines. When you explicitly ask for the formal representation, you get what &lt;code&gt;__repr__&lt;/code&gt; defines.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;comparisons-with-magic-methods&quot;&gt;Comparisons with Magic Methods&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#comparisons-with-magic-methods&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;The magic methods used for comparisons are:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;__eq__(self, other)&lt;/code&gt;: defines equality behavior (==).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__ne__(self, other)&lt;/code&gt;: defines inequality behavior (!=).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__lt__(self, other)&lt;/code&gt;: defines less-than behavior (&amp;lt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__le__(self, other)&lt;/code&gt;: defines less-than-or-equal behavior (&amp;lt;=).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__gt__(self, other)&lt;/code&gt;: defines greater-than behavior (&amp;gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__ge__(self, other)&lt;/code&gt;: defines greater-than-or-equal behavior (&amp;gt;=).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Here’s an example: a class that represents a word. You might want to compare words in lexicographic (alphabetical) order — the default string comparison already does that — but you might also want to compare by other criteria, like word length or syllable count. In this example we’ll compare by length. Here’s the implementation:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:94ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Word&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, word):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Note that we have to use __new__. This is because str is an immutable&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# type, so we have to initialize the value at creation time&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; word:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Value contains spaces. Truncating to first space.&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;word &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; word[:word.index(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)]  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# the word is all characters before the first space&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, word)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__gt__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, other):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(other)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__lt__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, other):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(other)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__ge__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, other):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(other)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__le__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, other):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(other)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;word1 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Word(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;hello&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;word2 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Word(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;world&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;word3 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Word(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;python&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(word1 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; word2)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: False&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(word1 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; word3)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: True&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(word2 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; word1) &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: True&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Note that we didn’t define &lt;code&gt;__eq__()&lt;/code&gt; and &lt;code&gt;__ne__()&lt;/code&gt;. That’s deliberate: defining them would produce some strange results (for example, &lt;code&gt;Word(&apos;foo&apos;) == Word(&apos;bar&apos;)&lt;/code&gt; would return True). So we leave them out and fall back on &lt;code&gt;str&lt;/code&gt;’s built-in comparison.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;context-managers&quot;&gt;Context Managers&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#context-managers&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Context managers make sure resources are cleaned up properly after use. We can implement one with the magic methods &lt;code&gt;__enter__()&lt;/code&gt; and &lt;code&gt;__exit__()&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:67ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;DatabaseConnection&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, database_name):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.database_name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; database_name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.connection &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__enter__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Connecting to database: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.database_name&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.connection &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.database_name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.connection&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__exit__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, exc_type, exc_value, traceback):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Closing database connection: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.database_name&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;with&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; DatabaseConnection(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;user database&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; conn:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Using connection: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;conn&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Performing database operations...&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;with&lt;/code&gt; runs whatever &lt;code&gt;__enter__()&lt;/code&gt; defines when entering the block and binds &lt;code&gt;__enter__()&lt;/code&gt;’s return value to the target in the &lt;code&gt;as&lt;/code&gt; clause (if there is one). When leaving the block, whatever &lt;code&gt;__exit__()&lt;/code&gt; defines runs.&lt;/p&gt;&lt;p&gt;For async code, just switch to &lt;code&gt;__aenter__()&lt;/code&gt; and &lt;code&gt;__aexit__()&lt;/code&gt;.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;optimizing-attribute-access-with-slots&quot;&gt;Optimizing Attribute Access with &lt;strong&gt;slots&lt;/strong&gt;&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#optimizing-attribute-access-with-slots&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;By default, Python objects store attributes in a dictionary. The upside is that you can add attributes dynamically; the downside is that it can use more memory and lookups are relatively slow. Defining &lt;code&gt;__slots__&lt;/code&gt; prevents the class from creating a &lt;code&gt;__dict__&lt;/code&gt; and a &lt;code&gt;__weakref__&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;To use &lt;code&gt;__slots__&lt;/code&gt;, define an attribute named &lt;code&gt;__slots__&lt;/code&gt; in the class and give it the allowed attribute names:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:52ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__slots__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;isbn&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;stock&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, title, author, isbn, stock):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; title&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.author &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; author&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.isbn &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; isbn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.stock &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; stock&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Note that without &lt;code&gt;__weakref__&lt;/code&gt;, this class doesn’t support weak references. If you need weak reference support, declare &lt;code&gt;__weakref__&lt;/code&gt; in &lt;code&gt;__slots__&lt;/code&gt; manually.&lt;/p&gt;&lt;p&gt;With inheritance, if the parent class defines &lt;code&gt;__slots__&lt;/code&gt;, the child class must define its own too — otherwise child instances will have a &lt;code&gt;__dict__&lt;/code&gt; and &lt;code&gt;__weakref__&lt;/code&gt;.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;iterators-and-generators&quot;&gt;Iterators and Generators&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#iterators-and-generators&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;You may have noticed that most container objects work with the for statement:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:18ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; char &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;abc&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(char)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Behind the scenes, the for statement calls &lt;code&gt;iter()&lt;/code&gt; on the container object. That function returns an iterator object with a &lt;code&gt;__next__()&lt;/code&gt; method, which accesses the container’s elements one at a time. When there are no more elements, &lt;code&gt;__next__()&lt;/code&gt; raises &lt;code&gt;StopIteration&lt;/code&gt; to signal the loop to end. You can call &lt;code&gt;__next__()&lt;/code&gt; via &lt;code&gt;next()&lt;/code&gt;. Here’s the equivalent of &lt;code&gt;for char in &quot;abc&quot;&lt;/code&gt; spelled out:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:37ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; s &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;abc&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; it &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;iter&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(s)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(it)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(it)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(it)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;c&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(it)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;Traceback (most recent call last):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:2ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;File &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&amp;lt;stdin&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, line &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;StopIteration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;To make one of our own classes iterable, we just implement the above. Define &lt;code&gt;__iter__()&lt;/code&gt; to return an object with a &lt;code&gt;__next__()&lt;/code&gt; method; if the class already defines &lt;code&gt;__next__()&lt;/code&gt;, just return &lt;code&gt;self&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:57ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Reverse&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&quot;&quot;Iterator for looping over a sequence backwards.&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, data):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.data &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.index &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(data)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__iter__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__next__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.index &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;StopIteration&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.index &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.index &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.data[&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.index]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Now for a side note: is there an easier way to implement iteration? Yes — generators. Generators look like regular functions, but they use &lt;code&gt;yield&lt;/code&gt; when they want to return data. They automatically create &lt;code&gt;__iter__()&lt;/code&gt; and &lt;code&gt;__next__()&lt;/code&gt;, and each call to &lt;code&gt;next()&lt;/code&gt; on a generator resumes execution from where it left off. When all elements have been produced, it automatically raises &lt;code&gt;StopIteration&lt;/code&gt;. With generators, creating an iterator can be as easy as writing a regular function:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:44ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;reverse&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(data):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; index &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(data)&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;yield&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; data[index]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;with-metaclasses&quot;&gt;With Metaclasses&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#with-metaclasses&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t. The people who actually need them know with certainty that they need them, and don’t need an explanation why.&lt;/p&gt;
&lt;p&gt;——Tim Peters&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;So I decided not to cover them.&lt;/p&gt;&lt;p&gt;Just kidding — let’s continue.&lt;/p&gt;&lt;section&gt;&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#introduction&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Let’s start with “Hello, World!”:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:128ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;str&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;type&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: (&amp;lt;class &apos;object&apos;&amp;gt;,)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: AttributeError: &apos;str&apos; object has no attribute &apos;__bases__&apos;. Did you mean: &apos;__class__&apos;?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;In Python, everything is an object. Even basic data types are objects created by built-in classes (which is exactly why you can call methods directly on a string). As the code shows, the string &lt;code&gt;&quot;Hello, World!&quot;&lt;/code&gt; is an instance of the built-in class &lt;code&gt;str&lt;/code&gt;, and the string instance itself has no base classes. Turning to the built-in class &lt;code&gt;str&lt;/code&gt;, it’s an instance of the &lt;code&gt;type&lt;/code&gt; class, and its base class is &lt;code&gt;object&lt;/code&gt;. Since instances are what you get when a class is instantiated, the built-in class &lt;code&gt;str&lt;/code&gt; must itself be instantiated by &lt;code&gt;type&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:44ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Book&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(Book.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# &amp;lt;class &apos;type&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(Book.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# (&amp;lt;class &apos;object&apos;&amp;gt;,)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The same holds for our custom classes: they inherit from &lt;code&gt;object&lt;/code&gt; and are instances of &lt;code&gt;type&lt;/code&gt;.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;the-python-object-system--from-the-ground-up&quot;&gt;The Python Object System — From the Ground Up&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#the-python-object-system--from-the-ground-up&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote class=&quot;admonition bdm-note&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;NOTE&lt;/span&gt;&lt;p&gt;This section is largely based on “Python Types and Objects” by Shalabh Chaturvedi, reorganized and adapted by me (Raven95676) for educational purposes. Since the original author retains all rights, this section is not released under the CC BY-NC-SA 4.0 license. If the original copyright holder believes this section infringes on their copyright, please contact me (Raven95676) to have the relevant content removed.&lt;/p&gt;&lt;p&gt;The images referenced in this section are quite old; please read any occurrence of &lt;code&gt;&amp;lt;type &apos;object&apos;&amp;gt;&lt;/code&gt; in them as &lt;code&gt;&amp;lt;class &apos;object&apos;&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;We’re going to build the Python object system from scratch, starting at the very beginning — a blank sheet of paper.&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_3&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;571&quot; height=&quot;357&quot; src=&quot;https://blog.ravenote.me/_astro/3.C4paqDEQ_1OSMzV.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;Before drawing anything, let’s introduce the relationships. We connect objects with two kinds of relationships:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Subclass-parent class relationship (inheritance): one object is a specialized version of another — “a catgirl is a kind of fantasy creature”.&lt;/li&gt;
&lt;li&gt;Type-instance relationship (instantiation): one object is a concrete instance of another — “Nova the catgirl is an instance of catgirl”.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Inheritance is drawn as a solid line from child to parent; instantiation is a dashed line from instance to type, as in the diagram below:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_4&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;341&quot; height=&quot;215&quot; src=&quot;https://blog.ravenote.me/_astro/4.DHhsQHTP_NFUYr.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;Let’s start our exploration at the root of everything:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:52ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;type&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: ()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;type&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: (&amp;lt;class &apos;object&apos;&amp;gt;,)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;object&lt;/code&gt; is instantiated by &lt;code&gt;type&lt;/code&gt; and has no parent class. That makes &lt;code&gt;object&lt;/code&gt; the starting point of inheritance. &lt;code&gt;type&lt;/code&gt; is instantiated by itself, and its parent is &lt;code&gt;object&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Let’s put these findings on the diagram:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_5&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;571&quot; height=&quot;357&quot; src=&quot;https://blog.ravenote.me/_astro/5.CP2vNWu4_2gmrdj.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;Now let’s bring in the built-in data types &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;dict&lt;/code&gt;, and &lt;code&gt;tuple&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:53ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;type&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: (&amp;lt;class &apos;object&apos;&amp;gt;,)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;tuple&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;type&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;tuple&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: (&amp;lt;class &apos;object&apos;&amp;gt;,)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;type&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: (&amp;lt;class &apos;object&apos;&amp;gt;,)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;They all inherit from &lt;code&gt;object&lt;/code&gt; and are all instantiated by &lt;code&gt;type&lt;/code&gt;. Now let’s instantiate a list and see what happens:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:120ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;mylist &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(mylist.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;list&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(mylist.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: AttributeError: &apos;list&apos; object has no attribute &apos;__bases__&apos;. Did you mean: &apos;__class__&apos;?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;mylist&lt;/code&gt; is instantiated by &lt;code&gt;list&lt;/code&gt; and has no parent class.&lt;/p&gt;&lt;p&gt;Let’s add these findings to the diagram:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_6&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;571&quot; height=&quot;357&quot; src=&quot;https://blog.ravenote.me/_astro/6.DYr60dfI_Z1xSYg7.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;Now let’s define our own class based on the existing &lt;code&gt;object&lt;/code&gt; class (if you don’t specify a base, the class inherits from &lt;code&gt;object&lt;/code&gt; by default), then instantiate it:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:53ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;C&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;obj &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;cobj &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; C()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(C.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;type&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(C.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__bases__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: (&amp;lt;class &apos;object&apos;&amp;gt;,)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(obj.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;object&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cobj.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: &amp;lt;class &apos;__main__.C&apos;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Let’s put these findings on the diagram:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_7&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;571&quot; height=&quot;357&quot; src=&quot;https://blog.ravenote.me/_astro/7.BmMzb_9O_9mw6i.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;In fact, what each of these three boxes represents is now plain to see:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_8&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;571&quot; height=&quot;357&quot; src=&quot;https://blog.ravenote.me/_astro/8.TuSz7pnd_ZGLOE5.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;The first box is the class of all classes — we call it the metaclass.&lt;/p&gt;&lt;p&gt;The second box is both the class of the third box and an instance of the first box — we call it the type object.&lt;/p&gt;&lt;p&gt;The third box is an instance of the second box — we simply call it the instance.&lt;/p&gt;&lt;p&gt;The metaclass instantiates type objects, and type objects instantiate classes. In other words, the creation of every new object ultimately boils down to instantiation.&lt;/p&gt;&lt;p&gt;So the following two snippets are essentially equivalent:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:33ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;MyClass&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;MyClass &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;MyClass&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, (), {})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;using-metaclasses&quot;&gt;Using Metaclasses&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#using-metaclasses&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;So now we——&lt;/p&gt;&lt;p&gt;We know: by default, classes are built with &lt;code&gt;type&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;We know: classes can be inherited from.&lt;/p&gt;&lt;p&gt;So can we inherit from &lt;code&gt;type&lt;/code&gt;, create a new metaclass, and use that new metaclass to create classes? Of course we can — that’s the very core of metaclasses.&lt;/p&gt;&lt;p&gt;Congratulations — we’re finally ready to learn how to use metaclasses.&lt;/p&gt;&lt;p&gt;A basic metaclass typically inherits from &lt;code&gt;type&lt;/code&gt; and overrides its &lt;code&gt;__new__()&lt;/code&gt; or &lt;code&gt;__init__()&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:66ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Meta&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, clsname: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, bases: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;tuple&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, clsdict: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, clsname, bases, clsdict)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, clsname: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, bases: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;tuple&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, clsdict: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;dict&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(clsname, bases, clsdict)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;clsname&lt;/code&gt; is the class name and will become the new class’s &lt;code&gt;__name__&lt;/code&gt; attribute. &lt;code&gt;bases&lt;/code&gt; is the tuple of base classes and will become the &lt;code&gt;__bases__&lt;/code&gt; attribute; if it’s empty, &lt;code&gt;object&lt;/code&gt; is added. &lt;code&gt;clsdict&lt;/code&gt; is the dict of attribute and method definitions from the class body; it may be copied or wrapped before becoming the &lt;code&gt;__dict__&lt;/code&gt; attribute.&lt;/p&gt;&lt;p&gt;Now let’s give this metaclass a job: it will reject any class definition containing method names with mixed case:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:62ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;NoMixedCaseMeta&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, clsname, bases, clsdict):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; clsdict:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name.lower() &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:16ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;TypeError&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;Bad attribute name: &apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, clsname, bases, clsdict)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;How do you apply a metaclass? By specifying the &lt;code&gt;metaclass&lt;/code&gt; parameter:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:69ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;metaclass&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;NoMixedCaseMeta&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;foo_bar&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;metaclass&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;NoMixedCaseMeta&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fooBar&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: TypeError: Bad attribute name: fooBar&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;From our discussion above, we know classes are instantiated by a metaclass, which defaults to &lt;code&gt;type&lt;/code&gt;. So specifying &lt;code&gt;metaclass&lt;/code&gt; is equivalent to going from:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:49ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;A &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, (), {&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;foo_bar&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;lambda&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; self: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;B &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, (), {&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;fooBar&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;lambda&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; self: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;to:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:107ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;A &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; NoMixedCaseMeta(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;A&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, (), {&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;foo_bar&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;lambda&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; self: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;B &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; NoMixedCaseMeta(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;B&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, (), {&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;fooBar&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;lambda&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; self: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;})  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: TypeError: Bad attribute name: fooBar&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;practical-oop-tips-in-python&quot;&gt;Practical OOP Tips in Python&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#practical-oop-tips-in-python&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3 id=&quot;private-attributes&quot;&gt;”Private” Attributes&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#private-attributes&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Python doesn’t have truly private attributes. But most Python code follows a convention: a name with a single leading underscore should be treated as a non-public part of the API (whether it’s a function, method, or data member). If that implementation ever disappears or its behavior changes, you’re on your own.&lt;/p&gt;&lt;p&gt;When a name has at least two leading underscores and at most one trailing underscore, it’s replaced with &lt;code&gt;_classname__name&lt;/code&gt;, where &lt;code&gt;classname&lt;/code&gt; is the current class name without the leading underscores. This mechanism is called name mangling. It’s generally used to avoid name clashes with names defined by subclasses.&lt;/p&gt;&lt;p&gt;Some tutorials online claim this mechanism can implement private attributes — that internal code can access the attribute while external code can’t. The second half of that claim is wrong: renaming a name doesn’t make it inaccessible. And personally, I wouldn’t use name mangling for this purpose — no matter how you mangle it, the attribute is still accessible from anywhere, so why bother?&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;defining-interfaces-with-abstract-base-classes&quot;&gt;Defining Interfaces with Abstract Base Classes&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#defining-interfaces-with-abstract-base-classes&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In large multi-developer projects, how do you make sure classes written by different developers all follow a unified interface? That’s where abstract base classes come in. An ABC defines a set of methods that must be implemented; any subclass must implement every abstract method, or instantiating it raises an exception:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:158ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; abc &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;CacheInterface&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;save_to_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, key, value):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;load_from_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, key):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;RedisCache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;CacheInterface&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;save_to_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, key, value):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Saved to Redis: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;load_from_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, key):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Loaded from Redis: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;cached_&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;FileCache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;CacheInterface&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;save_to_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, key, value):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Saved to file: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;load_from_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, key):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Loaded from file: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;file_&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;IncompleteCache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;CacheInterface&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;save_to_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, key, value):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Saved: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;redis_cache &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; RedisCache()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;file_cache &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; FileCache()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;test &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; IncompleteCache()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: TypeError: Can&apos;t instantiate abstract class IncompleteCache without an implementation for abstract method &apos;load_from_cache&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;using-enums&quot;&gt;Using Enums&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#using-enums&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When writing code we often need to represent a fixed set of states or types — order status (pending payment, paid, shipped), for example. Enums are a much more elegant way to do this:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:27ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; enum &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Enum, auto&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;OrderStatus&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Enum&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;PENDING&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;pending&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;PAID&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;paid&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;SHIPPED&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;shipped&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;DELIVERED&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;delivered&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;CANCELLED&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;cancelled&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If the concrete values don’t matter, use &lt;code&gt;auto&lt;/code&gt; to generate them automatically:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:21ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Priority&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Enum&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;LOW&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; auto()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;MEDIUM&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; auto()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;HIGH&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; auto()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;eliminating-duplicate-code-with-decorators&quot;&gt;Eliminating Duplicate Code with Decorators&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#eliminating-duplicate-code-with-decorators&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4 id=&quot;writing-your-own-decorators&quot;&gt;Writing Your Own Decorators&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#writing-your-own-decorators&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Generally speaking, a decorator is a function that takes another function as an argument and returns a closure with extra behavior added (hence the name “decorator”). Suppose we need functions that generate email content:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:33ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;welcome_message&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to our team.&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Formal emails are expected to follow certain etiquette. But the added formatting and content are fixed — if every email-generating function copy-pasted the same boilerplate, a future change to the email format would force you to edit every function. To avoid that hassle, we can write a decorator:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:37ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;email_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Hello,&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Best regards,&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Raven&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Let’s apply it:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:33ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@email_decorator&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;welcome_message&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to our team.&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;welcome_message()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;When we call &lt;code&gt;welcome_message&lt;/code&gt;, what actually runs is the closure &lt;code&gt;wrapper&lt;/code&gt;: it prints the greeting, calls the original function, and finally prints the signature.&lt;/p&gt;&lt;p&gt;In fact, the code above with &lt;code&gt;@&lt;/code&gt; is equivalent to this:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:50ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;welcome_message &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; email_decorator(welcome_message)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;@&lt;/code&gt; is convenient syntactic sugar — decorators work perfectly fine without it.&lt;/p&gt;&lt;p&gt;Right now &lt;code&gt;welcome_message&lt;/code&gt; takes no arguments. What if we want to extend it — say, to accept a department name? You might try this:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:118ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@email_decorator&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;welcome_message&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(department):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to our &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;department&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; team.&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;welcome_message()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: TypeError: email_decorator.&amp;lt;locals&amp;gt;.wrapper() takes 0 positional arguments but 1 was given&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;But that raises a &lt;code&gt;TypeError&lt;/code&gt;. Look closely: &lt;code&gt;func()&lt;/code&gt; inside our decorator takes no arguments — that’s the root of the problem. To make the decorator more general, add &lt;code&gt;*args&lt;/code&gt; and &lt;code&gt;**kwargs&lt;/code&gt; so it accepts any number of arguments (though you can also add exactly the parameters you need):&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:37ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;email_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Hello,&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Best regards,&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Raven&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;You may have noticed that this decorator returns nothing. But the decorated function may need to return a value — in that case the decorator has to “catch” that value and return it. Let’s use a decorator that measures a function’s execution time as an example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:83ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;timer_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;start_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time.time()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; func(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;end_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time.time()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Function &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__name__}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; took &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;end_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; start_time&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;:.4f&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; seconds&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; result&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@timer_decorator&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;calc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(n):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fibonacci&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; fibonacci(x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; fibonacci(x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; fibonacci(n)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; result&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;calc(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;35&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;A detail many people miss: when you try to get metadata of the original function — like &lt;code&gt;__name__&lt;/code&gt; — you get &lt;code&gt;wrapper&lt;/code&gt; instead of the intuitive &lt;code&gt;calc&lt;/code&gt;. That’s expected, because &lt;code&gt;wrapper&lt;/code&gt; is what’s actually being called. But sometimes you genuinely need the original function’s metadata. That’s where the &lt;code&gt;wraps&lt;/code&gt; decorator from the &lt;code&gt;functools&lt;/code&gt; module comes in:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:83ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; functools &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wraps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;timer_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@wraps&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;start_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time.perf_counter()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; func(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;end_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time.perf_counter()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Function &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__name__}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; took &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;end_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; start_time&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;:.4f&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; seconds&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; result&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Back to our email decorator. Sometimes the decorator itself needs to take parameters — say, to customize the sender. In that case we add another layer on top of the existing decorator structure: a function called a decorator factory, which takes the parameters and “produces” a decorator:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:47ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; functools &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wraps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;email_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(from_who):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@wraps&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Hello,&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Best regards,&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\n{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;from_who&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; decorator&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@email_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;from_who&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Raven&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;welcome_message&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(department):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to our &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;department&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; team.&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;welcome_message(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Development&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Why do we need a decorator factory? Can’t we just pass arguments directly? No — because the &lt;code&gt;@&lt;/code&gt; syntax only passes the decorated function to the decorator. If we want the decorator itself to accept arguments, passing them directly won’t work. The &lt;code&gt;@&lt;/code&gt; syntax above is equivalent to:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:70ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;decorated_welcome &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; email_decorator(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;from_who&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Raven&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)(welcome_message)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Here, &lt;code&gt;email_decorator(from_who=&quot;Raven&quot;)&lt;/code&gt; runs first and returns a decorator function, which then receives &lt;code&gt;welcome_message&lt;/code&gt; and produces the final decorated function.&lt;/p&gt;&lt;p&gt;Sometimes one decorator isn’t enough. In that case you simply stack them. One thing to keep in mind: decorators are applied from the bottom up, so don’t get the order wrong:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:47ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; functools &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wraps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;email_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(from_who):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@wraps&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Hello,&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Best regards,&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\n{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;from_who&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; decorator&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;add_studio_info&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@wraps&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; func(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;---&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Raven-Studio&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; result&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@add_studio_info&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@email_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;from_who&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Raven&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;welcome_message&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(department):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to our &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;department&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; team.&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;welcome_message(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Development&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Actually, the order is easy to understand. The &lt;code&gt;@&lt;/code&gt; usage here is equivalent to:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:85ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;welcome_message &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; add_studio_info(email_decorator(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;from_who&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Raven&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)(welcome_message))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Besides functions, classes can also be used as decorators. This is very useful when you need to manage state or organize complex logic together, and it typically requires overriding two magic methods, &lt;code&gt;__init__()&lt;/code&gt; and &lt;code&gt;__call__()&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:52ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; functools &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wraps&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;EmailDecorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, from_who):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.from_who &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; from_who&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__call__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@wraps&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Hello,&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Best regards,&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\n{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.from_who&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@EmailDecorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;from_who&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Raven&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;welcome_message&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(department):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Welcome to our &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;department&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; team.&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;welcome_message(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Development&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;__init__()&lt;/code&gt; receives the decorator’s arguments; &lt;code&gt;__call__()&lt;/code&gt; receives the function being decorated and returns the wrapped function.&lt;/p&gt;&lt;p&gt;Of course, decorators can also decorate classes — we’ll cover that together in the “Metaclass Alternatives” section below.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;using-the-lru_cache-decorator&quot;&gt;Using the lru_cache Decorator&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#using-the-lru_cache-decorator&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Now let’s turn back to the Fibonacci calculation function:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:83ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; functools &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wraps, lru_cache&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;timer_decorator&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@wraps&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(func)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;wrapper&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;start_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time.perf_counter()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; func(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;end_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; time.perf_counter()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Function &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;func.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__name__}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; took &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;end_time &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; start_time&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;:.4f&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; seconds&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; result&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; wrapper&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@timer_decorator&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;calc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(n):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@lru_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;maxsize&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;4096&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fibonacci&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; fibonacci(x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; fibonacci(x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; fibonacci(n)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; result&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;calc(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;@lru_cache&lt;/code&gt; caches the results of function calls. When the function is called again with the same arguments, it returns the cached result immediately instead of recomputing. Without &lt;code&gt;@lru_cache&lt;/code&gt;, computing &lt;code&gt;calc(50)&lt;/code&gt; takes a while; with it, the call finishes almost instantly.&lt;/p&gt;&lt;p&gt;Of course, &lt;code&gt;@lru_cache&lt;/code&gt; isn’t suitable for every situation. First, the arguments must be hashable — the internal implementation relies on a dictionary that uses the arguments as keys. Second, the function must be called frequently with the same arguments for caching to pay off. And if the function depends on data that changes dynamically without being passed as arguments (like the current time or global state), a cached result may be stale.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;ensuring-unique-enum-values-with-unique&quot;&gt;Ensuring Unique Enum Values with @unique&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#ensuring-unique-enum-values-with-unique&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;By default, enums allow multiple names to be aliases of the same value. If you need every value to be used only once, use the &lt;code&gt;@unique&lt;/code&gt; decorator:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:92ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; enum &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Enum, unique&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@unique&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Mistake&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Enum&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ONE&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;TWO&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;THREE&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;FOUR&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: ValueError: duplicate values found in &amp;lt;enum &apos;Mistake&apos;&amp;gt;: FOUR -&amp;gt; THREE&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;using-the-property-decorator&quot;&gt;Using the property Decorator&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#using-the-property-decorator&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Suppose we’re developing some management system and need a &lt;code&gt;Person&lt;/code&gt; class to manage a person’s information:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:34ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Person&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, name, age):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; age&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Person(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;M&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.age)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 30&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x.age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;360&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.age)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 360&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Here’s the problem: attribute assignment is completely uncontrolled — any value, no matter how unreasonable, gets accepted. We need validation when values are set. One option is writing &lt;code&gt;set_xxx&lt;/code&gt;/&lt;code&gt;get_xxx&lt;/code&gt; methods, but that isn’t very elegant in Python. Instead, use the &lt;code&gt;@property&lt;/code&gt; decorator:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:63ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Person&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, name, age):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; age&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;property&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@age.setter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, value):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;150&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ValueError&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Age must be between 0 and 150&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Person(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;M&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.age)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 30&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x.age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;45&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.age)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 45&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x.age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;360&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: ValueError: Age must be between 0 and 150&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Incidentally, if you don’t define a setter, you get a read-only attribute:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:85ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Person&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, name, age):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; age&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;property&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Person(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;M&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.age)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 30&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x.age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;360&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: AttributeError: property &apos;age&apos; of &apos;Person&apos; object has no setter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;You can also use &lt;code&gt;deleter&lt;/code&gt; to define what happens when the attribute is deleted with &lt;code&gt;del&lt;/code&gt;. For the record, if no deleter is defined, &lt;code&gt;del&lt;/code&gt; raises an &lt;code&gt;AttributeError&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:61ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Person&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, name, age):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; age&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;property&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@age.setter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, value):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;150&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ValueError&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Age must be between 0 and 150&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@age.deleter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._age &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Person(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;M&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.age)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 30&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;del&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x.age&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(x.age)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: 0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;using-the-dataclass-decorator&quot;&gt;Using the dataclass Decorator&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#using-the-dataclass-decorator&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;When creating classes to store data in Python, you usually end up writing a lot of boilerplate. For example, a class to represent a product:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:101ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Product&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, name: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, unit_price: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, quantity: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.unit_price &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; unit_price&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.quantity &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; quantity&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__repr__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Product(name=&apos;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.name&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;, unit_price=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.unit_price&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;, quantity=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.quantity&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__eq__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, other):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;not&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;isinstance&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(other, Product):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;NotImplemented&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.name, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.unit_price, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.quantity) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;other.name,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;other.unit_price,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;other.quantity,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;total_cost&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.unit_price &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.quantity&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Every data class means reams of repetitive code — not very elegant. Fortunately, the &lt;code&gt;@dataclass&lt;/code&gt; decorator generates all that boilerplate for us:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:46ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; dataclasses &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; dataclass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@dataclass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Product&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;name: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;unit_price: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;quantity: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;total_cost&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.unit_price &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.quantity&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;When defining a dataclass, you can give fields default values. Note that all fields without defaults must come before fields with defaults, or you’ll get a &lt;code&gt;TypeError&lt;/code&gt;. For immutable objects, assigning a default directly is fine. For mutable objects, you must use &lt;code&gt;field&lt;/code&gt;’s &lt;code&gt;default_factory&lt;/code&gt; parameter to avoid all instances sharing the same mutable object (after all, defaults live on the class as class attributes):&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:49ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; dataclasses &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; dataclass, field&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@dataclass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Product&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;name: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;unit_price: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;quantity: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;tags: list[&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; field(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;default_factory&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;total_cost&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.unit_price &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.quantity&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;default_factory&lt;/code&gt; needs a callable that takes no arguments; the dataclass calls it to produce a fresh value whenever a default is needed. Passing &lt;code&gt;list&lt;/code&gt; directly initializes an empty list. If you want the default to be a list with specific contents, use a &lt;code&gt;lambda&lt;/code&gt; to define an anonymous function, e.g. &lt;code&gt;lambda: [&quot;content&quot;]&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;By the way, if the default value is an immutable object, you can use the &lt;code&gt;default&lt;/code&gt; parameter directly. Note that &lt;code&gt;default&lt;/code&gt; and &lt;code&gt;default_factory&lt;/code&gt; conflict — which makes sense: with two ways to initialize a default value, Python wouldn’t know which one to call.&lt;/p&gt;&lt;p&gt;And &lt;code&gt;field&lt;/code&gt; can do more than that. If you don’t want a field to appear in &lt;code&gt;__init__()&lt;/code&gt;, set &lt;code&gt;init&lt;/code&gt; to &lt;code&gt;False&lt;/code&gt;. If a field shouldn’t participate in comparisons, set &lt;code&gt;compare&lt;/code&gt; to &lt;code&gt;False&lt;/code&gt;. If a field should be keyword-only, set &lt;code&gt;kw_only&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The dataclass decorator itself also has some very useful parameters. For example, setting &lt;code&gt;frozen&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt; creates an immutable data class:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:77ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; dataclasses &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; dataclass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@dataclass&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;frozen&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Point&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;x: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;y: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;p &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Point(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;p.x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: dataclasses.FrozenInstanceError: cannot assign to field &apos;x&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;You can also set &lt;code&gt;order&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt; to make dataclass instances support ordering comparisons, not just equality. And if some value should be computed dynamically from other values after initialization, define a &lt;code&gt;__post_init__&lt;/code&gt; method:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:62ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; math&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; dataclasses &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; dataclass, field&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@dataclass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Circle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;radius: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;area: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;float&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; field(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;False&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__post_init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.area &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; math.pi &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.radius &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;c &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Circle(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5.0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(c)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Circle(radius=5.0, area=78.53981633974483)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;metaclass-alternatives&quot;&gt;Metaclass Alternatives&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#metaclass-alternatives&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;As I keep saying, 99% of the time you don’t need metaclasses. Lest anyone think that any kind of class customization requires a metaclass, here are the alternatives.&lt;/p&gt;&lt;section&gt;&lt;h4 id=&quot;class-decorators-instead-of-metaclasses&quot;&gt;Class Decorators Instead of Metaclasses&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#class-decorators-instead-of-metaclasses&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;For one-off modifications or checks of a class, a class decorator works. Take the class-decorator equivalent of &lt;code&gt;NoMixedCaseMeta&lt;/code&gt; as an example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:69ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;no_mixed_case&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__dict__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name.lower() &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;TypeError&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;Bad attribute name: &apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@no_mixed_case&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;foo_bar&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@no_mixed_case&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fooBar&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: TypeError: Bad attribute name: fooBar&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;magic-methods-instead-of-metaclasses&quot;&gt;Magic Methods Instead of Metaclasses&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#magic-methods-instead-of-metaclasses&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;What if you need the check to happen at inheritance time? That’s where the &lt;code&gt;__init_subclass__&lt;/code&gt; magic method comes in. Again using the equivalent of &lt;code&gt;NoMixedCaseMeta&lt;/code&gt; as an example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:69ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;NoMixedCaseBase&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init_subclass__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init_subclass__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;args, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__dict__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name.lower() &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:16ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;TypeError&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Bad attribute name: &quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;NoMixedCaseBase&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;foo_bar&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;NoMixedCaseBase&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fooBar&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Raise: TypeError: Bad attribute name: fooBar&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;when-only-a-metaclass-will-do&quot;&gt;When Only a Metaclass Will Do&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#when-only-a-metaclass-will-do&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Is there anything that truly requires a metaclass — something only a metaclass can achieve? Yes. For instance, suppose we get the wild idea to reverse the MRO. That calls for a metaclass:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:116ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PluginA&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Plugin A&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PluginB&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Plugin B&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ReverseMeta&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;mro&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(cls):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;default_mro &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.mro(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;reversed_mro &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;reversed&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(default_mro[:&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;])) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;tuple&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(reversed_mro)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PluginA&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PluginB&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;B&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PluginA&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PluginB&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;metaclass&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ReverseMeta&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(A.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__mro__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# (&amp;lt;class &apos;__main__.A&apos;&amp;gt;, &amp;lt;class &apos;__main__.PluginA&apos;&amp;gt;, &amp;lt;class &apos;__main__.PluginB&apos;&amp;gt;, &amp;lt;class &apos;object&apos;&amp;gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(B.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__mro__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# (&amp;lt;class &apos;__main__.PluginB&apos;&amp;gt;, &amp;lt;class &apos;__main__.PluginA&apos;&amp;gt;, &amp;lt;class &apos;__main__.B&apos;&amp;gt;, &amp;lt;class &apos;object&apos;&amp;gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;a &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; A()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;b &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; B()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(a.test())  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Plugin A&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(b.test())  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Plugin B&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;OK, let’s look at a more down-to-earth example: implementing a minimal ORM.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:95ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Field&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, default&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.default &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;CharField&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Field&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, default&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(default)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;IntegerField&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Field&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, default&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(default)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ModelMeta&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(mcs, name, bases, clsdict):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;Model&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(mcs, name, bases, clsdict)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fields &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; k, v &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; clsdict.items():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;isinstance&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(v, Field):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:16ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;fields[k] &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; v&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; k &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; fields:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;del&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; clsdict[k]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;clsdict[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;__fields__&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; fields&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(mcs, name, bases, clsdict)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Model&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;metaclass&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ModelMeta&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;kwargs):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; field_name, field &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.__fields__.items():&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;value &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; kwargs.get(field_name, field.default)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;setattr&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, field_name, value)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__repr__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;field_values &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; field_name &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.__fields__:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;value &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;getattr&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, field_name)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;field_values.append(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;field_name&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!r&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__class__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__name__}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;, &apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.join(field_values)&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Product&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Model&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;title &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; CharField()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;price &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; IntegerField()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;description &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; CharField(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;default&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;No description&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;product1 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Product(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Laptop&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;price&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;7999&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;description&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Portable computer&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;product2 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Product(&lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Phone&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;price&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;4999&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(product1)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Product(title=&apos;Laptop&apos;, price=7999, description=&apos;Portable computer&apos;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(product2)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Product(title=&apos;Phone&apos;, price=4999, description=&apos;No description&apos;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;oop-best-practices&quot;&gt;OOP Best Practices&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#oop-best-practices&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Code is written for humans to read. Unless you have a compelling reason to do otherwise — in which case leave a comment explaining it — or the code is throwaway, don’t force your future self, or the colleague inheriting your code, to become an archaeologist.&lt;/p&gt;
&lt;p&gt;——Raven&lt;/p&gt;
&lt;/blockquote&gt;&lt;section&gt;&lt;h3 id=&quot;kiss&quot;&gt;KISS&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#kiss&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Keep it simple stupid — this is the overarching principle of best practices. Always pursue simple, clear design and implementation, and avoid unnecessary complexity.&lt;/p&gt;&lt;p&gt;Here’s the simplest example. Suppose we need a function that takes a list of integers and returns the squares of all even numbers in it. A more convoluted version looks like this:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:47ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;process_data&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(data: list[&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]) -&amp;gt; list[&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;temp &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; item &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; data:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; item &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;temp.append(item)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; temp:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;result.append(num&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; result&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;It only takes a single list comprehension:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:47ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;process_data&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(data: list[&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]) -&amp;gt; list[&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [x&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; data &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;yagni&quot;&gt;YAGNI&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#yagni&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;YAGNI stands for “You aren’t gonna need it”. When writing code, don’t overthink it — get the task in front of you done first, and adapt when the need actually arises. Don’t assume “what if we need it someday?”. Unless there’s a concrete requirement, that “someday” is just a possibility — not worth pouring a lot of effort into.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;solid&quot;&gt;SOLID&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#solid&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote class=&quot;admonition bdm-note&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;NOTE&lt;/span&gt;&lt;p&gt;This section draws on the relevant definitions from Wikipedia. Since Wikipedia content is licensed under CC BY-SA 4.0, this section is not released under the CC BY-NC-SA 4.0 license.&lt;/p&gt;&lt;p&gt;This section is largely based on “Have you really understood SOLID after all these years of coding?” by Mei Xuesong.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_9&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1078&quot; height=&quot;380&quot; src=&quot;https://blog.ravenote.me/_astro/9.nFCAI9Q4_Z2l7lDh.webp&quot; /&gt;
(Image source: “Have you really understood SOLID after all these years of coding?” by Mei Xuesong)&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;In short, the Single Responsibility Principle is the foundation of all design principles, and the Open/Closed Principle is the ultimate goal of design. The Liskov Substitution Principle emphasizes the correctness of a program at runtime when subclasses replace their parent classes, and it helps achieve the Open/Closed Principle. The Interface Segregation Principle helps achieve the Liskov Substitution Principle while also embodying the Single Responsibility Principle. The Dependency Inversion Principle is the dividing line between procedural programming and object-oriented programming, and it also guides the Interface Segregation Principle.&lt;/p&gt;
&lt;p&gt;——Mei Xuesong&lt;/p&gt;
&lt;/blockquote&gt;&lt;section&gt;&lt;h4 id=&quot;s---single-responsibility-principle&quot;&gt;S - Single Responsibility Principle&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#s---single-responsibility-principle&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;An object should have only a single responsibility.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Per Robert C. Martin’s definition, the core idea of the Single Responsibility Principle is to use “reasons to change” as the criterion for defining responsibilities: every class or module should have exactly one reason to change. If you can think of more than one reason to change a class, that class has more than one responsibility.&lt;/p&gt;&lt;p&gt;Take a report processing module as an example. Imagine a module that both edits and prints reports. Such a module has two reasons to change. First, the content of the report can change (editing). Second, the format of the report can change (printing). These two kinds of changes happen for entirely different reasons. The Single Responsibility Principle holds that these are in fact two separate responsibilities, and so they should live in separate classes or modules.&lt;/p&gt;&lt;p&gt;Coupling things that change for different reasons is bad design. If the report editing flow changes, there’s serious danger: when both responsibilities live in the same class, a change to the editing flow can alter shared state or dependencies and break the printing code.&lt;/p&gt;&lt;p&gt;Frequency of change is another reason worth considering. Even within the same role, requirements change at different rates. The classic case: business logic requirements are relatively stable, while presentation requirements change much more often — people always want something new. So these two kinds of requirements are typically implemented in different classes.&lt;/p&gt;&lt;p&gt;In a sense, the Single Responsibility Principle is about separating concerns: separating the concerns of different roles, and separating concerns that change at different times.&lt;/p&gt;&lt;p&gt;How do you apply the Single Responsibility Principle in practice? When do you split, and when do you merge? Watch a new chef learning to stir-fry and figuring out “a pinch of salt”. He keeps tasting until the flavor is just right. Writing code works the same way: you need to recognize the signals of changing requirements, keep “tasting” your code, and refactor until the “flavor” is exactly right.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;o---openclosed-principle&quot;&gt;O - Open/Closed Principle&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#o---openclosed-principle&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;Software should be open for extension, but closed for modification.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;A well-designed entity should be able to change its behavior without modifying its source code.&lt;/p&gt;&lt;p&gt;Why? Suppose you’re the author of a successful open-source library used by many developers. One day you need to extend a feature, and the only way is to modify existing code — which forces every library user to change their code too. Worse, after they’re forced to make those changes, their own dependents may end up forced to change theirs as well. That scenario is an absolute disaster.&lt;/p&gt;&lt;p&gt;That said, we can’t foresee every possible extension point at initial design time, and we can’t reserve extension points everywhere. The right approach is to let requirement changes drive design decisions (which is YAGNI).&lt;/p&gt;&lt;p&gt;We may never fully achieve the Open/Closed Principle, but that doesn’t stop it from being the ultimate goal of design. Every other SOLID principle serves the Open/Closed Principle, directly or indirectly.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;l---liskov-substitution-principle&quot;&gt;L - Liskov Substitution Principle&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#l---liskov-substitution-principle&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;Objects in a program should be replaceable by instances of their subtypes without altering the correctness of that program.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Anywhere a parent class is used in a program, a subclass should be substitutable without changing the program’s behavior. A subclass should extend the parent’s behavior, not alter it. The classic example comes from Robert C. Martin’s “Agile Software Development: Principles, Patterns, and Practices”: the square inheriting from the rectangle.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:61ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Rectangle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, width: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, height: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._width &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; width&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._height &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; height&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;property&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._width&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@width.setter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, value: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._width &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;property&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._height&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@height.setter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, value: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._height &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;property&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;area&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._width &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._height&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Square&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Rectangle&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, size: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(size, size)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;property&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().width&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@width.setter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, value: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._width &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._height &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;property&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self) -&amp;gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;().height&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@height.setter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, value: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._width &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;._height &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;print_area&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(rect: Rectangle):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;51&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;rect.width &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;rect.height &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;53&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Area: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;rect.area&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;54&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;55&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;56&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;rect &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Rectangle(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;57&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;print_area(rect)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Area: 50&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;58&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;59&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;sq &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Square(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;60&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;print_area(sq)  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Area: 100  &amp;lt;-- behavior has changed&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Common sense says a square is a special kind of rectangle, so square-inherits-from-rectangle seems harmless. But &lt;code&gt;print_area&lt;/code&gt; assumes that after setting width to 5 and height to 10, the passed-in &lt;code&gt;Rectangle&lt;/code&gt; has an area of 50. When a &lt;code&gt;Square&lt;/code&gt; is passed in, &lt;code&gt;Square&lt;/code&gt; enforces equal width and height, so setting &lt;code&gt;height&lt;/code&gt; to 10 also sets &lt;code&gt;width&lt;/code&gt; to 10, making the area 100. Thus &lt;code&gt;Square&lt;/code&gt; cannot fully replace &lt;code&gt;Rectangle&lt;/code&gt;: it changes the behavior &lt;code&gt;print_area&lt;/code&gt; expects.&lt;/p&gt;&lt;p&gt;In short, the conflict stems from the behavioral contract implied by &lt;code&gt;Rectangle&lt;/code&gt;’s methods. &lt;code&gt;Rectangle&lt;/code&gt;’s setters imply that “width and height can be modified independently”, and &lt;code&gt;Square&lt;/code&gt;’s implementation breaks that contract — which is why it violates the Liskov Substitution Principle.&lt;/p&gt;&lt;p&gt;If your design satisfies the Liskov Substitution Principle, subclasses (or implementations of an interface) can replace their parents (or the interface) without breaking correctness, changing the system’s behavior and thereby extending it. Both Branch By Abstraction (introducing an abstraction layer that the old and new implementations both conform to, then gradually replacing functionality) and the Strangler pattern (during the transition period when old and new systems coexist, routing requests to old and new implementations through an abstraction layer, gradually migrating functionality to the new system) build on the Liskov Substitution Principle to extend and evolve systems. That is precisely “closed for modification, open for extension” — which makes the Liskov Substitution Principle a way to achieve the Open/Closed Principle.&lt;/p&gt;&lt;p&gt;And to achieve the Liskov Substitution Principle, you need the Interface Segregation Principle.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;i---interface-segregation-principle&quot;&gt;I - Interface Segregation Principle&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#i---interface-segregation-principle&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;Many client-specific interfaces are better than one general-purpose interface.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Interfaces exist to decouple. Developers often have a misconception that implementation classes need interfaces. In fact, consumers need interfaces; implementation classes merely provide services. So interfaces should be defined by the consumer (the client). Only with this understanding can you correctly stand in the consumer’s shoes and define Role interfaces, instead of extracting Header interfaces from implementation classes.&lt;/p&gt;&lt;p&gt;For example, say we have a modern printer with print, scan, and fax capabilities. Extracting an interface directly from it like this produces a Header interface:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:42ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; abc &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PrinterInterface&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;print_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;scan_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fax_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, num: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;But here’s the problem: suppose we have an old printer that can only print — no scanning or faxing. The old printer is forced to depend on interface methods it doesn’t need, which violates the Interface Segregation Principle:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:75ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;OldPrinter&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PrinterInterface&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;print_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Printing document: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;doc&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;scan_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;NotImplementedError&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;This printer does not support scanning&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fax_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, num: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;NotImplementedError&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;This printer does not support faxing&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;We can’t guarantee that clients depending on this interface will never call the unsupported methods. So the right approach is to stand in the consumer’s shoes and abstract out Role interfaces:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:51ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; abc &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Printable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;print_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Scannable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;scan_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Faxable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fax_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, num: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;OldPrinter&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Printable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;print_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Printing document: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;doc&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ModernPrinter&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Printable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Scannable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Faxable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;print_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Printing document: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;doc&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;scan_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Scanning document&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;fax_doc&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, doc: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, num: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Sending fax: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;doc&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; to &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;num&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;With Role interfaces, the old printer and the modern printer — each a consumer — can consume exactly the interfaces they need.&lt;/p&gt;&lt;p&gt;In essence, the Interface Segregation Principle is itself an expression of the Single Responsibility Principle, and it serves the Liskov Substitution Principle in turn.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;d---dependency-inversion-principle&quot;&gt;D - Dependency Inversion Principle&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#d---dependency-inversion-principle&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote&gt;
&lt;p&gt;Depend upon abstractions, not concretions.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;This principle is really guidance on how to implement the Interface Segregation Principle, as mentioned earlier: high-level consumers should not depend on concrete implementations; consumers should define and depend on Role interfaces, and low-level concrete implementations should also depend on Role interfaces, since they implement those interfaces.&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_10&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;400&quot; height=&quot;86&quot; src=&quot;https://blog.ravenote.me/_astro/10.CbekbZ7F_Z2o5vhF.webp&quot; /&gt;
(Image source: A Simple DIP Example)&lt;/p&gt;&lt;p&gt;In the diagram above, when the Button directly switches the lamp on and off, the Button depends on the Lamp. That code is completely equivalent to procedural programming:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:39ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Lamp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;turn_on&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Lamp is ON&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;turn_off&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Lamp is OFF&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Button&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, lamp: Lamp):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.lamp &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; lamp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;press&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.lamp.turn_on()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;release&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.lamp.turn_off()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;lamp &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Lamp()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Button(lamp)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button.press()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Lamp is ON&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button.release()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Lamp is OFF&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;&lt;img alt=&quot;python_classes_and_oop_11&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;300&quot; height=&quot;219&quot; src=&quot;https://blog.ravenote.me/_astro/11.C2qzEDTu_ZcFLAD.webp&quot; /&gt;
(Image source: A Simple DIP Example)&lt;/p&gt;&lt;p&gt;What if the Button also needs to control a TV, or a microwave? The way to handle this kind of change is abstraction: abstract out a Role interface, &lt;code&gt;ButtonServer&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:45ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; abc &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ButtonServer&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;ABC&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;turn_on&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;@abstractmethod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;turn_off&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;pass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Lamp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ButtonServer&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;turn_on&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Lamp is ON&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;turn_off&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Lamp is OFF&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;TV&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ButtonServer&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;turn_on&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;TV is ON&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;turn_off&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;TV is OFF&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Button&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self, device: ButtonServer):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.device &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; device&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;press&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.device.turn_on()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;release&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(self):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;.device.turn_off()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;lamp &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Lamp()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;tv &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; TV()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button1 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Button(lamp)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button2 &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; Button(tv)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button1.press()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Lamp is ON&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button1.release()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: Lamp is OFF&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button2.press()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: TV is ON&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;button2.release()  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Output: TV is OFF&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Whether it’s a lamp or a TV, as long as it implements &lt;code&gt;ButtonServer&lt;/code&gt;, the &lt;code&gt;Button&lt;/code&gt; can control it. This is the object-oriented way of programming.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;dry&quot;&gt;DRY&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#dry&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;DRY stands for “Don’t repeat yourself”. When code is highly repetitive (for example, features built through lots of copy-paste), it’s time to think hard about whether there’s a better solution. In Python, decorators are usually the go-to tool for this kind of problem.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#summary&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Every best practice above boils down to two operations: “decouple” and “reuse”.&lt;/p&gt;&lt;p&gt;KISS emphasizes simplicity, and one of the main ways to achieve simplicity is to eliminate unnecessary complex dependencies through sensible decoupling, and to avoid repeated implementation through effective reuse. YAGNI reminds us that decoupling and reuse should be driven by actual requirements rather than speculation — don’t decouple for the sake of decoupling, or reuse for the sake of reuse. SOLID and DRY provide concrete guidelines for decoupling and reuse. And decoupling and reuse are themselves related: reuse requires decoupling — only when modules are fully decoupled from each other can they be effectively reused.&lt;/p&gt;&lt;p&gt;All these principles point to the same goal: building software systems that are maintainable, extensible, robust, and easy to understand.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;references&quot;&gt;References&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/python_classes_and_oop/#references&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;[Latest] &lt;a href=&quot;https://docs.python.org/3.12/tutorial/&quot;&gt;The Python Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Latest] &lt;a href=&quot;https://docs.python.org/3.12/reference&quot;&gt;The Python Language Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2015] &lt;a href=&quot;https://nostarch.com/python-crash-course-3rd-edition&quot;&gt;Python Crash Course, 3rd Edition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2011] &lt;a href=&quot;http://oreilly.com/catalog/errata.csp?isbn=9781449340377&quot;&gt;Python Cookbook, 3rd Edition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Unknown] &lt;a href=&quot;https://www.runoob.com/python3/python3-tutorial.html&quot;&gt;Runoob Python 3 Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2012] &lt;a href=&quot;https://pycoders-weekly-chinese.readthedocs.io/en/latest/issue6/a-guide-to-pythons-magic-methods.html&quot;&gt;A Guide to Python’s Magic Methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2006] &lt;a href=&quot;https://flylib.com/books/en/4.444.1.71/1/&quot;&gt;A Simple DIP Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[2018] Have you really understood SOLID after all these years of coding? By Mei Xuesong (URL no longer reachable): &lt;code&gt;hxxps://insights.thoughtworks.cn/what-is-solid-principle/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;[2009] Python Types and Objects By Shalabh Chaturvedi (URL no longer reachable): &lt;code&gt;hxxp://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;img alt=&quot;Not By AI&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;131&quot; height=&quot;42&quot; src=&quot;https://blog.ravenote.me/_astro/not-by-ai.BRg_BaJh_invcO.webp&quot; /&gt;&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>Useful Registry Keys (Continuously Updated)</title><link>https://blog.ravenote.me/en/posts/useful_registry_key/</link><guid isPermaLink="true">https://blog.ravenote.me/en/posts/useful_registry_key/</guid><description>Some genuinely useful registry keys</description><pubDate>Thu, 23 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote class=&quot;admonition bdm-warning&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;WARNING&lt;/span&gt;&lt;p&gt;Editing the registry carries risks — proceed with caution. Incorrect changes can cause serious system failures, or even require a full system reinstall.&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;admonition bdm-note&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;NOTE&lt;/span&gt;&lt;p&gt;Thanks to Disa for the additions.&lt;/p&gt;&lt;/blockquote&gt;
&lt;section&gt;&lt;h2 id=&quot;auto-start&quot;&gt;Auto-start&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#auto-start&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Run: runs at every boot.&lt;/li&gt;
&lt;li&gt;RunOnce: runs only once, then deletes itself after execution.&lt;/li&gt;
&lt;/ul&gt;&lt;section&gt;&lt;h3 id=&quot;user-level&quot;&gt;User-level&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#user-level&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:81ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_CURRENT_USER\Software\Microsoft\Windows&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;NT&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\C&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;urrentVersion&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\W&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;indows&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\l&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;oad&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;system-level&quot;&gt;System-level&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#system-level&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:82ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce\Setup&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;NT&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\C&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;urrentVersion&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\W&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;inlogon&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\U&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;serinit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\RunOnce&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;image-file-execution-options&quot;&gt;Image File Execution Options&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#image-file-execution-options&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3 id=&quot;image-hijacking&quot;&gt;Image hijacking&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#image-hijacking&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When you launch the target program, the hijacking program runs instead of the original one.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:91ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;NT&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\C&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;urrentVersion&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\I&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;mage&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Execution&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Option&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Create a subkey named after the target process, and inside it add a &lt;code&gt;debugger&lt;/code&gt; value set to the hijacking program.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;silentprocessexit&quot;&gt;SilentProcessExit&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#silentprocessexit&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When &lt;code&gt;ReportingMode&lt;/code&gt; is set to 1, the system runs the program specified in &lt;code&gt;MonitorProcess&lt;/code&gt; when the monitored process exits.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:81ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;NT&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\C&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;urrentVersion&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\S&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ilentProcessExit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Create a subkey named after the target process, add a &lt;code&gt;MonitorProcess&lt;/code&gt; value set to the hijacking program, and a &lt;code&gt;ReportingMode&lt;/code&gt; value set to 1.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;minimumstackcommitinbytes&quot;&gt;MinimumStackCommitInBytes&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#minimumstackcommitinbytes&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Setting &lt;code&gt;MinimumStackCommitInBytes&lt;/code&gt; to a large enough value makes the specified program crash with a stack overflow.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:135ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;NT&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\C&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;urrentVersion&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\I&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;mage&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Execution&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Options&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\[&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Target&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Process]&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\M&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;inimumStackCommitInBytes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;scheduled-tasks&quot;&gt;Scheduled Tasks&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#scheduled-tasks&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3 id=&quot;hierarchy-information&quot;&gt;Hierarchy information&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#hierarchy-information&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:87ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;NT&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\C&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;urrentVersion&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\S&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;chedule&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\T&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;askCache&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\T&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ree&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If the index is 0, the task is not visible in &lt;code&gt;taskschd.msc&lt;/code&gt;.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;task-details&quot;&gt;Task details&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#task-details&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:88ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;NT&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\C&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;urrentVersion&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\S&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;chedule&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\T&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;askCache&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\T&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;asks&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;deleting-files-after-reboot&quot;&gt;Deleting Files After Reboot&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/useful_registry_key/#deleting-files-after-reboot&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:95ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Manager&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\P&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;endingFileRenameOperations&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Each operation consists of a pair of strings:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;The first string is the path of the source file or directory.&lt;/li&gt;
&lt;li&gt;The second string is the path of the target file or directory (empty for a delete operation).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For example:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:18ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;\??\C:\OldFile.txt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;\??\C:\NewFile.txt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This renames C:\OldFile.txt to C:\NewFile.txt.&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>Unlocking BitLocker from the Command Line</title><link>https://blog.ravenote.me/en/posts/unlock_bitlocker_with_command_line/</link><guid isPermaLink="true">https://blog.ravenote.me/en/posts/unlock_bitlocker_with_command_line/</guid><description>Unlock BitLocker from the command line</description><pubDate>Fri, 20 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The commands below assume the drive to be unlocked is C, unlocked using the 48-digit recovery key.&lt;/p&gt;
&lt;p&gt;CMD:&lt;/p&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:100ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:1ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;manage-bde.exe&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-unlock&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;C:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-recoverypassword&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;PowerShell:&lt;/p&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:105ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:1ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Unlock-BitLocker&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-MountPoint&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;C&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-RecoveryPassword&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;</content:encoded></item><item><title>Basic Security Measures for a VPS</title><link>https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/</link><guid isPermaLink="true">https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/</guid><description>Essential security measures to take after you get a VPS</description><pubDate>Fri, 22 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This article is a self-reposted copy at: &lt;a href=&quot;https://linux.do/t/topic/267502&quot;&gt;https://linux.do/t/topic/267502&lt;/a&gt;&lt;/p&gt;
&lt;section&gt;&lt;h2 id=&quot;preface&quot;&gt;Preface&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#preface&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When you get your hands on a VPS, what should you do with it?&lt;/p&gt;&lt;p&gt;If you host your website or services on shared hosting from a reputable provider, the provider handles the basic server security. On a VPS, though, you are the one responsible for security. More privileges come with more responsibility — a VPS gives you far more freedom and, naturally, carries far more risk. &lt;strong&gt;The goal isn’t absolute security; it’s being more secure than most people.&lt;/strong&gt; If your server isn’t easy to break into, that’s a win.&lt;/p&gt;&lt;p&gt;This article is written for Ubuntu 24.04 LTS; the general ideas still apply to other distributions.&lt;/p&gt;&lt;p&gt;Before you continue, we recommend reading the material by &lt;a href=&quot;https://lug.ustc.edu.cn/&quot;&gt;LUG@USTC&lt;/a&gt;: &lt;a href=&quot;https://101.lug.ustc.edu.cn/&quot;&gt;https://101.lug.ustc.edu.cn/&lt;/a&gt;&lt;/p&gt;&lt;blockquote class=&quot;admonition bdm-note&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;NOTE&lt;/span&gt;&lt;p&gt;This article is unrelated to the &lt;a href=&quot;https://github.com/ustclug/Linux101-docs&quot;&gt;https://github.com/ustclug/Linux101-docs&lt;/a&gt; project.&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;account-security&quot;&gt;Account Security&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#account-security&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Some VPS providers hand you the root account by default. Root holds the highest privileges on the entire system, and leaving that much power exposed by default is naturally risky. The right approach is to create a non-root account and use sudo to elevate privileges only when root access is truly needed.&lt;/p&gt;&lt;section&gt;&lt;h3 id=&quot;create-a-non-root-account&quot;&gt;Create a Non-root Account&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#create-a-non-root-account&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Create an account that can elevate privileges with the following command:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:42ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;useradd&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-G&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/bin/bash&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&amp;lt;username&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Then set a password for this user — at least 16 characters of mixed upper/lowercase letters and digits (my personal minimum for acceptable security):&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:17ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;passwd&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&amp;lt;username&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;You should also change the root password. The default passwords on cloud servers are usually weak, and some providers even email the default credentials, which isn’t great for security.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;disable-root-password-login-over-ssh&quot;&gt;Disable Root Password Login over SSH&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#disable-root-password-login-over-ssh&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Leaving aside the fact that logging in as root is inherently risky, the root username is always “root” — if password login is allowed for it, an attacker only needs to brute-force the password to try to break into your system. Since we’ve already created a non-root account, we can simply disable SSH login for root.&lt;/p&gt;&lt;p&gt;Edit the SSH configuration file:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:29ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;vim&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Set the following:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:49ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Disable remote password login for the root user&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PermitRootLogin&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;prohibit-password&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Then restart the SSH service to apply the change:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:26ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;restart&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Why not set it to &lt;code&gt;no&lt;/code&gt;?&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;I don’t usually fully disable root login with &lt;code&gt;PermitRootLogin no&lt;/code&gt; either. I’m more used to setting up keys like any other sudoer and disabling password login entirely, allowing keys only. I only configure it that way on machines where I can operate the out-of-band cluster console; otherwise one failure could leave you without root — for example, if the disk fills up, you can’t even establish a remote SSH session.&lt;/p&gt;
&lt;p&gt;In theory &lt;code&gt;PermitRootLogin prohibit-password&lt;/code&gt; is fine, but it becomes a hassle when the server dies and you need rescue access. I’d actually recommend only disabling remote password login while keeping local password login, so you can still log in as root locally via VNC or IPMI to rescue the machine when something goes wrong.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;change-the-ssh-port&quot;&gt;Change the SSH Port&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#change-the-ssh-port&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;The very first thing is to move SSH off port 22.&lt;/p&gt;
&lt;p&gt;This is a supplement added on top of the original post.&lt;/p&gt;
&lt;p&gt;In practice, most people change the port as soon as they log in.&lt;/p&gt;
&lt;p&gt;The first thing I do after logging in is change the sshd port and update the firewall — port 22 gets nothing but password-guessing attempts.&lt;/p&gt;
&lt;p&gt;One trick: after changing the port and restarting sshd, your current connection stays alive. Try connecting to the new port — if it connects, the change worked. If you can’t establish a new connection, you can still revert the change or check your firewall configuration.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Normally, editing the SSH port via &lt;code&gt;sudo vim /etc/ssh/sshd_config&lt;/code&gt; and restarting with &lt;code&gt;sudo systemctl restart ssh.service&lt;/code&gt; is enough:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:18ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Set the SSH port&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&amp;lt;your-port&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;However, on &lt;strong&gt;Ubuntu 22.10 or newer&lt;/strong&gt; you may find this is &lt;strong&gt;ineffective&lt;/strong&gt; — after restarting, the SSH service still listens on the original port.&lt;/p&gt;&lt;p&gt;That’s because on Ubuntu 22.10 and newer, ssh is socket-activated by default.&lt;/p&gt;&lt;p&gt;On Ubuntu 22.10, Ubuntu 23.04, and Ubuntu 23.10, change it like this:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:53ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;mkdir&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/systemd/system/ssh.socket.d&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;vim&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/systemd/system/ssh.socket.d/listen.conf&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;daemon-reload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;restart&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh.socket&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;restart&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh.service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;A reference &lt;code&gt;listen.conf&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:17ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;[Socket]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;ListenStream&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;ListenStream&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;2233&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;On Ubuntu 24.04, change it like this:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:34ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;vim&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;daemon-reload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;restart&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh.service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If you don’t care about the memory saved by socket activation, you can revert to a non-socket-activated setup with the following commands:&lt;/p&gt;&lt;blockquote class=&quot;admonition bdm-warning&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;WARNING&lt;/span&gt;&lt;p&gt;Make sure your configuration files are correct first.&lt;/p&gt;&lt;/blockquote&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:39ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--now&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh.socket&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;enable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--now&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh.service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If you’re migrating a configuration (from Ubuntu 22.10 and above, below 24.04):&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:54ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--now&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh.socket&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;rm&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-f&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/systemd/system/ssh.service.d/00-socket.conf&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;rm&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-f&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/systemd/system/ssh.socket.d/addresses.conf&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;daemon-reload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;enable&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--now&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh.service&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Instead of editing &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; directly, it’s better to create a conf file under &lt;code&gt;/etc/ssh/sshd_config.d/&lt;/code&gt; for your custom sshd settings. This prevents configuration conflicts after an OpenSSH update.&lt;/p&gt;&lt;p&gt;Reference: &lt;a href=&quot;https://unix.stackexchange.com/questions/727492/passwordauthentication-no-but-i-can-still-login-by-password/727500#727500&quot;&gt;ssh - PasswordAuthentication no, but I can still login by password - Unix &amp;amp; Linux Stack Exchange&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Some cloud providers drop their own conf file into &lt;code&gt;/etc/ssh/sshd_config.d/&lt;/code&gt; to enable remote password login (sshd disables it by default). Rule those out before modifying any sshd settings:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:74ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Check whether sshd_config.d contains other conf files&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ls&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/ssh/sshd_config.d/&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;.conf&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# If so, rename them so your custom config isn&apos;t overridden&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;mv&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/ssh/sshd_config.d/xxx.conf/etc/ssh/sshd_config.d/xxx.conf.bak&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;CloudCone, for example, ships a &lt;code&gt;/etc/ssh/sshd_config.d/50-cloud-init.conf&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;After changing sshd settings, run &lt;code&gt;sudo sshd -T&lt;/code&gt; first to inspect the effective configuration, so you’re not blindsided by an override :joy:.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:47ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# How root is allowed to log in&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;sshd&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-T&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;grep&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-i&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;PermitRootLogin&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Password authentication&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;sshd&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-T&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;grep&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-i&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;PasswordAuthentication&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# SSH port&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;sshd&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-T&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;grep&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-i&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Port&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Worth noting: &lt;code&gt;prohibit-password&lt;/code&gt; is an alias of &lt;code&gt;without-password&lt;/code&gt;, so seeing the output below is perfectly normal.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:42ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;sshd&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-T&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;grep&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-i&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;PermitRootLogin&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;permitrootlogin&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;without-password&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;References:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://unix.stackexchange.com/questions/99307/permit-root-to-login-via-ssh-only-with-key-based-authentication/99308#99308&quot;&gt;Permit root to login via ssh only with key-based authentication - Unix &amp;amp; Linux Stack Exchange&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.openssh.com/txt/release-7.0&quot;&gt;OpenSSH 7.0 Release Notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;protect-ssh-from-brute-force-with-fail2ban&quot;&gt;Protect SSH from Brute Force with Fail2ban&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#protect-ssh-from-brute-force-with-fail2ban&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Install Fail2ban:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:25ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;apt&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;install&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;fail2ban&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The officially recommended approach is to customize settings via jail.local:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:33ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;vim&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/fail2ban/jail.local&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Use the following config as a starting point for your own (remember to remove the comments):&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:159ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;[sshd]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ignoreip&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;127.0.0.1/8&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Whitelist&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;enabled&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;sshd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;22&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Port; update this if you changed the SSH port&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;maxretry&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Maximum number of attempts&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;findtime&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Window in seconds within which maxretry applies&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;bantime&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;600&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Ban duration in seconds; -1 is a permanent ban (not recommended)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;action&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;action_&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [port=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;%(port) s&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;protocol=&quot;%(protocol) s&quot;,&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;logpath=&quot;%(logpath) s&quot;,&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;chain=&quot;%(chain) s&quot;]&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Use this if you don&apos;t need email notifications&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;banaction&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;iptables-multiport&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Ban method&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;logpath&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/var/log/auth.log&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# SSH login log location&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;ssh-login-notifications&quot;&gt;SSH Login Notifications&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#ssh-login-notifications&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;Very useful. I also added a WeCom bot notification that fires automatically on every SSH login, so I’d know right away if someone got in.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;You can use a PAM module to trigger a script on every SSH login.&lt;/p&gt;&lt;p&gt;Edit &lt;code&gt;/etc/pam.d/sshd&lt;/code&gt; and append:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:50ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;session&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;optional&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;pam_exec.so&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/path/to/script&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;For the use case above, the script looks roughly like this:
Reference: &lt;a href=&quot;https://developer.work.weixin.qq.com/document/path/91770&quot;&gt;https://developer.work.weixin.qq.com/document/path/91770&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Note (Nov 26, 2024): Fixed some issues in the example script.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:97ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [ &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$PAM_TYPE&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;open_session&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ]; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;then&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;exit&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;fi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;ip&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$PAM_RHOST&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;date&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;date&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;+&quot;% e % b % Y, % a % r&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$PAM_USER&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;webhook_url&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxxxxxx&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-X&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;POST&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$webhook_url&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-H&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;msgtype&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;markdown&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;markdown&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;**Login Alert**&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;n&amp;gt; User: &lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$name&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;n&amp;gt; Client IP: &lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$ip&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;n&amp;gt; Login time: &lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$date&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;}&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Replace the API key and delivery method with whatever fits your own use case.&lt;/p&gt;&lt;p&gt;Once the script is written, make it executable:&lt;/p&gt;&lt;p&gt;&lt;code&gt;sudo chmod +x /usr/local/bin/notify_ssh_login.sh&lt;/code&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;strict-run-commands-with-absolute-paths&quot;&gt;[Strict] Run Commands with Absolute Paths&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#strict-run-commands-with-absolute-paths&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Using absolute paths pins down exactly which program or file runs, so a tampered environment variable can’t trick you into executing a potentially malicious program.&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Using the full path to su avoids running a fake su planted by an attacker.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;log-in-with-ssh-keys&quot;&gt;Log In with SSH Keys&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#log-in-with-ssh-keys&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote class=&quot;admonition bdm-tip&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;TIP&lt;/span&gt;&lt;p&gt;If your VPS provider offers SSH key binding, you can skip this section and follow the provider’s method.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Run this in PowerShell:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:21ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssh-keygen&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-t&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ed25519&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Just accept the default key path. You can leave the passphrase empty or set one.&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:106ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Generating&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;public/private&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ed25519&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;pair.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Enter&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;which&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;the&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (C:&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\U&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;sers&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\&amp;lt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;user&amp;gt;/.ssh/id_ed25519): &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Press Enter to accept the default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Enter&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;passphrase&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (empty &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;no&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;passphrase&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;): &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Leave empty or set a passphrase&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;Enter&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;same&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;passphrase&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;again:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Same as above&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Then edit the authorized keys file on the VPS:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:26ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;vim&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;~/.ssh/authorized_keys&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Next, open C:\Users&amp;lt;user&amp;gt;/.ssh/id_ed25519.pub, copy its contents, and paste them in.&lt;/p&gt;&lt;p&gt;Edit the SSH configuration file:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:29ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;vim&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/ssh/sshd_config&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Set the following:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:39ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PubkeyAuthentication&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;yes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;AuthorizedKeysFile&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;.ssh/authorized_keys&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PasswordAuthentication&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;no&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Then restart the SSH service to apply the change:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:26ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;restart&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;enable-the-ufw-firewall&quot;&gt;Enable the UFW Firewall&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#enable-the-ufw-firewall&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote class=&quot;admonition bdm-tip&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;TIP&lt;/span&gt;&lt;p&gt;If your VPS provider offers a firewall and you don’t have complex requirements, you can skip this section and use the provider’s firewall.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Before enabling UFW, we need to set up rules first. Let’s start with UFW’s default policies:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:71ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;default&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;outgoing&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Allow all outbound traffic by default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;default&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;incoming&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Deny all inbound traffic by default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;View the currently active UFW rules:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:51ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;status&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;numbered&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Show rules with numbers&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Allow or deny traffic on a port with the following commands (22, 80, and 443 used as examples):&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:67ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Allow inbound traffic on port 22/proto&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;22/proto&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Allow outbound traffic on port 22/proto&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;out&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;22/proto&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Without specifying in/out, it defaults to in&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;22/proto&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Without specifying a protocol, both tcp and udp are allowed&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# To deny instead, change allow to deny&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Allow a port range from start_port to end_port&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;start_port:end_port&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Allow multiple ports, comma-separated&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port1,port2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Allow traffic from a specific IP or CIDR range&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ip/cidr&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Allow traffic from a specific IP or CIDR range to port 22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ip/cidr&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Allow tcp traffic from a specific IP or CIDR range to port 22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ip/cidr&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# If you specify multiple ports, you must specify the protocol&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ip&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;80,443&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# comment adds a description to the rule&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ip&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;80,443&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;comment&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Delete active rules with:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:70ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;22&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Prefix the rule with delete&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Or delete by the number from &quot;ufw status numbered&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Once all rules are in place, start, stop, or reload UFW:&lt;/p&gt;&lt;blockquote class=&quot;admonition bdm-warning&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;WARNING&lt;/span&gt;&lt;p&gt;Before enabling the firewall, make sure port 22 (or whatever your SSH port is) is allowed.&lt;/p&gt;&lt;/blockquote&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:30ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;enable&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;reload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;To reset all rules:&lt;/p&gt;&lt;blockquote class=&quot;admonition bdm-warning&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;WARNING&lt;/span&gt;&lt;p&gt;Make sure UFW is disabled before resetting the rules.&lt;/p&gt;&lt;/blockquote&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:14ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;reset&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;My advice: only allow the ports you actually use, such as 22, 80, and 443.&lt;/p&gt;&lt;p&gt;By default, UFW only logs dropped packets that don’t match a rule. If you want detailed logging for a service, add &lt;code&gt;log&lt;/code&gt; after &lt;code&gt;allow&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:52ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# Log successful SSH connections too, for the record&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;22/tcp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;block-ping&quot;&gt;Block Ping&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#block-ping&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4 id=&quot;block-ping-with-iptables&quot;&gt;Block Ping with iptables&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#block-ping-with-iptables&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Check current iptables rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;iptables -L -n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;This lists the current iptables rules: &lt;code&gt;-L&lt;/code&gt; lists the rules, and &lt;code&gt;-n&lt;/code&gt; displays IP addresses and port numbers numerically instead of resolving them to hostnames and service names.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Block ping (inbound ICMP Echo Request):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;iptables -A INPUT -p icmp --icmp-type 8 -j DROP&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Here, &lt;code&gt;-A INPUT&lt;/code&gt; appends a rule to the end of the INPUT chain (which handles packets destined for this machine). &lt;code&gt;-p icmp&lt;/code&gt; specifies the ICMP protocol, &lt;code&gt;--icmp-type 8&lt;/code&gt; is ICMP type 8 (Echo Request), and &lt;code&gt;-j DROP&lt;/code&gt; drops matching packets.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Save iptables rules (if you want them to persist):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to save iptables rules differs between Linux distributions.&lt;/li&gt;
&lt;li&gt;On RHEL-based systems like CentOS, use the &lt;code&gt;service iptables save&lt;/code&gt; command. It writes the current rules to &lt;code&gt;/etc/sysconfig/iptables&lt;/code&gt; so they survive a reboot.&lt;/li&gt;
&lt;li&gt;On Debian-based systems like Ubuntu, install the &lt;code&gt;iptables-persistent&lt;/code&gt; package. After installation, use &lt;code&gt;iptables-save &amp;gt; /etc/iptables/rules.v4&lt;/code&gt; (for IPv4 rules) to save the rules so they’re restored after a reboot.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Restore ping&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;To restore ping, delete the rule you just added with the &lt;code&gt;iptables -D INPUT -p icmp --icmp-type 8 -j DROP&lt;/code&gt; command. &lt;code&gt;-D INPUT&lt;/code&gt; removes a rule from the INPUT chain; the other parameters are the same as when adding the rule.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;block-ping-with-ufw&quot;&gt;Block Ping with UFW&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#block-ping-with-ufw&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;blockquote class=&quot;admonition bdm-note&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;NOTE&lt;/span&gt;&lt;p&gt;To err on the side of caution, the rules related to destination-unreachable, time-exceeded, and parameter-problem have been removed.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;UFW has no direct command for blocking the icmp protocol. UFW defines allow rules for ping in &lt;code&gt;/etc/ufw/before.rules&lt;/code&gt;; change &lt;code&gt;ACCEPT&lt;/code&gt; to &lt;code&gt;DROP&lt;/code&gt; there to block ping:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:62ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-before-input&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;icmp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--icmp-type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;echo-request&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DROP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-before-forward&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;icmp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--icmp-type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;echo-request&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DROP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Heads-up: this only blocks IPv4 — the box is still pingable over IPv6.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;To block ping over IPv6 as well, edit &lt;code&gt;/etc/ufw/before6.rules&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:66ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw6-before-output&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;icmpv6&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--icmpv6-type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;echo-request&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DROP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw6-before-output&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;icmpv6&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--icmpv6-type&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;echo-reply&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DROP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!INFO]
Leave the remaining icmpv6 rules unchanged.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;restrict-ssh-access-by-ip&quot;&gt;Restrict SSH Access by IP&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#restrict-ssh-access-by-ip&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;My office network has a static IP, so I open port 22 in the VPS provider’s firewall and restrict it to that IP. Whenever I need access from another IP, I just add it.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;If you have a dynamic public IP and your provider offers an API for modifying firewall rules, you can use that directly.&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;If you don’t have a static IP at home, you can use a web terminal like Tencent Cloud’s &lt;a href=&quot;https://orcaterm.cloud.tencent.com/&quot;&gt;orcaterm&lt;/a&gt; — the basic features are free forever. Here are &lt;a href=&quot;https://www.tencentcloud.com/zh/document/product/213/39708?lang=zh&quot;&gt;orcaterm’s IP ranges&lt;/a&gt;; load them into ipset and allow only those IPs to reach the SSH port. Test that the connection actually works before applying the rule. If you’re a Tencent Cloud user, you can even drop the SSH port entirely in the security group — when I used Tencent Cloud, I only opened ports 80 and 443.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;You can also do this with UFW.&lt;/p&gt;&lt;p&gt;Or use the firewall provided by your VPS provider (if supported) — it’s easier to adjust when you run into connectivity problems.&lt;/p&gt;&lt;p&gt;Steps for adding servers from other providers to &lt;a href=&quot;https://orcaterm.cloud.tencent.com/&quot;&gt;orcaterm&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;step1&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;238&quot; height=&quot;140&quot; src=&quot;https://blog.ravenote.me/_astro/2.d8X4qZeC_Z2iqFjA.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;step2&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;261&quot; height=&quot;128&quot; src=&quot;https://blog.ravenote.me/_astro/3.C6bpo-WZ_1YX0K6.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;step3&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;513&quot; height=&quot;500&quot; src=&quot;https://blog.ravenote.me/_astro/4.DYPxqVhQ_Z1zXFHx.webp&quot; /&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;keep-software-updated&quot;&gt;Keep Software Updated&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#keep-software-updated&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3 id=&quot;update-regularly&quot;&gt;Update Regularly&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#update-regularly&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;My advice is to log into your VPS periodically and run &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;/code&gt; to keep every package up to date.&lt;/p&gt;&lt;p&gt;That said, Ubuntu installs security updates automatically every day by default, so you don’t need to do this too often.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;enable-ubuntu-pro&quot;&gt;Enable Ubuntu Pro&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#enable-ubuntu-pro&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;The same great OS, with more security updates
Reducing the average CVE (Common Vulnerabilities and Exposures) exposure time from 98 days to 1 day
Extended CVE patching, ten years of security maintenance, optional support, and maintenance for your entire open-source application stack&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;That’s Ubuntu’s official marketing copy. I can’t tell you exactly how useful it is, but a fix is better than no fix — and it’s free for up to 5 machines for personal use, so enabling it costs you nothing.&lt;/p&gt;&lt;p&gt;First, create an Ubuntu One account: &lt;a href=&quot;https://ubuntu.com/login&quot;&gt;https://ubuntu.com/login&lt;/a&gt;&lt;/p&gt;&lt;p&gt;After registering, go to &lt;a href=&quot;https://ubuntu.com/pro/dashboard&quot;&gt;https://ubuntu.com/pro/dashboard&lt;/a&gt; to find your token.&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;Ubuntu Pro&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;690&quot; height=&quot;435&quot; src=&quot;https://blog.ravenote.me/_astro/1.BmcbaFET_Z1UXzVI.webp&quot; /&gt;&lt;/p&gt;&lt;p&gt;Once you have your token, head to the VPS and run &lt;code&gt;sudo pro attach [YOUR_TOKEN]&lt;/code&gt;. After a short wait, Ubuntu Pro is enabled. I’d recommend running &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;/code&gt; once more afterwards to make sure the latest security updates are installed.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;hide-the-public-ip&quot;&gt;Hide the Public IP&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#hide-the-public-ip&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Hiding the public IP isn’t a security requirement shared by every VPS user. One off-the-cuff idea for the future (once IPv6 is widely deployed) is to expose only the origin’s IPv6 address to the CDN — mass scanners like Censys would take a very long time to sweep it. You’d still want an allowlist, though.&lt;/p&gt;
&lt;/blockquote&gt;&lt;section&gt;&lt;h3 id=&quot;stop-ssl-certificates-from-leaking-your-ip&quot;&gt;Stop SSL Certificates from Leaking Your IP&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#stop-ssl-certificates-from-leaking-your-ip&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;This section, “Stop SSL Certificates from Leaking Your IP,” is quoted from “How to Prevent Certificates from Leaking Your Origin IP” by Qiu Weimeng, published under the CC BY-SA 4.0 license. The rest of this article is published under the CC BY-NC-SA 4.0 license, but this section uses the CC BY-SA 4.0 license.&lt;/p&gt;
&lt;/blockquote&gt;&lt;section&gt;&lt;h4 id=&quot;apply-for-and-download-a-certificate&quot;&gt;Apply for and Download a Certificate&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#apply-for-and-download-a-certificate&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Sign up and log in to &lt;a href=&quot;https://app.zerossl.com/login&quot;&gt;ZeroSSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Go to the &lt;a href=&quot;https://app.zerossl.com/dashboard&quot;&gt;Dashboard&lt;/a&gt;, find “Create SSL Certificate,” and click the blue “New Certificate” button&lt;/li&gt;
&lt;li&gt;Enter your origin IP under “Enter Domains”&lt;/li&gt;
&lt;li&gt;Expiry doesn’t really matter — the point is to keep Censys from scanning a real certificate for your domain. So choose a 90-day certificate&lt;/li&gt;
&lt;li&gt;Leave CSR &amp;amp; Contact unchanged&lt;/li&gt;
&lt;li&gt;Choose “HTTP File Upload” as the domain validation method
&lt;ul&gt;
&lt;li&gt;If you use NGINX and haven’t touched &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt;, you’re fine. Of course, if you’ve changed it, just make sure a &lt;code&gt;server {listen 80; root /var/www/html;}&lt;/code&gt; block remains&lt;/li&gt;
&lt;li&gt;Then download the Auth File and upload it to &lt;code&gt;/var/www/html/.well-known/pki-validation&lt;/code&gt;. Create the folder if it doesn’t exist, and make sure NGINX can access these files, or validation will still fail&lt;/li&gt;
&lt;li&gt;As prompted, click the &lt;code&gt;.txt&lt;/code&gt; file to check whether it’s accessible. If it loads, validation is done&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;configure-the-certificate-and-block-ip-based-http-access-on-ports-80443&quot;&gt;Configure the Certificate and Block IP-Based HTTP Access on Ports 80/443&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#configure-the-certificate-and-block-ip-based-http-access-on-ports-80443&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Download the &lt;code&gt;*.zip&lt;/code&gt; file and extract it. The extracted folder contains the certificate you applied for&lt;/li&gt;
&lt;li&gt;Merge &lt;code&gt;ca_bundle.crt&lt;/code&gt; and &lt;code&gt;certificate.crt&lt;/code&gt;: open &lt;code&gt;certificate.crt&lt;/code&gt; in a reliable editor such as notepad3 or VSCode, then paste the contents of &lt;code&gt;ca_bundle.crt&lt;/code&gt; into it. The format is:&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:27ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-----BEGIN&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;CERTIFICATE-----&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;contents&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;certificate.crt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-----END&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;CERTIFICATE-----&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-----BEGIN&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;CERTIFICATE-----&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;contents&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;of&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ca_bundle.crt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-----END&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;CERTIFICATE-----&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Upload the merged file and &lt;code&gt;private.key&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Upload the certificate to a folder NGINX can access — we put it in &lt;code&gt;/etc/nginx/ip-certificate/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Configure &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt;. Reference config:&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:71ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;#HTTP Server Default Set&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;listen&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;80&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;listen&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;443&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;http2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;default_server&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;server_name&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ip&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;#HTTP_TO_HTTPS_END&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_certificate&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/nginx/ip-certificate/certificate.crt&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_certificate_key&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/nginx/ip-certificate/private.key&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_protocols&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;TLSv1.1&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;TLSv1.2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;TLSv1.3&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_ciphers&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_prefer_server_ciphers&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_session_cache&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;shared:SSL:10m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_session_timeout&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;10m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;#Server ROOT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;index.html&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;root&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/var/www/html/&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;index.html&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;444&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;#NGINX HTPP Code 444&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Run &lt;code&gt;nginx -t&lt;/code&gt; on the server to check for errors; if it’s valid, restart with &lt;code&gt;sudo systemctl restart nginx&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Type your IP directly into a browser and check whether the connection immediately turns into a blank page.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;the-newer-method-nginx-1194&quot;&gt;The Newer Method (Nginx 1.19.4+)&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#the-newer-method-nginx-1194&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If your Nginx version is 1.19.4 or newer, you can use the &lt;code&gt;ssl_reject_handshake&lt;/code&gt; directive to reject every TLS handshake that doesn’t match a configured domain:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:34ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;listen&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;443&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ssl&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;default_server&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;server_name&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_reject_handshake&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If you get an error like &lt;code&gt;nginx: [emerg] unknown directive &quot;ssl_reject_handshake&quot;&lt;/code&gt;, first check whether your Nginx version is at least 1.19.4 — &lt;code&gt;ssl_reject_handshake on;&lt;/code&gt; was added in Nginx 1.19.4 (mainline).&lt;/p&gt;&lt;p&gt;If you compiled Nginx from source, make sure the &lt;code&gt;ngx_http_ssl_module&lt;/code&gt; module is enabled. It isn’t built by default; you need the &lt;code&gt;--with-http_ssl_module&lt;/code&gt; configure option.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;are-we-safe-now&quot;&gt;Are We Safe Now?&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#are-we-safe-now&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In the previous sections, we only ensured that an attacker can’t fetch a default certificate by visiting your IP directly and infer your domain from it. Nothing says an attacker has to learn IP-to-domain mappings that way, though. As you can see, the rules above all rely on &lt;code&gt;server_name&lt;/code&gt; matching. An attacker could easily walk through every non-CDN IP range carrying the correct &lt;code&gt;server_name&lt;/code&gt;, recording which targets respond correctly. Here’s a simple implementation of that check (without the scanning part):&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;python&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:82ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# https://gist.github.com/Raven95676/39ffdba22144e39d7155ad9dc1bcca55&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ssl&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; socket&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;check&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (ip, domain):&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;try&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;context &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ssl.create_default_context ()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:9ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;         &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;with&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; socket.create_connection ((ip, &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;443&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; sock:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;with&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; context.wrap_socket (sock, &lt;/span&gt;&lt;span style=&quot;--0:#FFAB70;--1:#FFAB70&quot;&gt;server_hostname&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;domain) &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ssl_sock:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:16ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;request &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;GET / HTTP/1.1&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Host: &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;domain&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;}\n&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Connection: close&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;\n\n&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:16ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;ssl_sock.sendall (request.encode ())&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:16ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;ssl_sock.recv (&lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;4096&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;True&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;except&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;Exception&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;False&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (check (&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;192.168.0.256&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;example.com&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;patching-it-up&quot;&gt;Patching It Up&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#patching-it-up&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote class=&quot;admonition bdm-tip&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;TIP&lt;/span&gt;&lt;p&gt;If your VPS provider offers a firewall, you can just use the provider’s firewall.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;You can just use this method&lt;/p&gt;&lt;p&gt;We can allow only the CDN’s CIDR ranges to reach ports 80/443 on the server. First, add the allow rules:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:84ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;CIDR range&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;80,443&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;comment&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;CDN provider&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;The comment isn’t required — it’s just so you can recognize what the rule is for later.&lt;/p&gt;&lt;p&gt;Ask your CDN provider for its CIDR ranges — some publish them on their website. For example, Cloudflare’s CIDR ranges are available at: &lt;a href=&quot;https://www.cloudflare.com/ips-v4&quot;&gt;https://www.cloudflare.com/ips-v4&lt;/a&gt;&lt;/p&gt;&lt;p&gt;That’s the IPv4 list; the IPv6 one is at: &lt;a href=&quot;https://www.cloudflare.com/ips-v6&quot;&gt;https://www.cloudflare.com/ips-v6&lt;/a&gt;&lt;/p&gt;&lt;p&gt;For Cloudflare, a community member also wrote a script that syncs Cloudflare’s IPs into UFW for port 443 when run:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:147ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;RULES&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;numbered&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;grep&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;Cloudflare IP&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;awk&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-F&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;[][]&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;{print $2}&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sort&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-nr&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; RULE &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; $RULES; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;do&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;Deleting rule &lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$RULE&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; $RULE&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;done&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; cfip &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-sw&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; &apos;\n&apos; https://www.cloudflare.com/ips-v {4,6}`&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;do&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; $cfip &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;443&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;comment&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&apos;Cloudflare IP&apos;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;done&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;reload&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/dev/null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Because of the special circumstances involved, I’d suggest running the following command first to check that the output is correct before deploying the script:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:87ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; cfip &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-sw&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; &apos;\n&apos; https://www.cloudflare.com/ips-v {4,6}`&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;do&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; $cfip; &lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;done&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If the output looks right (like below), you can deploy it:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:15ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;173.245.48.0/20&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;103.21.244.0/22&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;…&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (omitted)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;2400:cb00::/32&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;2606:4700::/32&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;…&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (omitted)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;After adding the rules, list the current firewall rules:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:24ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;numbered&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Delete any pre-existing rules that allow all traffic on ports 80 and 443:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:24ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;delete&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&amp;lt;number&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Why not just use Nginx’s &lt;code&gt;deny&lt;/code&gt; directive? Because &lt;code&gt;deny&lt;/code&gt; returns a 403 Forbidden status code — and before it can, the TLS handshake must complete. Only after a successful TLS handshake can the client send an HTTP request and receive a response. So using &lt;code&gt;deny&lt;/code&gt; directly here would be doing pointless work.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;are-we-really-safe&quot;&gt;Are We Really Safe…?&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#are-we-really-safe&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This is really a Cloudflare special, but the ideas apply to other CDN providers too if you want extra security. Cloudflare offers more than CDN services — there’s a whole lineup of products like Workers and WARP. Some of these services have characteristics worth noting:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;They can make outbound requests&lt;/li&gt;
&lt;li&gt;They use Cloudflare’s IP ranges&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Cloudflare certainly restricts abuse, but just in case, we can take one more security measure — Authenticated Origin Pulls.&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;[!INFO]
Make sure the SSL/TLS encryption mode is set to Full or Full (strict).&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Download the &lt;a href=&quot;https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem&quot;&gt;Cloudflare certificate&lt;/a&gt; and configure it:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:48ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_client_certificate&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/path/to/certificate.pem&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ssl_verify_client&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Then enable Authenticated Origin Pulls under SSL/TLS → Origin Server.&lt;/p&gt;&lt;p&gt;The SafeLine WAF community edition can’t stably use this method yet, unless you’re willing to put another reverse proxy in front of it.&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;moving-toward-full-containerization&quot;&gt;Moving Toward Full Containerization&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#moving-toward-full-containerization&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;My advice: make good use of containerization for isolation.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;This section doesn’t cover server panels like 1Panel or Docker panels like Portainer.&lt;/p&gt;&lt;section&gt;&lt;h3 id=&quot;docker-basics&quot;&gt;Docker Basics&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#docker-basics&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote class=&quot;admonition bdm-note&quot;&gt;&lt;span class=&quot;bdm-title&quot;&gt;NOTE&lt;/span&gt;&lt;p&gt;There’s mature documentation available, so I won’t reinvent the wheel.&lt;/p&gt;&lt;p&gt;This article is unrelated to the &lt;a href=&quot;https://github.com/yeasy/docker_practice&quot;&gt;https://github.com/yeasy/docker_practice&lt;/a&gt; project.&lt;/p&gt;&lt;p&gt;Just being a little lazy&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Side note: if &lt;code&gt;docker-compose&lt;/code&gt; says the command isn’t found, try &lt;code&gt;docker compose&lt;/code&gt;. The &lt;code&gt;version&lt;/code&gt; field is deprecated in docker compose — it will be ignored with a warning in existing compose files.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://yeasy.gitbook.io/docker_practice&quot;&gt;https://yeasy.gitbook.io/docker_practice&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Update: added the official Chinese Docker documentation.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://docs.docker.net.cn/manuals/&quot;&gt;https://docs.docker.net.cn/manuals/&lt;/a&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;when-ufw-cant-control-docker-recommended&quot;&gt;When UFW Can’t Control Docker (Recommended)&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#when-ufw-cant-control-docker-recommended&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;One more thing about Docker: you don’t really need UFW to manage which ports Docker exposes — Docker writes its own iptables rules to control them. Using docker compose as an example:&lt;/p&gt;
&lt;/blockquote&gt;&lt;section&gt;&lt;h4 id=&quot;1-for-services-used-only-within-the-app-databases-redis-etc&quot;&gt;1. For Services Used Only Within the App (Databases, Redis, etc.)&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#1-for-services-used-only-within-the-app-databases-redis-etc&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Only expose them on the internal container network. When compose brings up the stack, it creates a bridge named &lt;code&gt;&amp;lt;first-service-name&amp;gt;_default&lt;/code&gt;, which you can see with &lt;code&gt;docker network ls&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Containers expose all their ports on this internal network by default.&lt;/li&gt;
&lt;li&gt;Other containers on the same network can reach the service by container name and port.&lt;/li&gt;
&lt;li&gt;Containers not attached to that network can’t access any of its ports.&lt;/li&gt;
&lt;li&gt;For services only exposed on the internal network, &lt;strong&gt;no&lt;/strong&gt; port mapping is needed under &lt;code&gt;ports&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;2-for-services-behind-a-reverse-proxy&quot;&gt;2. For Services Behind a Reverse Proxy&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#2-for-services-behind-a-reverse-proxy&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Binding to 127.0.0.1 only keeps the port from being reachable from outside; use this on the container in question:&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;yaml&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:29ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#85E89D;--1:#85E89D&quot;&gt;ports&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;127.0.0.1:&amp;lt;port&amp;gt;:&amp;lt;port&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4 id=&quot;3-for-services-that-need-direct-external-port-access&quot;&gt;3. For Services That Need Direct External Port Access&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#3-for-services-that-need-direct-external-port-access&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;Map the port directly:&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:21ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ports:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:6ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&amp;lt;port&amp;gt;:&amp;lt;port&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;And here’s an example compose.yml:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:73ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;services:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;rsshub:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;image:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;diygod/rsshub:latest&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;restart:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;always&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ports:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;127.0.0.1:1200:1200&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;environment:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;NODE_ENV:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;production&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;CACHE_TYPE:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;redis&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;REDIS_URL:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;redis://redis:6379/&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;PUPPETEER_WS_ENDPOINT:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;ws://browserless:3000&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;env_file:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;.env&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;healthcheck:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;CMD&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;curl&quot;,&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;-f&quot;,&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;http://localhost:1200/healthz&quot;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;interval:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;30s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;timeout:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;10s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;retries:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;depends_on:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;redis&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;browserless&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;browserless:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;image:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;browserless/chrome&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;restart:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;always&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ulimits:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;core:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:16ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;hard:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:16ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;soft:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;healthcheck:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;CMD&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;curl&quot;,&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;-f&quot;,&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;http://localhost:3000/pressure&quot;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;interval:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;30s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;timeout:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;10s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;retries:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;redis:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;image:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;redis:alpine&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;restart:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;always&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;volumes:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;./data:/data&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;healthcheck:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;CMD&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;redis-cli&quot;,&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;ping&quot;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;interval:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;30s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;timeout:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;10s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;retries:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;start_period:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;5s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;sb:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;image:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ghcr.io/sagernet/sing-box&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;container_name:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;sb&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;51&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;restart:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;always&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;volumes:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:12ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;53&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;./sing-box:/etc/sing-box/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;54&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;command&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-D&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/var/lib/sing-box&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-C&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;/etc/sing-box/run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Additionally, if you need to keep external ports blocked, besides binding to 127.0.0.1 there’s another option:&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;For services that need a reverse proxy (Nginx/Caddy, etc.), configure a Docker-private IP starting with 172 in the Compose file and don’t configure a port. This way Docker won’t expose any public port, and the reverse proxy can just point at the private IP and its default port.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;For example, this MySQL Compose file assigns the private IP &lt;code&gt;172.20.0.15&lt;/code&gt; and comments out the port mapping; when configuring the reverse proxy, simply proxy to &lt;code&gt;172.20.0.15:3306&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:33ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;networks:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:2ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;default:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;external:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;name:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; ${DOCKER_MY_NETWORK}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;services:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:2ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;mysql:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;container_name:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;mysql8&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;image:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;mysql:8&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# ports:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;#   - &quot;3306:3306&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;environment:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:6ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;TZ:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;Asia/Shanghai&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;networks:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:6ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;default:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:8ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ipv4_address:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;172.20.0.15&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot; style=&quot;--ecIndent:4ch&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;restart:&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;unless-stopped&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;when-ufw-cant-control-docker-not-recommended&quot;&gt;When UFW Can’t Control Docker (Not Recommended)&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#when-ufw-cant-control-docker-not-recommended&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;This section, “When UFW Can’t Control Docker (Not Recommended),” is quoted from the README of the project &lt;strong&gt;&lt;a href=&quot;https://github.com/chaifeng/ufw-docker&quot;&gt;ufw-docker&lt;/a&gt;&lt;/strong&gt; by &lt;a href=&quot;https://github.com/chaifeng&quot;&gt;chaifeng&lt;/a&gt;, released under the GPL-3.0 license. The rest of this article is published under the CC BY-NC-SA 4.0 license, but this section uses the GPL-3.0 license.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;The current new solution only requires modifying one UFW config file; keep all of Docker’s own config and options at their defaults.&lt;/p&gt;&lt;p&gt;Edit UFW’s config file &lt;code&gt;/etc/ufw/after.rules&lt;/code&gt; and append the following rules:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:107ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# BEGIN UFW AND DOCKER&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;filter&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;:ufw-user-forward&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [0:0]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;:ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [0:0]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;:DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; [0:0]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-user-forward&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;RETURN&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;10.0.0.0/8&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;RETURN&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;172.16.0.0/12&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;RETURN&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-s&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;192.168.0.0/16&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--sport&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;53&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--dport&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;1024:65535&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;RETURN&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--tcp-flags&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;FIN,SYN,RST,ACK&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;SYN&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;192.168.0.0/16&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--tcp-flags&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;FIN,SYN,RST,ACK&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;SYN&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;10.0.0.0/8&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--tcp-flags&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;FIN,SYN,RST,ACK&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;SYN&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;172.16.0.0/12&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--dport&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;0:32767&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;192.168.0.0/16&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--dport&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;0:32767&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;10.0.0.0/8&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-p&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--dport&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;0:32767&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-d&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;172.16.0.0/12&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DOCKER-USER&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;RETURN&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-m&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;limit&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--limit&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;3/min&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--limit-burst&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;LOG&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;--log-prefix&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;[UFW DOCKER BLOCK]&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;-A&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;ufw-docker-logging-deny&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-j&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;DROP&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;COMMIT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#99A0A6;--1:#99A0A6&quot;&gt;# END UFW AND DOCKER&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Then restart UFW with &lt;code&gt;sudo systemctl restart ufw&lt;/code&gt;. From now on, the outside can no longer access any port published by Docker, while containers can still communicate with each other on private network addresses, and containers can still access the external network normally. &lt;strong&gt;The rules may fail to take effect after restarting UFW due to some unknown reason — if so, reboot the server.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;To allow external access to a service provided by a Docker container — say a container’s service port is &lt;code&gt;80&lt;/code&gt; — use the following command:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:49ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;80&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;This allows external access to every service published by Docker whose internal service port is &lt;code&gt;80&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Note that this &lt;code&gt;80&lt;/code&gt; is the container’s port, not the &lt;code&gt;8080&lt;/code&gt; port published on the server with something like &lt;code&gt;-p 0.0.0.0:8080:80&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;If multiple containers have service port 80 but you only want a specific one reachable from outside — say its private address is &lt;code&gt;172.17.0.2&lt;/code&gt; — use a command like:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:56ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;tcp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;172.17.0.2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;80&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;If a container’s service uses UDP, say a DNS service, use the following command to allow external access to all published DNS services:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:49ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;53&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Similarly, to target just one specific container, e.g. the IP &lt;code&gt;172.17.0.2&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:56ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;ufw&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;allow&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;proto&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;udp&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;172.17.0.2&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;53&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;chaitin-safeline-waf--cloudflare-single-node-deployment&quot;&gt;Chaitin SafeLine WAF + Cloudflare Single-Node Deployment&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#chaitin-safeline-waf--cloudflare-single-node-deployment&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;After racking my brain, there’s not much to write&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;If you need stronger security, stack a WAF and a honeypot in front like I did.&lt;/p&gt;
&lt;/blockquote&gt;&lt;section&gt;&lt;h3 id=&quot;deployment&quot;&gt;Deployment&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#deployment&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;There’s a one-click deployment command:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:74ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;bash&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-c&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;$(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-fsSLk&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; https://waf-ce.chaitin.cn/release/latest/setup.sh)&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Or deploy the LTS version:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:86ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;RELEASE&lt;/span&gt;&lt;span style=&quot;--0:#F97583;--1:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;lts&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;bash&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-c&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;$(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#79B8FF;--1:#79B8FF&quot;&gt;-fsSLk&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt; https://waf-ce.chaitin.cn/release/latest/setup.sh)&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Since this setup puts Cloudflare in front of the SafeLine WAF, you need to set Protected Sites → Global Config → Origin IP retrieval to “Take the address of the previous proxy from X-Forwarded-For”.&lt;/p&gt;&lt;p&gt;If other issues come up, check the &lt;a href=&quot;https://docs.waf-ce.chaitin.cn/zh/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5&quot;&gt;troubleshooting&lt;/a&gt; section of the official documentation.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;accessing-the-safeline-console-via-a-domain&quot;&gt;Accessing the SafeLine Console via a Domain&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#accessing-the-safeline-console-via-a-domain&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Best solution: don’t use a domain&lt;/p&gt;&lt;p&gt;If you want to access the SafeLine console via a domain, you’ll find it doesn’t work once Cloudflare’s orange cloud is enabled. That’s because Cloudflare’s port forwarding only supports a fixed set of ports:&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;HTTP ports supported by Cloudflare: 80, 8080, 8880, 2052, 2082, 2086, 2095&lt;/p&gt;
&lt;p&gt;HTTPS ports supported by Cloudflare: 443, 2053, 2083, 2087, 2096, 8443&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;The solution is simple: go to Rules → Origin Rules and create a rule. The incoming request match expression looks roughly like:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:62ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;starts_with&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; (http.request.full_uri, &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;&quot;https://&amp;lt;your-domain&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;Set the destination port rewrite to 9443.&lt;/p&gt;&lt;p&gt;To hide your public IP, add a firewall rule that only lets Cloudflare’s CDN CIDR ranges reach port 9443.&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;redirect-issues&quot;&gt;Redirect Issues&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#redirect-issues&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If a port number unexpectedly appears in the URL after a redirect, add the following under Protected Sites → Site Details → Custom NGINX Config:&lt;/p&gt;&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame is-terminal&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sr-only&quot;&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;bash&quot; class=&quot;wrap&quot; style=&quot;--ecMaxLine:50ch&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;gutter&quot;&gt;&lt;div class=&quot;ln&quot; aria-hidden=&quot;true&quot;&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#B392F0;--1:#B392F0&quot;&gt;proxy_redirect&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;https://&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$host&lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;:[port]&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#9ECBFF;--1:#9ECBFF&quot;&gt;https://&lt;/span&gt;&lt;span style=&quot;--0:#E1E4E8;--1:#E1E4E8&quot;&gt;$host;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div class=&quot;copy-btn-icon&quot;&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3 id=&quot;hide-the-admin-panel-with-wireguard&quot;&gt;Hide the Admin Panel with WireGuard&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#hide-the-admin-panel-with-wireguard&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;Don’t expose your VPS admin panels (such as the SafeLine WAF or BT Panel) to the public internet.
Accessing them over a VPN like WireGuard is a more secure choice.
Detailed WireGuard installation instructions are available at &lt;a href=&quot;https://www.wireguard.com/install/&quot;&gt;Installation - WireGuard&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2 id=&quot;references&quot;&gt;References&lt;a class=&quot;anchor&quot; href=&quot;https://blog.ravenote.me/en/posts/basic_security_measures_for_vps/#references&quot;&gt;&lt;span class=&quot;anchor-icon&quot; data-pagefind-ignore&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ubuntu.com/pro/tutorial&quot;&gt;Getting Started with Ubuntu Pro, from the Ubuntu official site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;How to Prevent Certificates from Leaking Your Origin IP — by Qiu Weimeng&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.ubuntu.org.cn/Ufw%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97&quot;&gt;UFW User Guide, from Ubuntu Chinese Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement&quot;&gt;Key-based authentication in OpenSSH for Windows, from Microsoft Learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.docker.com/engine/install/ubuntu&quot;&gt;Install Docker Engine on Ubuntu, from the Docker official site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/2&quot;&gt;https://linux.do/t/topic/267502/2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/3&quot;&gt;https://linux.do/t/topic/267502/3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/168843/11&quot;&gt;https://linux.do/t/topic/168843/11&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/18&quot;&gt;https://linux.do/t/topic/267502/18&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/chaifeng/ufw-docker&quot;&gt;https://github.com/chaifeng/ufw-docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/23&quot;&gt;https://linux.do/t/topic/267502/23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/42&quot;&gt;https://linux.do/t/topic/267502/42&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/44&quot;&gt;https://linux.do/t/topic/267502/44&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/20&quot;&gt;https://linux.do/t/topic/267502/20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.work.weixin.qq.com/document/path/91770&quot;&gt;https://developer.work.weixin.qq.com/document/path/91770&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/21&quot;&gt;https://linux.do/t/topic/267502/21&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/22&quot;&gt;https://linux.do/t/topic/267502/22&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/57&quot;&gt;https://linux.do/t/topic/267502/57&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/2069041&quot;&gt;https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/2069041&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/242440/29&quot;&gt;https://linux.do/t/topic/242440/29&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/71&quot;&gt;https://linux.do/t/topic/267502/71&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/87&quot;&gt;https://linux.do/t/topic/267502/87&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/97&quot;&gt;https://linux.do/t/topic/267502/97&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/99&quot;&gt;https://linux.do/t/topic/267502/99&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/108&quot;&gt;https://linux.do/t/topic/267502/108&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/121&quot;&gt;https://linux.do/t/topic/267502/121&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/122&quot;&gt;https://linux.do/t/topic/267502/122&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/135&quot;&gt;https://linux.do/t/topic/267502/135&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/267502/175&quot;&gt;https://linux.do/t/topic/267502/175&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;img alt=&quot;Not By AI&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;131&quot; height=&quot;42&quot; src=&quot;https://blog.ravenote.me/_astro/not-by-ai.BRg_BaJh_invcO.webp&quot; /&gt;&lt;/p&gt;&lt;/section&gt;</content:encoded></item></channel></rss>