1
0
wiki/Technology/ProgrammingLanguage/Python/进阶/面向对象进阶.html

680 lines
597 KiB
HTML
Raw Normal View History

2024-09-03 21:23:28 +08:00
<!DOCTYPE html>
<html><head><title>面向对象</title><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta property="og:title" content="面向对象"/><meta property="og:description" content="面向对象."/><meta property="og:image" content="https://wiki.7wate.com/static/og-image.png"/><meta property="og:width" content="1200"/><meta property="og:height" content="675"/><link rel="icon" href="../../../../static/icon.png"/><meta name="description" content="面向对象."/><meta name="generator" content="Quartz"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com"/><script async src="https://umami.7wate.com/script.js" data-website-id="c061efdc-95dd-4d21-9d04-a1ffda0a85b9"></script><script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?94d8ccb156eb7c65abf317e6e01cdba9";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script><script async src="https://www.googletagmanager.com/gtag/js?id=G-MHMEL0F832"></script><script>
(function() {
window.dataLayer = window.dataLayer || [];
function gtag() {
window.dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-MHMEL0F832');
})();
</script><link href="../../../../index.css" rel="stylesheet" type="text/css" spa-preserve/><link href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css" rel="stylesheet" type="text/css" spa-preserve/><link href="https://fonts.googleapis.com/css2?family=IBM Plex Mono&amp;family=Schibsted Grotesk:wght@400;700&amp;family=Source Sans Pro:ital,wght@0,400;0,600;1,400;1,600&amp;display=swap" rel="stylesheet" type="text/css" spa-preserve/><script src="../../../../prescript.js" type="application/javascript" spa-preserve></script><script type="application/javascript" spa-preserve>const fetchData = fetch(`../../../../static/contentIndex.json`).then(data => data.json())</script></head><body data-slug="Technology/ProgrammingLanguage/Python/进阶/面向对象进阶"><div id="quartz-root" class="page"><div id="quartz-body"><div class="left sidebar"><h1 class="page-title "><a href="../../../..">📚 X·Eden</a></h1><div class="spacer mobile-only"></div><div class="search "><div id="search-icon"><p>Search</p><div></div><svg tabIndex="0" aria-labelledby="title desc" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.9 19.7"><title id="title">Search</title><desc id="desc">Search</desc><g class="search-path" fill="none"><path stroke-linecap="square" d="M18.5 18.3l-5.4-5.4"></path><circle cx="8" cy="8" r="7"></circle></g></svg></div><div id="search-container"><div id="search-space"><input autocomplete="off" id="search-bar" name="search" type="text" aria-label="Search for something" placeholder="Search for something"/><div id="results-container"></div></div></div></div><div class="darkmode "><input class="toggle" id="darkmode-toggle" type="checkbox" tabIndex="-1"/><label id="toggle-label-light" for="darkmode-toggle" tabIndex="-1"><svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" version="1.1" id="dayIcon" x="0px" y="0px" viewBox="0 0 35 35" style="enable-background:new 0 0 35 35;" xmlSpace="preserve"><title>Light mode</title><path d="M6,17.5C6,16.672,5.328,16,4.5,16h-3C0.672,16,0,16.672,0,17.5 S0.672,19,1.5,19h3C5.328,19,6,18.328,6,17.5z M7.5,26c-0.414,0-0.789,0.168-1.061,0.439l-2,2C4.168,28.711,4,29.086,4,29.5 C4,30.328,4.671,31,5.5,31c0.414,0,0.789-0.168,1.06-0.44l2-2C8.832,28.289,9,27.914,9,27.5C9,26.672,8.329,26,7.5,26z M17.5,6 C18.329,6,19,5.328,19,4.5v-3C19,0.672,18.329,0,17.5,0S16,0.672,16,1.5v3C16,5.328,16.671,6,17.5,6z M27.5,9 c0.414,0,0.789-0.168,1.06-0.439l2-2C30.832,6.289,31,5.914,31,5.5C31,4.672,30.329,4,29.5,4c-0.414,0-0.789,0.168-1.061,0.44 l-2,2C26.168,6.711,26,7.086,26,7.5C26,8.328,26.671,9,27.5,9z M6.439,8.561C6.711,8.832,7.086,9,7.5,9C8.328,9,9,8.328,9,7.5 c0-0.414-0.168-0.789-0.439-1.061l-2-2C6.289,4.168,5.914,4,5.5,4C4.672,4,4,4.672,4,5.5c0,0.414,0.168,0.789,0.439,1.06 L6.439,8.561z M33.5,16h-3c-0.828,0-1.5,0.672-1.5,1.5s0.672,1.5,1.5,1.5h3c0.828,0,1.5-0.672,1.5-1.5S34.328,16,33.5,16z M28.561,26.439C28.289,26.168,27.914,26,27.5,26c-0.828,0-1.5,0.672-1.5,1.5c0,0.414,0.168,0.789,0.439,1.06l2,2 C28.711,30.832,29.086,31,29.5,31c0.828,0,1.5-0.672,1.5-1.5c0-0.414-0.168-0.789-0.439-1.061L28.561,26.439z M17.5,29 c-0.829,0-1.5,0.672-1.5,1.5v3c0,0.828,0.671,1.5,1.5,1.5s1.5-0.672,1.5-1.5v-3C19,29.672,18.329,29,17.5,29z M17.5,7 C11.71,7,7,11.71,7,17.5S11.71,28,17.5,28S28,23.29,28,17.5S23.29,7,17.5,7z M17.5,25c-4.136,0-7.5-3.364-7.5-7.5 c0-4.136,3.364-7.5,7.5-7.5c4.136,0,7.5,3.364,7.5,7.5C25,21.636,21.636,25,17.5,25z"></path></svg></label><label id="toggle-label-dark" for="darkmode-toggle" tabIndex="-1"><svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" version="1.1" id="nightIcon" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background='new 0 0 100 100'" xmlSpace="preserve"><title>Dark mode</title><path d="M96.76,66.458c-0.853-0.852-2.15-1.064-3.23-0.534c-6.063,2.991-12.858,4.571-19.655,4.571 C62.022,70.495,50.88,65.88,42.5,57.5C29.043,44.043,25.658,23.536,34.076,6.47c0.532-1.08,0.318-2.379-0.534-3.23 c-0.851-0.852-2.15-1.064-3.23-0.534c-4.918,2.427-9.375,5.619-13.246,9.491c-9.447,9.447-14.65,2
<pre><code class="mermaid">graph TD
A[类定义阶段: class MyClass] --> B[类对象创建]
B --> C1[类属性访问: MyClass.class_attr]
B --> C[实例化阶段: __new__ method]
C --> D[初始化阶段: __init__ method]
D --> E1[属性的设置与获取: __setattr__, __getattr__]
D --> E2[对象的表示: __str__, __repr__]
D --> E3[方法调用]
D --> E4[上下文管理: __enter__, __exit__]
D --> E5[对象比较: __eq__, __lt__]
D --> E6[对象的计算: __add__, __mul__]
E1 --> F
E2 --> F
E3 --> F
E4 --> F
E5 --> F
E6 --> F
F[对象销毁: del obj or GC] --> G[__del__ method]
G --> H[垃圾回收: Cleanup by Python GC]
</code></pre>
<ol>
<li><strong>类定义阶段</strong>:在这个阶段定义类的方法和属性。</li>
<li><strong>类对象创建</strong>:当 Python 读取到类定义时,它会创建一个类对象。</li>
<li><strong>类属性访问</strong>:在实例化之前,可以访问类的静态和类属性。</li>
<li><strong>实例化阶段</strong>:使用类名创建对象时,首先调用 <code>__new__</code> 方法来分配内存。</li>
<li><strong>初始化阶段</strong>:紧随其后,<code>__init__</code> 方法会被调用,对新对象进行初始化。</li>
<li><strong>属性的设置与获取</strong>:在对象的生命周期中,你可以使用 <code>__getattr__</code>, <code>__setattr__</code>, <code>__getattribute__</code> 等特殊方法来控制属性的访问。</li>
<li><strong>对象的表示</strong>:当尝试显示对象时(例如,通过 print<code>__str__</code><code>__repr__</code> 方法可以被调用。</li>
<li><strong>方法调用</strong>:可以调用对象的方法。</li>
<li><strong>上下文管理</strong>:使用 <code>with</code> 语句时,对象的 <code>__enter__</code><code>__exit__</code> 方法会被调用。</li>
<li><strong>对象比较</strong>:使用比较操作符时(如==或><code>__eq__</code>, <code>__lt__</code>, <code>__le__</code> 等特殊方法会被调用。</li>
<li><strong>对象的计算</strong>:如加法或乘法等运算符,会调用 <code>__add__</code>, <code>__mul__</code> 等特殊方法。</li>
<li><strong>对象销毁</strong>:当对象的引用计数减少到零或者被明确销毁(使用 <code>del</code> 语句)时,<code>__del__</code> 方法会被调用。</li>
<li><strong>垃圾回收</strong>Python 的垃圾回收器会识别循环引用,并在适当的时候销毁相关对象。</li>
</ol>
<h2 id="特殊方法">特殊方法<a aria-hidden="true" tabindex="-1" href="#特殊方法" class="internal"> §</a></h2>
<p>Python 中的类包含了许多特殊方法,它们经常被称为<strong>魔术方法magic methods<strong>或者</strong>双下方法dunder methods</strong>,因为它们的名字都是以双下划线开始和结束的。这些特殊方法为 Python 的对象提供了许多内置的功能,如算术运算、迭代和字符串表示。</p>
<p>魔术方法是 Python 类的特殊方法,它们定义了许多 Python 中基本的操作。例如,当你为一个对象定义了 <code>__add__</code> 方法时,这个对象就可以使用 <code>+</code> 运算符。这些方法的名称都是以两个下划线开始和结束,这也是为什么它们被称为双下方法的原因。</p>
<h3 id="基础方法">基础方法<a aria-hidden="true" tabindex="-1" href="#基础方法" class="internal"> §</a></h3>
<h4 id="__init__"><code>__init__</code><a aria-hidden="true" tabindex="-1" href="#__init__" class="internal"> §</a></h4>
<p><code>__init__</code> 方法是类的构造函数,当我们创建类的实例时,<code>__init__</code> 方法会被自动调用。我们可以在 <code>__init__</code> 方法中初始化实例的属性。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">value</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">value </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> value </span><span style="color:var(--shiki-token-comment);"># 初始化实例属性</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">10</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(mc.value)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出10</span></span></code></pre></div>
<h4 id="__del__"><code>__del__</code><a aria-hidden="true" tabindex="-1" href="#__del__" class="internal"> §</a></h4>
<p><code>__del__</code> 方法是类的析构函数,当一个实例被销毁时(例如被垃圾回收器回收时),<code>__del__</code> 方法会被自动调用。注意,我们<strong>通常不需要在 <code>__del__</code> 方法中做清理工作Python 的垃圾回收器会自动清理对象的资源。</strong></p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__del__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Instance is being destroyed.&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">del</span><span style="color:var(--shiki-color-text);"> mc </span><span style="color:var(--shiki-token-comment);"># 销毁实例</span></span></code></pre></div>
<h4 id="__str__"><code>__str__</code><a aria-hidden="true" tabindex="-1" href="#__str__" class="internal"> §</a></h4>
<p><code>__str__</code> 方法返回一个表示该对象的字符串,这个字符串通常用于给用户看。当我们调用 <code>str()</code><code>print()</code> 时,会使用 <code>__str__</code> 的返回值。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__str__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;This is a MyClass instance.&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(mc)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出This is a MyClass instance.</span></span></code></pre></div>
<p><em>注意,<code>__repr__</code><code>__str__</code> 的区别在于,<strong><code>__repr__</code> 更侧重于开发,而 <code>__str__</code> 更侧重于用户。</strong></em></p>
<h4 id="__repr__"><code>__repr__</code><a aria-hidden="true" tabindex="-1" href="#__repr__" class="internal"> §</a></h4>
<p><code>__repr__</code> 方法返回一个表示该对象的官方字符串,这个字符串通常可以被 <code>eval()</code> 执行来重新得到这个对象。如果我们没有定义 <code>__str__</code> 方法,那么在调用 <code>str()</code><code>print()</code> 时也会使用 <code>__repr__</code> 的返回值。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__repr__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;MyClass()&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(mc)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出MyClass()</span></span></code></pre></div>
<h4 id="__format__"><code>__format__</code><a aria-hidden="true" tabindex="-1" href="#__format__" class="internal"> §</a></h4>
<p><code>__format__</code> 方法定义了当我们调用 <code>format()</code> 或使用格式化字符串f-string时的行为。<code>format_spec</code> 是一个格式说明符,它是在格式化字符串中 <code>:</code> 后面的部分。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__format__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">format_spec</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> format_spec </span><span style="color:var(--shiki-token-keyword);">==</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'fancy'</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'This is a fancy MyClass instance.'</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'This is a MyClass instance.'</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">mc:fancy</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出This is a fancy MyClass instance.</span></span></code></pre></div>
<h3 id="数学运算">数学运算<a aria-hidden="true" tabindex="-1" href="#数学运算" class="internal"> §</a></h3>
<p>比较运算的魔术方法允许类的实例之间进行比较。例如,<code>__eq__</code> 定义了对象的等于操作。这些方法的使用可以使您的类实例支持标准的比较操作符,如 <code>==</code>, <code>!=</code>, <code>+</code>, <code>-</code>, <code>%</code>, 和 <code>@</code>。类似地,可以为其他数学运算符定义其他魔术方法。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Book</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">title</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">author</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">title </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> title</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">author </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> author</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__eq__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">other</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">isinstance</span><span style="color:var(--shiki-token-punctuation);">(other, Book):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">title </span><span style="color:var(--shiki-token-keyword);">==</span><span style="color:var(--shiki-color-text);"> other</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">title </span><span style="color:var(--shiki-token-keyword);">and</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">author </span><span style="color:var(--shiki-token-keyword);">==</span><span style="color:var(--shiki-color-text);"> other</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">author</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">False</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 比较两本书是否具有相同的标题和作者</span></span>
<span data-line><span style="color:var(--shiki-color-text);">book1 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Book</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'1984'</span><span style="color:var(--shiki-token-punctuation);">, </span><span style="color:var(--shiki-token-string-expression);">'George Orwell'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">book2 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Book</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'1984'</span><span style="color:var(--shiki-token-punctuation);">, </span><span style="color:var(--shiki-token-string-expression);">'George Orwell'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">book3 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Book</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">'Brave New World'</span><span style="color:var(--shiki-token-punctuation);">, </span><span style="color:var(--shiki-token-string-expression);">'Aldous Huxley'</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(book1 </span><span style="color:var(--shiki-token-keyword);">==</span><span style="color:var(--shiki-token-punctuation);"> book2)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出True</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(book1 </span><span style="color:var(--shiki-token-keyword);">==</span><span style="color:var(--shiki-token-punctuation);"> book3)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出False</span></span></code></pre></div>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Vector</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">x</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">y</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">x </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> x</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">y </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> y</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__add__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">other</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">isinstance</span><span style="color:var(--shiki-token-punctuation);">(other, Vector):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Vector</span><span style="color:var(--shiki-token-punctuation);">(self.x </span><span style="color:var(--shiki-token-keyword);">+</span><span style="color:var(--shiki-token-punctuation);"> other.x, self.y </span><span style="color:var(--shiki-token-keyword);">+</span><span style="color:var(--shiki-token-punctuation);"> other.y)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">NotImplemented</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 使用 + 操作符组合两个向量</span></span>
<span data-line><span style="color:var(--shiki-color-text);">v1 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Vector</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">1</span><span style="color:var(--shiki-token-punctuation);">, </span><span style="color:var(--shiki-token-constant);">2</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">v2 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Vector</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">2</span><span style="color:var(--shiki-token-punctuation);">, </span><span style="color:var(--shiki-token-constant);">3</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">v3 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> v1 </span><span style="color:var(--shiki-token-keyword);">+</span><span style="color:var(--shiki-color-text);"> v2</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(v3.x, v3.y)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出3 5</span></span></code></pre></div>
<table><thead><tr><th>运算符</th><th>对应的魔术方法</th><th>描述</th></tr></thead><tbody><tr><td><code>==</code></td><td><code>__eq__</code></td><td>等于</td></tr><tr><td><code>!=</code></td><td><code>__ne__</code></td><td>不等于</td></tr><tr><td><code>&lt;</code></td><td><code>__lt__</code></td><td>小于</td></tr><tr><td><code>&lt;=</code></td><td><code>__le__</code></td><td>小于或等于</td></tr><tr><td><code>></code></td><td><code>__gt__</code></td><td>大于</td></tr><tr><td><code>>=</code></td><td><code>__ge__</code></td><td>大于或等于</td></tr><tr><td><code>+</code></td><td><code>__add__</code></td><td>加法</td></tr><tr><td><code>-</code></td><td><code>__sub__</code></td><td>减法</td></tr><tr><td><code>*</code></td><td><code>__mul__</code></td><td>乘法</td></tr><tr><td><code>/</code></td><td><code>__truediv__</code></td><td>真除</td></tr><tr><td><code>//</code></td><td><code>__floordiv__</code></td><td>整除</td></tr><tr><td><code>%</code></td><td><code>__mod__</code></td><td>取模</td></tr><tr><td><code>**</code></td><td><code>__pow__</code></td><td>乘方</td></tr><tr><td><code>@</code></td><td><code>__matmul__</code></td><td>Python 3.5+ 矩阵乘法</td></tr></tbody></table>
<h3 id="容器方法">容器方法<a aria-hidden="true" tabindex="-1" href="#容器方法" class="internal"> §</a></h3>
<h4 id="__len__"><code>__len__</code><a aria-hidden="true" tabindex="-1" href="#__len__" class="internal"> §</a></h4>
<p><code>__len__</code> 方法定义了 <code>len()</code> 的返回值。它应该返回一个整数,表示对象包含的元素的个数。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">data </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> [</span><span style="color:var(--shiki-token-constant);">1</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">2</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">3</span><span style="color:var(--shiki-color-text);">]</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__len__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">len</span><span style="color:var(--shiki-token-punctuation);">(self.data)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-function);">len</span><span style="color:var(--shiki-token-punctuation);">(mc))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出3</span></span></code></pre></div>
<h4 id="__getitem__"><code>__getitem__</code><a aria-hidden="true" tabindex="-1" href="#__getitem__" class="internal"> §</a></h4>
<p><code>__getitem__</code> 方法定义了使用索引访问元素的行为。<code>key</code> 是索引。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__getitem__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">key</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;You are trying to access key </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-color-text);">key</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">.&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(mc[</span><span style="color:var(--shiki-token-constant);">10</span><span style="color:var(--shiki-token-punctuation);">])</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出You are trying to access key 10.</span></span></code></pre></div>
<h4 id="__setitem__"><code>__setitem__</code><a aria-hidden="true" tabindex="-1" href="#__setitem__" class="internal"> §</a></h4>
<p><code>__setitem__</code> 方法定义了使用索引设置元素的行为。<code>key</code> 是索引,<code>value</code> 是我们试图设置的值。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__setitem__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">key</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">value</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;Set key </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">key</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);"> to </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">value</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">.&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-color-text);">mc</span><span style="color:var(--shiki-token-punctuation);">[</span><span style="color:var(--shiki-token-constant);">10</span><span style="color:var(--shiki-token-punctuation);">]</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;value&quot;</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出Set key 10 to value.</span></span></code></pre></div>
<h4 id="__delitem__"><code>__delitem__</code><a aria-hidden="true" tabindex="-1" href="#__delitem__" class="internal"> §</a></h4>
<p><code>__delitem__</code> 方法定义了使用索引删除元素的行为。<code>key</code> 是索引。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__delitem__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">key</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;Deleted key </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">key</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">.&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">del</span><span style="color:var(--shiki-color-text);"> mc</span><span style="color:var(--shiki-token-punctuation);">[</span><span style="color:var(--shiki-token-constant);">10</span><span style="color:var(--shiki-token-punctuation);">]</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出Deleted key 10.</span></span></code></pre></div>
<h4 id="__iter____next__"><code>__iter__</code><code>__next__</code><a aria-hidden="true" tabindex="-1" href="#__iter____next__" class="internal"> §</a></h4>
<p>迭代器协议的魔术方法允许对象支持迭代,这意味着您可以在对象上使用 <code>for</code> 循环。为了使一个对象可迭代,您需要定义 <code>__iter__</code><code>__next__</code> 两个魔术方法。</p>
<ul>
<li>
<p><code>__iter__</code> 返回对象本身,它应该返回一个实现了 <code>__next__</code> 的迭代器对象。</p>
</li>
<li>
<p><code>__next__</code> 方法返回序列中的下一个值。如果所有项都返回了,那么它应该引发一个 <code>StopIteration</code> 异常来通知迭代的完成。</p>
</li>
</ul>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Counter</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">start</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">end</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">current </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> start</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">end </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> end</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__iter__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> self</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__next__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">current </span><span style="color:var(--shiki-token-keyword);">&lt;</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">end</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> value </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">current</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">current </span><span style="color:var(--shiki-token-keyword);">+=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">1</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> value</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">else</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">raise</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">StopIteration</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 使用Counter迭代器</span></span>
<span data-line><span style="color:var(--shiki-color-text);">counter </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Counter</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">1</span><span style="color:var(--shiki-token-punctuation);">, </span><span style="color:var(--shiki-token-constant);">4</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> number </span><span style="color:var(--shiki-token-keyword);">in</span><span style="color:var(--shiki-color-text);"> counter</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(number)</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 1</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 2</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 3</span></span></code></pre></div>
<p>在上述 <code>Counter</code> 类中,我们定义了一个简单的迭代器,它从 <code>start</code> 开始,每次迭代增加 1直到 <code>end</code> 为止。<code>for</code> 循环通过调用 <code>__iter__</code> 来获取迭代器对象,并在每次迭代中调用 <code>__next__</code>,直到捕获 <code>StopIteration</code> 异常为止。</p>
<h3 id="属性访问">属性访问<a aria-hidden="true" tabindex="-1" href="#属性访问" class="internal"> §</a></h3>
<h4 id="__dir__"><code>__dir__</code><a aria-hidden="true" tabindex="-1" href="#__dir__" class="internal"> §</a></h4>
<p><code>__dir__</code> 方法返回类中定义的属性、方法等的列表。它对内置的 <code>dir()</code> 函数的行为进行重载。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__dir__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> [</span><span style="color:var(--shiki-token-string-expression);">&quot;custom_attr1&quot;</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;custom_attr2&quot;</span><span style="color:var(--shiki-color-text);">]</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-function);">dir</span><span style="color:var(--shiki-token-punctuation);">(mc))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出:['custom_attr1', 'custom_attr2']</span></span></code></pre></div>
<h4 id="__getattr__"><code>__getattr__</code><a aria-hidden="true" tabindex="-1" href="#__getattr__" class="internal"> §</a></h4>
<p>当尝试访问一个不存在的属性时,<code>__getattr__</code> 方法会被调用。<code>name</code> 是试图访问的属性名称。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__getattr__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">name</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-color-text);">name</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);"> does not exist.&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(mc.unknown_attr)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出unknown_attr does not exist.</span></span></code></pre></div>
<p><em>值得注意的是,<strong><code>__getattr__</code> 只有在所请求的属性不存在时才会被调用。</strong></em></p>
<h4 id="__setattr__"><code>__setattr__</code><a aria-hidden="true" tabindex="-1" href="#__setattr__" class="internal"> §</a></h4>
<p>每当尝试设置一个属性值时,<code>__setattr__</code> 都会被调用,不论该属性是否存在。<code>name</code> 是试图设置的属性的名称,而 <code>value</code> 是试图赋给该属性的值。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__setattr__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">name</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">value</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-constant);">__dict__</span><span style="color:var(--shiki-color-text);">[name] </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> value </span><span style="color:var(--shiki-token-comment);"># 防止无限递归, 需要在__dict__中设置属性</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;Set </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">name</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);"> to </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">value</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">.&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-color-text);">mc</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">attr </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">10</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出Set attr to 10.</span></span></code></pre></div>
<h4 id="__delattr__"><code>__delattr__</code><a aria-hidden="true" tabindex="-1" href="#__delattr__" class="internal"> §</a></h4>
<p>当试图删除一个属性时,<code>__delattr__</code> 方法会被调用。<code>name</code> 是试图删除的属性的名称。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> attr </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">10</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__delattr__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">name</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">del</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-constant);">__dict__</span><span style="color:var(--shiki-color-text);">[name] </span><span style="color:var(--shiki-token-comment);"># 防止无限递归, 需要在__dict__中删除属性</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;Deleted </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">name</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">.&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">del</span><span style="color:var(--shiki-color-text);"> mc</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">attr </span><span style="color:var(--shiki-token-comment);"># 输出Deleted attr.</span></span></code></pre></div>
<h4 id="__getattribute__"><code>__getattribute__</code><a aria-hidden="true" tabindex="-1" href="#__getattribute__" class="internal"> §</a></h4>
<p>每次尝试访问一个属性时,<code>__getattribute__</code> 方法都会被调用,无论该属性是否存在。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__getattribute__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">name</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;You are trying to access </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-color-text);">name</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">.&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(mc.attr)</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出You are trying to access attr.</span></span></code></pre></div>
<p>重要的是,<strong>如果 <code>__getattribute__</code> 被定义,那么 <code>__getattr__</code> 不会被调用,因为 <code>__getattribute__</code> 的优先级更高。</strong>*</p>
<h3 id="上下文管理">上下文管理<a aria-hidden="true" tabindex="-1" href="#上下文管理" class="internal"> §</a></h3>
<h4 id="__enter____exit__"><code>__enter__</code><code>__exit__</code><a aria-hidden="true" tabindex="-1" href="#__enter____exit__" class="internal"> §</a></h4>
<p>当使用 <code>with</code> 语句进入上下文管理时,<code>__enter__</code> 方法会被调用。它应该返回上下文管理器对象本身或其他与上下文相关的对象。</p>
<p><code>with</code> 语句块结束时,<code>__exit__</code> 方法会被调用。它接收三个参数:<code>exc_type</code><code>exc_val</code><code>exc_tb</code>,分别代表异常类型、异常值和异常回溯。如果 <code>with</code> 语句块中没有发生异常,这三个参数的值都为 <code>None</code></p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">ContextManager</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__enter__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Entering the context&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> self</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__exit__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">exc_type</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">exc_val</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">exc_tb</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> exc_type </span><span style="color:var(--shiki-token-keyword);">is</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">None</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Exiting the context without any exception.&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">else</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;Exiting the context with exception: </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">exc_val</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">say_hello</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Hello from inside the context!&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">with</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">ContextManager</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">as</span><span style="color:var(--shiki-color-text);"> cm</span><span style="color:var(--shiki-token-punctuation);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> cm</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">say_hello</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># Entering the context</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># Hello from inside the context!</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># Exiting the context without any exception.</span></span></code></pre></div>
<p>如果在 <code>with</code> 语句块中引发了异常,<code>__exit__</code> 方法可以选择处理这个异常(例如记录日志)并返回 <code>True</code> 来阻止异常向外传播,或者返回 <code>False</code>(或 <code>None</code>)让异常继续向外传播。</p>
<p>上下文管理器是一种非常强大的工具,特别是当涉及到需要设置和清理资源的任务时,例如文件 I/O、网络连接或数据库连接。</p>
<h3 id="描述符">描述符<a aria-hidden="true" tabindex="-1" href="#描述符" class="internal"> §</a></h3>
<p>描述符是实现了描述符协议的对象。描述符协议由 <code>__get__</code><code>__set__</code><code>__delete__</code> 方法组成。描述符用于创建那些需要特殊行为的对象属性,例如类型检查或只读属性。</p>
<h4 id="__get__"><code>__get__</code><a aria-hidden="true" tabindex="-1" href="#__get__" class="internal"> §</a></h4>
<p><code>__get__</code> 方法定义了在获取属性时应执行的行为。当试图获取属性值时,这个方法会被调用。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Descriptor</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__get__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">instance</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">owner</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;Getting value from </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">instance.</span><span style="color:var(--shiki-token-constant);">__class__</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-constant);">__name__}</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> attr </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Descriptor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);">mc</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">attr</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># Getting value from MyClass</span></span></code></pre></div>
<h4 id="__set__"><code>__set__</code><a aria-hidden="true" tabindex="-1" href="#__set__" class="internal"> §</a></h4>
<p><code>__set__</code> 方法定义了在设置属性值时应执行的行为。当试图给属性赋值时,这个方法会被调用。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Descriptor</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__set__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">instance</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">value</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;Setting value </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">value</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);"> to </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">instance.</span><span style="color:var(--shiki-token-constant);">__class__</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-constant);">__name__}</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> attr </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Descriptor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);">mc</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">attr </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">10</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># Setting value 10 to MyClass</span></span></code></pre></div>
<h4 id="__delete__"><code>__delete__</code><a aria-hidden="true" tabindex="-1" href="#__delete__" class="internal"> §</a></h4>
<p><code>__delete__</code> 方法定义了当删除属性时应执行的行为。当试图删除属性时,这个方法会被调用。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Descriptor</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__delete__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">instance</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;Deleting value from </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-token-punctuation);">instance.</span><span style="color:var(--shiki-token-constant);">__class__</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-constant);">__name__}</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> attr </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Descriptor</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-keyword);">del</span><span style="color:var(--shiki-color-text);"> mc</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">attr</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出:</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># Deleting value from MyClass</span></span></code></pre></div>
<h3 id="使对象可调用">使对象可调用<a aria-hidden="true" tabindex="-1" href="#使对象可调用" class="internal"> §</a></h3>
<p>**在 Python 中,函数是一类对象,可以调用它们。**但是,您知道您也可以使自己的对象表现得像函数一样吗?通过定义 <code>__call__</code> 魔术方法,您可以使类的实例表现得像函数,从而允许对它们进行调用。</p>
<h4 id="__call__"><code>__call__</code><a aria-hidden="true" tabindex="-1" href="#__call__" class="internal"> §</a></h4>
<p>当实例作为函数被“调用”时,<code>__call__</code> 方法就会被执行。这提供了一种优雅的方式来使用对象,同时保持其对象性质。通过这种方式,您的对象不仅可以表示数据,还可以表现得像函数,这增加了编码的灵活性和创造性。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Greeter</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">greeting</span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-token-string-expression);">&quot;Hello&quot;</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">greeting </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> greeting</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__call__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">name</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">f</span><span style="color:var(--shiki-token-string-expression);">&quot;</span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-color-text);">self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">greeting</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">, </span><span style="color:var(--shiki-token-constant);">{</span><span style="color:var(--shiki-color-text);">name</span><span style="color:var(--shiki-token-constant);">}</span><span style="color:var(--shiki-token-string-expression);">!&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-comment);"># 创建一个Greeter实例</span></span>
<span data-line><span style="color:var(--shiki-color-text);">hello_greeter </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Greeter</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Hello&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-function);">hello_greeter</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;John&quot;</span><span style="color:var(--shiki-token-punctuation);">))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出Hello, John!</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">bonjour_greeter </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Greeter</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Bonjour&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-function);">bonjour_greeter</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Pierre&quot;</span><span style="color:var(--shiki-token-punctuation);">))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出Bonjour, Pierre!</span></span></code></pre></div>
<h3 id="值比较">值比较<a aria-hidden="true" tabindex="-1" href="#值比较" class="internal"> §</a></h3>
<h4 id="__hash__"><code>__hash__</code><a aria-hidden="true" tabindex="-1" href="#__hash__" class="internal"> §</a></h4>
<p><code>__hash__</code> 方法返回对象的哈希值。哈希值通常用于字典的键值和其他需要快速查找的数据结构中。如果一个对象是可变的,通常最好不要实现此方法。如果对象定义了 <code>__eq__</code> 方法并且是不可变的,则通常也应定义此方法。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">value</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">value </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> value</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__eq__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">other</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">isinstance</span><span style="color:var(--shiki-token-punctuation);">(other, MyClass):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">value </span><span style="color:var(--shiki-token-keyword);">==</span><span style="color:var(--shiki-color-text);"> other</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">value</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">NotImplemented</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__hash__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">hash</span><span style="color:var(--shiki-token-punctuation);">(self.value)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">obj1 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">obj2 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">my_dict </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-punctuation);">{</span><span style="color:var(--shiki-color-text);">obj1</span><span style="color:var(--shiki-token-punctuation);">:</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;a&quot;</span><span style="color:var(--shiki-token-punctuation);">}</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(my_dict[obj2])</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出a</span></span></code></pre></div>
<h4 id="__bool__"><code>__bool__</code><a aria-hidden="true" tabindex="-1" href="#__bool__" class="internal"> §</a></h4>
<p><code>__bool__</code> 方法用于实现 <code>bool()</code> 内置函数的调用。当我们调用 <code>bool()</code> 函数或使用对象在条件语句(例如 <code>if obj:</code>)中作为条件时,会调用此方法。如果 <code>__bool__</code> 没有被定义,<code>__len__</code> 会被调用(如果已定义)。如果两者都未定义,所有实例都默认为 <code>True</code></p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">value</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">value </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> value</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__bool__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">bool</span><span style="color:var(--shiki-token-punctuation);">(self.value)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">obj1 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">0</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">obj2 </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">bool</span><span style="color:var(--shiki-token-punctuation);">(obj1))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出False</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">bool</span><span style="color:var(--shiki-token-punctuation);">(obj2))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出True</span></span></code></pre></div>
<h3 id="类型转换">类型转换<a aria-hidden="true" tabindex="-1" href="#类型转换" class="internal"> §</a></h3>
<h4 id="__int__"><code>__int__</code><a aria-hidden="true" tabindex="-1" href="#__int__" class="internal"> §</a></h4>
<p><code>__int__</code> 方法允许将一个对象转换为整数。当使用 <code>int()</code> 内置函数时,如果对象实现了此方法,会被调用。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__int__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">42</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">obj </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">int</span><span style="color:var(--shiki-token-punctuation);">(obj))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出42</span></span></code></pre></div>
<h4 id="__float__"><code>__float__</code><a aria-hidden="true" tabindex="-1" href="#__float__" class="internal"> §</a></h4>
<p><code>__float__</code> 方法允许将一个对象转换为浮点数。当使用 <code>float()</code> 内置函数时,如果对象实现了此方法,会被调用。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__float__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">42.0</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">obj </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">float</span><span style="color:var(--shiki-token-punctuation);">(obj))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出42.0</span></span></code></pre></div>
<h4 id="__complex__"><code>__complex__</code><a aria-hidden="true" tabindex="-1" href="#__complex__" class="internal"> §</a></h4>
<p><code>__complex__</code> 方法允许将一个对象转换为复数。当使用 <code>complex()</code> 内置函数时,如果对象实现了此方法,会被调用。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__complex__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">3</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">+</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">4</span><span style="color:var(--shiki-token-keyword);">j</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">obj </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">complex</span><span style="color:var(--shiki-token-punctuation);">(obj))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出:(3+4j)</span></span></code></pre></div>
<h4 id="__bytes__"><code>__bytes__</code><a aria-hidden="true" tabindex="-1" href="#__bytes__" class="internal"> §</a></h4>
<p><code>__bytes__</code> 方法定义了当我们调用 <code>bytes()</code> 时的行为。它应该返回一个字节串。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__bytes__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">b</span><span style="color:var(--shiki-token-string-expression);">'MyClass instance'</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">mc </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">MyClass</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 创建实例</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">bytes</span><span style="color:var(--shiki-token-punctuation);">(mc))</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 输出b'MyClass instance'</span></span></code></pre></div>
<h2 id="类和静态方法">类和静态方法<a aria-hidden="true" tabindex="-1" href="#类和静态方法" class="internal"> §</a></h2>
<p>在 Python 中,类是一个创建对象的蓝图。对象则是基于类定义的实例。默认情况下,在类内部定义的方法是实例方法。</p>
<h3 id="实例方法">实例方法<a aria-hidden="true" tabindex="-1" href="#实例方法" class="internal"> §</a></h3>
<p>实例方法的第一个参数是 <code>self</code>,代表类的实例对象。它可以访问和修改与实例相关的属性和方法。实例方法<strong>只能由其实例对象调用</strong></p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">instance_method</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;This is an instance method&quot;</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> self</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">e </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(e.</span><span style="color:var(--shiki-token-function);">instance_method</span><span style="color:var(--shiki-token-punctuation);">())</span><span style="color:var(--shiki-color-text);"> </span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出 ('This is an instance method', &lt;__main__.Example object at 0x7f49af98f610>)</span></span></code></pre></div>
<h3 id="类方法">类方法<a aria-hidden="true" tabindex="-1" href="#类方法" class="internal"> §</a></h3>
<p>类方法使用 <code>@classmethod</code> 装饰器定义。其第一个参数是 <code>cls</code>,代表类本身。类方法既可以由类直接调用,也可以被其实例调用。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> class_var </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;Class Variable&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">@</span><span style="color:var(--shiki-token-constant);">classmethod</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">class_method</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">cls</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;This is a class method accessing:&quot;</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> cls</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">class_var</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(Example.</span><span style="color:var(--shiki-token-function);">class_method</span><span style="color:var(--shiki-token-punctuation);">())</span><span style="color:var(--shiki-color-text);"> </span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出 ('This is a class method accessing:', 'Class Variable')</span></span></code></pre></div>
<h3 id="静态方法">静态方法<a aria-hidden="true" tabindex="-1" href="#静态方法" class="internal"> §</a></h3>
<p>静态方法使用 <code>@staticmethod</code> 装饰器定义。它不需要传递 <code>self</code><code>cls</code> 参数。<strong>静态方法不能访问或修改类或实例的属性和方法。它仅仅与它所在的类相关</strong>,但不需要访问类的特性。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">@</span><span style="color:var(--shiki-token-constant);">staticmethod</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">static_method</span><span style="color:var(--shiki-color-text);">():</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;This is a static method&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(Example.</span><span style="color:var(--shiki-token-function);">static_method</span><span style="color:var(--shiki-token-punctuation);">())</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出 This is a static method</span></span></code></pre></div>
<h3 id="类方法-vs-静态方法">类方法 Vs 静态方法<a aria-hidden="true" tabindex="-1" href="#类方法-vs-静态方法" class="internal"> §</a></h3>
<table><thead><tr><th>类型</th><th>用途</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td><strong>类方法</strong></td><td>访问/修改类属性,方法继承于子类</td><td>可访问/修改类属性,适用于继承</td><td>不能访问实例特有的属性</td></tr><tr><td><strong>静态方法</strong></td><td>不需访问实例/类数据的操作,与类相关但不需访问类或实例</td><td>无需实例化,代码组织清晰</td><td>不能访问类和实例的属性或方法</td></tr></tbody></table>
<p>在面向对象编程中,合理地使用实例方法、类方法和静态方法可以使代码更有组织性,更易于维护。</p>
<h2 id="属性">属性<a aria-hidden="true" tabindex="-1" href="#属性" class="internal"> §</a></h2>
<h3 id="property-装饰器"><code>@property</code> 装饰器<a aria-hidden="true" tabindex="-1" href="#property-装饰器" class="internal"> §</a></h3>
<p>在 Python 中,<code>@property</code> 装饰器使我们能够将类中的方法用作属性,从而实现对属性的控制。它可以用于确保属性的读取和设置遵循某种特定的逻辑。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">number</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_number </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> number</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">@</span><span style="color:var(--shiki-token-constant);">property</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">number</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_number</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">e </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(e.number)</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出 5</span></span></code></pre></div>
<h3 id="使用-setter-和-getter-方法">使用 Setter 和 Getter 方法<a aria-hidden="true" tabindex="-1" href="#使用-setter-和-getter-方法" class="internal"> §</a></h3>
<p>Setter 和 Getter 在 Python 中用于控制属性的访问和赋值。</p>
<h4 id="property_namesetter"><code>@&lt;property_name>.setter</code><a aria-hidden="true" tabindex="-1" href="#property_namesetter" class="internal"> §</a></h4>
<p>在定义了属性的 getter 方法后,我们可以使用 <code>@&lt;property_name>.setter</code> 装饰器定义相应的 setter 方法,以控制该属性的赋值逻辑。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">number</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_number </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> number</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">@</span><span style="color:var(--shiki-token-constant);">property</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">number</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_number</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">@number</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">setter</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">number</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">value</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_number </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> value</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">e </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);">e</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">number </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">10</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(e.number)</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># 输出 10</span></span></code></pre></div>
<h4 id="property_namedeleter"><code>@&lt;property_name>.deleter</code><a aria-hidden="true" tabindex="-1" href="#property_namedeleter" class="internal"> §</a></h4>
<p>除了设置和获取属性,我们还可以定义如何删除属性。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-parameter);">number</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_number </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> number</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">@</span><span style="color:var(--shiki-token-constant);">property</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">number</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">return</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_number</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">@number</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">deleter</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">number</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-string-expression);">&quot;Deleting number&quot;</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">del</span><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_number</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">e </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-token-punctuation);">(</span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-token-punctuation);">)</span></span>
<span data-line><span style="color:var(--shiki-token-keyword);">del</span><span style="color:var(--shiki-color-text);"> e</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">number</span></span></code></pre></div>
<h3 id="属性保护">属性保护<a aria-hidden="true" tabindex="-1" href="#属性保护" class="internal"> §</a></h3>
<p>在 Python 中,我们通常<strong>使用下划线来表示属性应该是私有的或受保护的。</strong></p>
<ul>
<li><strong>受保护的属性</strong>: 通常使用单下划线前缀 <code>_</code> 来定义,例如 <code>_name</code>。这只是一个约定,表示这个属性是为类内部使用的,但外部仍然可以访问。</li>
<li><strong>私有属性</strong>: 使用双下划线前缀 <code>__</code> 来定义,例如 <code>__name</code>。Python 会对其进行名称修饰,使得在类的外部更难直接访问。</li>
</ul>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">__init__</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">__private_attr </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;I am private&quot;</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> self</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">_protected_attr </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;I am protected&quot;</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">reveal</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-parameter);">self</span><span style="color:var(--shiki-color-text);">):</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(self.__private_attr)</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">e </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-token-function);">print</span><span style="color:var(--shiki-token-punctuation);">(e._protected_attr)</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># print(e.__private_attr) # 将会抛出错误异常</span></span>
<span data-line><span style="color:var(--shiki-color-text);">e</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-token-function);">reveal</span><span style="color:var(--shiki-token-punctuation);">()</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);"># 正常工作</span></span></code></pre></div>
<h4 id="__slots__-限制动态属性的添加"><code>__slots__</code> 限制动态属性的添加<a aria-hidden="true" tabindex="-1" href="#__slots__-限制动态属性的添加" class="internal"> §</a></h4>
<p>为了提高性能和内存效率Python 允许在类定义中使用 <code>__slots__</code> 来限制可以添加到对象的属性。这通常在需要创建大量对象时很有用。</p>
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="python" data-theme="default"><code data-language="python" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">class</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-color-text);">:</span></span>
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">__slots__</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> [</span><span style="color:var(--shiki-token-string-expression);">'name'</span><span style="color:var(--shiki-token-punctuation);">,</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'age'</span><span style="color:var(--shiki-color-text);">]</span></span>
<span data-line> </span>
<span data-line><span style="color:var(--shiki-color-text);">e </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">Example</span><span style="color:var(--shiki-token-punctuation);">()</span></span>
<span data-line><span style="color:var(--shiki-color-text);">e</span><span style="color:var(--shiki-token-punctuation);">.</span><span style="color:var(--shiki-color-text);">name </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">&quot;ChatGPT&quot;</span></span>
<span data-line><span style="color:var(--shiki-token-comment);"># e.salary = 10000 # 将会抛出错误异常</span></span></code></pre></div></article></div><div class="right sidebar"><div class="graph "><h3>Graph View</h3><div class="graph-outer"><div id="graph-container" data-cfg="{&quot;drag&quot;:true,&quot;zoom&quot;:true,&quot;depth&quot;:1,&quot;scale&quot;:1.1,&quot;repelForce&quot;:0.5,&quot;centerForce&quot;:0.3,&quot;linkDistance&quot;:30,&quot;fontSize&quot;:0.6,&quot;opacityScale&quot;:1,&quot;showTags&quot;:true,&quot;removeTags&quot;:[]}"></div><svg version="1.1" id="global-graph-icon" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 55 55" fill="currentColor" xmlSpace="preserve"><path d="M49,0c-3.309,0-6,2.691-6,6c0,1.035,0.263,2.009,0.726,2.86l-9.829,9.829C32.542,17.634,30.846,17,29,17
s-3.542,0.634-4.898,1.688l-7.669-7.669C16.785,10.424,17,9.74,17,9c0-2.206-1.794-4-4-4S9,6.794,9,9s1.794,4,4,4
c0.74,0,1.424-0.215,2.019-0.567l7.669,7.669C21.634,21.458,21,23.154,21,25s0.634,3.542,1.688,4.897L10.024,42.562
C8.958,41.595,7.549,41,6,41c-3.309,0-6,2.691-6,6s2.691,6,6,6s6-2.691,6-6c0-1.035-0.263-2.009-0.726-2.86l12.829-12.829
c1.106,0.86,2.44,1.436,3.898,1.619v10.16c-2.833,0.478-5,2.942-5,5.91c0,3.309,2.691,6,6,6s6-2.691,6-6c0-2.967-2.167-5.431-5-5.91
v-10.16c1.458-0.183,2.792-0.759,3.898-1.619l7.669,7.669C41.215,39.576,41,40.26,41,41c0,2.206,1.794,4,4,4s4-1.794,4-4
s-1.794-4-4-4c-0.74,0-1.424,0.215-2.019,0.567l-7.669-7.669C36.366,28.542,37,26.846,37,25s-0.634-3.542-1.688-4.897l9.665-9.665
C46.042,11.405,47.451,12,49,12c3.309,0,6-2.691,6-6S52.309,0,49,0z M11,9c0-1.103,0.897-2,2-2s2,0.897,2,2s-0.897,2-2,2
S11,10.103,11,9z M6,51c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S8.206,51,6,51z M33,49c0,2.206-1.794,4-4,4s-4-1.794-4-4
s1.794-4,4-4S33,46.794,33,49z M29,31c-3.309,0-6-2.691-6-6s2.691-6,6-6s6,2.691,6,6S32.309,31,29,31z M47,41c0,1.103-0.897,2-2,2
s-2-0.897-2-2s0.897-2,2-2S47,39.897,47,41z M49,10c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S51.206,10,49,10z"></path></svg></div><div id="global-graph-outer"><div id="global-graph-container" data-cfg="{&quot;drag&quot;:true,&quot;zoom&quot;:true,&quot;depth&quot;:-1,&quot;scale&quot;:0.9,&quot;repelForce&quot;:0.5,&quot;centerForce&quot;:0.3,&quot;linkDistance&quot;:30,&quot;fontSize&quot;:0.6,&quot;opacityScale&quot;:1,&quot;showTags&quot;:true,&quot;removeTags&quot;:[]}"></div></div></div><div class="toc desktop-only"><button type="button" id="toc" class><h3>Table of Contents</h3><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="fold"><polyline points="6 9 12 15 18 9"></polyline></svg></button><div id="toc-content"><ul class="overflow"><li class="depth-0"><a href="#生命周期" data-for="生命周期">生命周期</a></li><li class="depth-0"><a href="#特殊方法" data-for="特殊方法">特殊方法</a></li><li class="depth-1"><a href="#基础方法" data-for="基础方法">基础方法</a></li><li class="depth-1"><a href="#数学运算" data-for="数学运算">数学运算</a></li><li class="depth-1"><a href="#容器方法" data-for="容器方法">容器方法</a></li><li class="depth-1"><a href="#属性访问" data-for="属性访问">属性访问</a></li><li class="depth-1"><a href="#上下文管理" data-for="上下文管理">上下文管理</a></li><li class="depth-1"><a href="#描述符" data-for="描述符">描述符</a></li><li class="depth-1"><a href="#使对象可调用" data-for="使对象可调用">使对象可调用</a></li><li class="depth-1"><a href="#值比较" data-for="值比较">值比较</a></li><li class="depth-1"><a href="#类型转换" data-for="类型转换">类型转换</a></li><li class="depth-0"><a href="#类和静态方法" data-for="类和静态方法">类和静态方法</a></li><li class="depth-1"><a href="#实例方法" data-for="实例方法">实例方法</a></li><li class="depth-1"><a href="#类方法" data-for="类方法">类方法</a></li><li class="depth-1"><a href="#静态方法" data-for="静态方法">静态方法</a></li><li class="depth-1"><a href="#类方法-vs-静态方法" data-for="类方法-vs-静态方法">类方法 Vs 静态方法</a></li><li class="depth-0"><a href="#属性" data-for="属性">属性</a></li><li class="depth-1"><a href="#property-装饰器" data-for="property-装饰器">@property 装饰器</a></li><li class="depth-1"><a href="#使用-setter-和-getter-方法" data-for="使用-setter-和-getter-方法">使用 Setter 和 Getter 方法</a></li><li class="depth-1"><a href="#属性保护" data-for="属性保护">属性保护</a></li></ul></div></div><div class="backlinks "><h3>Backlinks</h3><ul class="overflow"><li>No backlinks found</li></ul></div><div class="explorer mobile-only"><button type="button" id="explorer" data-behavior="collapse" data-collapsed="collapsed" data-savestate="true" data-tree="[{&quot;path&quot;:&quot;Journal&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Journal/2024&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Journal/2024/W33&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Obsidian&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Obsidian/Templates&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2018&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2020&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2021&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2022&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2023&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Blog/2024&quot;,&quot;collapsed&quot;:true},{&quot;path&quot;:&quot;Personal/Book&quot;,&quot;collapsed&quot;:true},{&quot;
function toggleCallout() {
const outerBlock = this.parentElement;
outerBlock.classList.toggle(`is-collapsed`);
const collapsed = outerBlock.classList.contains(`is-collapsed`);
const height = collapsed ? this.scrollHeight : outerBlock.scrollHeight;
outerBlock.style.maxHeight = height + `px`;
let current = outerBlock;
let parent = outerBlock.parentElement;
while (parent) {
if (!parent.classList.contains(`callout`)) {
return;
}
const collapsed2 = parent.classList.contains(`is-collapsed`);
const height2 = collapsed2 ? parent.scrollHeight : parent.scrollHeight + current.scrollHeight;
parent.style.maxHeight = height2 + `px`;
current = parent;
parent = parent.parentElement;
}
}
function setupCallout() {
const collapsible = document.getElementsByClassName(
`callout is-collapsible`
);
for (const div of collapsible) {
const title = div.firstElementChild;
if (title) {
title.removeEventListener(`click`, toggleCallout);
title.addEventListener(`click`, toggleCallout);
const collapsed = div.classList.contains(`is-collapsed`);
const height = collapsed ? title.scrollHeight : div.scrollHeight;
div.style.maxHeight = height + `px`;
}
}
}
document.addEventListener(`nav`, setupCallout);
window.addEventListener(`resize`, setupCallout);
</script><script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark'
mermaid.initialize({
startOnLoad: false,
securityLevel: 'loose',
theme: darkMode ? 'dark' : 'default'
});
document.addEventListener('nav', async () => {
await mermaid.run({
querySelector: '.mermaid'
})
});
</script><script src="https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js" type="application/javascript"></script><script src="../../../../postscript.js" type="module"></script></html>