<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>MiracleRice的小破站</title>
  
  <subtitle>书山有路勤为径，学海无涯苦作舟</subtitle>
  <link href="https://www.miraclerice.top/atom.xml" rel="self"/>
  
  <link href="https://www.miraclerice.top/"/>
  <updated>2023-12-10T12:52:46.580Z</updated>
  <id>https://www.miraclerice.top/</id>
  
  <author>
    <name>MiraceRice</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Google提升搜索效率</title>
    <link href="https://www.miraclerice.top/posts/5dad38ea/"/>
    <id>https://www.miraclerice.top/posts/5dad38ea/</id>
    <published>2023-12-02T07:21:15.000Z</published>
    <updated>2023-12-10T12:52:46.580Z</updated>
    
    <content type="html"><![CDATA[<ol><li><p>加双引号“搜索内容”,搜索结果一定包含搜索内容，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">&quot;医学图像配准&quot;</span><br></pre></td></tr></table></figure></li><li><p>搜索内容前加上intitle:，搜索结果标题含有搜索内容的部分或者关键词，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">intitle:医学图像配准</span><br></pre></td></tr></table></figure></li><li><p>“搜索内容”前加上intitle:，搜索结果标题一定包含搜索内容，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">intitle:&quot;医学图像配准&quot;</span><br></pre></td></tr></table></figure></li><li><p>限定标题多个关键词，搜索内容前加上allintitle:，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">intitle:医学图像配准 由粗略到精细 无监督</span><br><span class="line">intitle:&quot;医学图像配准&quot; &quot;由粗略到精细&quot;</span><br></pre></td></tr></table></figure></li><li><p>文章内容包含搜索内容，使用intext:，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">intitle:&quot;医学图像配准&quot; intext:&quot;MRI&quot;</span><br><span class="line">intext:&quot;医学图像配准&quot; &quot;L1&quot;</span><br></pre></td></tr></table></figure></li><li><p>限定网址关键词，使用inurl:，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">&quot;Medical image registration&quot; inurl:miccai</span><br><span class="line">&quot;Medical image registration&quot; inurl:miccai intext:&quot;unsupervised&quot;</span><br></pre></td></tr></table></figure></li><li><p>限定网址来源，site:，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">&quot;医学图像配准&quot; site:miraclerice.top</span><br></pre></td></tr></table></figure></li><li><p>限定文件格式，使用filetype:文件格式，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">&quot;医学图像配准&quot; filetype:pdf</span><br><span class="line">医学图配准 filetype:html</span><br></pre></td></tr></table></figure></li><li><p>限定图片大小，使用imagesize，一般作用不大</p></li><li><p>最新消息，直接去官网</p></li><li><p>youtube视频下载，加入9x，如<a href="https://www.9xyoutube.com/watch?v=tiN6T1LewmQ，或者使用https://savetube.pro/youtube-downloader">https://www.9xyoutube.com/watch?v=tiN6T1LewmQ，或者使用https://savetube.pro/youtube-downloader</a></p></li></ol>]]></content>
    
    
    <summary type="html">Google提升搜索效率</summary>
    
    
    
    <category term="效率" scheme="https://www.miraclerice.top/categories/%E6%95%88%E7%8E%87/"/>
    
    
    <category term="效率" scheme="https://www.miraclerice.top/tags/%E6%95%88%E7%8E%87/"/>
    
  </entry>
  
  <entry>
    <title>Windows Vscode 配置C/C++运行环境</title>
    <link href="https://www.miraclerice.top/posts/8d0ee0c8/"/>
    <id>https://www.miraclerice.top/posts/8d0ee0c8/</id>
    <published>2023-11-27T14:00:00.000Z</published>
    <updated>2023-11-28T08:53:41.716Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Windows-Vscode-配置C-C-运行环境"><a href="#Windows-Vscode-配置C-C-运行环境" class="headerlink" title="Windows Vscode 配置C/C++运行环境"></a>Windows Vscode 配置C/C++运行环境</h1><h3 id="1-Vscode的安装"><a href="#1-Vscode的安装" class="headerlink" title="1  Vscode的安装"></a>1  Vscode的安装</h3><p>&emsp;&emsp;相信看到这篇文章的朋友已经下载好vscode，如果没有下载好，也没有关系，官网下载连接：<a href="https://code.visualstudio.com/download">link</a>，Windows X64我建议下载为系统安装的，点击X64</p><p><img src="https://picbed.miraclerice.top/img/vscode/vscode下载.png" /></p><p>&emsp;&emsp;当然有些朋友会遇到下载特别慢的时候（你下载特别快的话可以跳过进入第2步），按下图操作：</p><p><img src="https://picbed.miraclerice.top/img/vscode/downloadSlow.png" /></p><p>复制的链接地址如下：</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">https://az764295.vo.msecnd.net/stable/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/VSCodeSetup-x64-1.84.2.exe</span><br></pre></td></tr></table></figure><p>接下来，替换下载地址为稳定镜像下载地址：</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">替换地址部分</span></span><br><span class="line">https://az764295.vo.msecnd.net</span><br></pre></td></tr></table></figure><p>稳定镜像下载地址：</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">https://vscode.cdn.azure.cn</span><br></pre></td></tr></table></figure><p>最终拼接好的镜像地址为：</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">https://vscode.cdn.azure.cn/stable/1a5daa3a0231a0fbba4f14db7ec463cf99d7768e/VSCodeSetup-x64-1.84.2.exe</span><br></pre></td></tr></table></figure><h3 id="2-安装-MinGW-w64-工具链"><a href="#2-安装-MinGW-w64-工具链" class="headerlink" title="2  安装 MinGW-w64 工具链"></a>2  安装 MinGW-w64 工具链</h3><ol><li><p>下载<a href="https://www.msys2.org/">MSYS2</a>，获取最新版本的 MinGW-w64，它提供了 GCC、MinGW-w64 和其他有用的 C++ 工具和库的最新本机版本。（<a href="https://github.com/msys2/msys2-installer/releases/download/2023-10-26/msys2-x86_64-20231026.exe">官方直链下载</a>）</p><p> <img src="https://picbed.miraclerice.top/img/vscode/msys2.png" /></p></li><li><p>运行安装程序。MSYS2 需要 64 位 Windows 8.1 或更高版本。（双击运行）</p><p> <img src="https://picbed.miraclerice.top/img/vscode/download1.png" /></p></li><li><p>默认安装路径为：“C:\msys64”，修改为自己的安装路径</p><p> <img src="https://picbed.miraclerice.top/img/vscode/download2.png" /></p></li><li><p>默认，下一步</p><p><img src="https://picbed.miraclerice.top/img/vscode/download3.png" /></p><p><img src="https://picbed.miraclerice.top/img/vscode/download4.png" /></p></li><li><p>点击完成</p><p> <img src="https://picbed.miraclerice.top/img/vscode/download5.png" /></p><p> <img src="https://picbed.miraclerice.top/img/vscode/download6.png" /></p></li><li><p>在打开的 MSYS2 终端窗口UCRT64 环境终端，复制，在终端鼠标中键输入以下命令，按回车（也可以自己手敲）</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain</span><br></pre></td></tr></table></figure><p> <img src="https://picbed.miraclerice.top/img/vscode/download7.png" /></p></li><li><p>直接回车</p><p> <img src="https://picbed.miraclerice.top/img/vscode/download8.png" /></p></li><li><p>输入y回车，等待下载完成即可，出现error则重复6-8步</p><p> <img src="https://picbed.miraclerice.top/img/vscode/download9.png" /></p></li><li><p>现在可以通过输入以下命令检查是否成功安装</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">gcc --version</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">或者</span></span><br><span class="line">g++ --version</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">或者</span></span><br><span class="line">gdb --version</span><br></pre></td></tr></table></figure><p> <img src="https://picbed.miraclerice.top/img/vscode/download10.png" /></p></li></ol><h3 id="3-配置环境变量"><a href="#3-配置环境变量" class="headerlink" title="3 配置环境变量"></a>3 配置环境变量</h3><ol><li><p>打开键盘win+r打开运行框，输入以下命令</p> <figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sysdm.cpl</span><br></pre></td></tr></table></figure><p> <img src="https://picbed.miraclerice.top/img/vscode/运行框.png" /></p></li><li><p>在弹出窗口点击高级，点击环境变量</p><p> <img src="https://picbed.miraclerice.top/img/vscode/path1.png" /></p></li><li><p>在系统变量找到path，选中后，点击编辑</p><p> <img src="https://picbed.miraclerice.top/img/vscode/path2.png" /></p></li><li><p>找到你安装路劲，找到urt64文件夹，找到bin文件夹</p><p> <img src="https://picbed.miraclerice.top/img/vscode/path3.png" /></p></li><li><p>复制该路径，如</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">你的应该为，你安装所选的路径+\ucrt64\bin</span></span><br><span class="line">D:\Program\msys2\msys64\ucrt64\bin</span><br></pre></td></tr></table></figure></li><li><p>在打开的环境变量，修改path下，新建，复制你的路径，然后一直点确定退出为止</p><p> <img src="https://picbed.miraclerice.top/img/vscode/path4.png" /></p></li><li><p>win+r输入cmd（前面已经提及，不在赘述），输入以下命令：</p> <figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">gcc --version</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">或者</span></span><br><span class="line">g++ --version</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">或者</span></span><br><span class="line">gdb --version</span><br></pre></td></tr></table></figure><p> 显示下图，即为配置成功</p><p> <img src="https://picbed.miraclerice.top/img/vscode/path5.png" /></p></li></ol><h3 id="4-vscode配置"><a href="#4-vscode配置" class="headerlink" title="4 vscode配置"></a>4 vscode配置</h3><ol><li><p>打开vscode，按住键盘ctrl+shift+x（或者点击左边箭头指向菜单项），搜索chinese，下载第一个，即可汉化vscode，当然这个看个人喜好</p><p> <img src="https://picbed.miraclerice.top/img/vscode/vsc1.png" /></p></li><li><p>接下来，搜索C/C++，下载第一个</p><p> <img src="https://picbed.miraclerice.top/img/vscode/vsc2.png" /></p></li><li><p>下载code runner</p><p> <img src="https://picbed.miraclerice.top/img/vscode/vsc3.png" /></p></li><li><p>创建test文件夹（可以是任意地方），打该文件夹拖进vscode工作区，点击是即可</p><p> <img src="https://picbed.miraclerice.top/img/vscode/nFile.png" /></p></li><li><p>创建文件sim.cpp，复制以下代码到你的sim.cpp文件中</p> <figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="comment">// #include &lt;bits/stdc++.h&gt;</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;cmath&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">double</span> a, b, c, l, r;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 原函数</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">double</span> <span class="title">f</span><span class="params">(<span class="type">double</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> a * <span class="built_in">exp</span>(b * <span class="built_in">pow</span>(x, c)); </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* Simpson公式</span></span><br><span class="line"><span class="comment">* f：被积函数</span></span><br><span class="line"><span class="comment">* l：积分下限</span></span><br><span class="line"><span class="comment">* r：积分上限</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">double</span> <span class="title">simpson</span><span class="params">(<span class="type">double</span> l, <span class="type">double</span> r)</span> </span>&#123; </span><br><span class="line">    <span class="type">double</span> mid = (l + r) / <span class="number">2</span>;</span><br><span class="line">    <span class="keyword">return</span> (<span class="built_in">f</span>(l) + <span class="number">4</span> * <span class="built_in">f</span>(mid) + <span class="built_in">f</span>(r)) * (r - l) / <span class="number">6</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 自适应辛普森积分求解函数</span></span><br><span class="line"><span class="comment">* l：积分下限</span></span><br><span class="line"><span class="comment">* r：积分上限</span></span><br><span class="line"><span class="comment">* eps：期望误差</span></span><br><span class="line"><span class="comment">* ans: simpson值</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="type">double</span> <span class="title">adaptive_simpson_integration</span><span class="params">(<span class="type">double</span> l, <span class="type">double</span> r, <span class="type">double</span> eps, <span class="type">double</span> ans)</span> </span>&#123;</span><br><span class="line">    <span class="type">double</span> mid = (l + r) / <span class="number">2</span>;</span><br><span class="line">    <span class="type">double</span> l_ = <span class="built_in">simpson</span>(l, mid), r_ = <span class="built_in">simpson</span>(mid, r);</span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">fabs</span>(l_ + r_ - ans) &lt; <span class="number">15</span> * eps) &#123;</span><br><span class="line">        <span class="keyword">return</span> l_ + r_ + (l_ + r_ - ans) / <span class="number">15</span>;         <span class="comment">// 确认精度</span></span><br><span class="line">        <span class="comment">// return l_ + r_; // 近似</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 精度不足递归调用该函数</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">adaptive_simpson_integration</span>(l, mid, eps / <span class="number">2</span>, l_) + <span class="built_in">adaptive_simpson_integration</span>(mid, r, eps / <span class="number">2</span>, r_); </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 自适应辛普森积分函数接口</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">double</span> <span class="title">adaptive_simpson_integration</span><span class="params">(<span class="type">double</span> l, <span class="type">double</span> r, <span class="type">double</span> eps)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">adaptive_simpson_integration</span>(l, r, eps, <span class="built_in">simpson</span>(l, r));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 输入参数，打印结果</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">void</span> <span class="title">integral_value</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;请您输入原函数各参数：&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">    <span class="built_in">scanf_s</span>(<span class="string">&quot;%lf%lf%lf&quot;</span>, &amp;a, &amp;b, &amp;c);</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;请您输入积分区间左右值：&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">    <span class="built_in">scanf_s</span>(<span class="string">&quot;%lf%lf&quot;</span>, &amp;l, &amp;r);</span><br><span class="line"></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;计算输出的结果为：&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">    <span class="comment">// 0.139403</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;%.6lf&quot;</span>, <span class="built_in">adaptive_simpson_integration</span>(l, r, <span class="number">1e-6</span>));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="built_in">integral_value</span>();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>点击右上角的下箭头，下拉列表选择运行C/C++文件（没有出现中文乱码就忽略下图第二步）</p><p> <img src="https://picbed.miraclerice.top/img/vscode/vsc4.png" /></p></li><li><p>选择编译器</p><p> <img src="https://picbed.miraclerice.top/img/vscode/vsc5.png" /></p></li><li><p>点开终端观察是否出现“请您输入原函数各参数：”，具体配置文件参考<a href="https://code.visualstudio.com/docs/cpp/config-mingw">官方文档</a></p><p> <img src="https://picbed.miraclerice.top/img/vscode/vsc6.png" /></p><p> <img src="https://picbed.miraclerice.top/img/vscode/vsc7.png" /></p></li><li><p>正常情况下，我们代码现在一般采用UTF-8，在windows的命令提示符窗口或者PowerShell窗口中，采用g++，gcc命令运行时会出现中文乱码（GB2312编码的可以忽略）</p><p> 解决方法：使用g++/gcc命令时，添加“-fexec-charset=GBK”参数，使得编译后输出中文不乱码：</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">g++ sim.cpp -fexec-charset=GBK -o sim</span><br></pre></td></tr></table></figure><p> 注：Windows上控制台的默认编码为gbk，而g++编译后默认输出编码为utf-8，因此控制台显示为乱码<br> 到此你已经入门了，剩下的需要自己摸索，这里提供我引用的与比较好的链接：</p><ul><li><p><a href="https://code.visualstudio.com/docs/cpp/config-mingw">vscode官方文档</a></p></li><li><p><a href="https://www.cnblogs.com/Galesaur-wcy/p/16214534.html">Windows下使用MinGW在命令行编译运行C++程序</a></p></li><li><p><a href="https://www.msys2.org/">MSYS2官网</a></p></li><li><a href="https://codeantenna.com/a/nFsEMTUHyf">❤️VS Code❤️，cmd终端窗口运行，解决中文乱码问题</a></li></ul></li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Windows-Vscode-配置C-C-运行环境&quot;&gt;&lt;a href=&quot;#Windows-Vscode-配置C-C-运行环境&quot; class=&quot;headerlink&quot; title=&quot;Windows Vscode 配置C/C++运行环境&quot;&gt;&lt;/a&gt;Windows Vs</summary>
      
    
    
    
    <category term="环境配置" scheme="https://www.miraclerice.top/categories/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/"/>
    
    
    <category term="C++" scheme="https://www.miraclerice.top/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>Markdown空格</title>
    <link href="https://www.miraclerice.top/posts/acd52190/"/>
    <id>https://www.miraclerice.top/posts/acd52190/</id>
    <published>2023-11-16T02:55:22.000Z</published>
    <updated>2023-11-21T15:58:27.253Z</updated>
    
    <content type="html"><![CDATA[<center style="color:#00ffff">首行缩进推荐两个Em空格</center><div class="table-container"><table><thead><tr><th style="text-align:center">字符</th><th style="text-align:center">HTML代码</th></tr></thead><tbody><tr><td style="text-align:center">不换行空格</td><td style="text-align:center"><code>&amp;nbsp;</code>或<code>&amp;#160;</code></td></tr><tr><td style="text-align:center">En 空格</td><td style="text-align:center"><code>&amp;ensp;</code>或<code>&amp;#8195;</code></td></tr><tr><td style="text-align:center">Em 空格</td><td style="text-align:center"><code>&amp;emsp;</code>或<code>&amp;#8194;</code></td></tr><tr><td style="text-align:center">窄空格</td><td style="text-align:center"><code>&amp;thinsp;</code></td></tr><tr><td style="text-align:center">标准空格</td><td style="text-align:center"><code>&amp;#20;</code></td></tr><tr><td style="text-align:center">换行（Return)</td><td style="text-align:center"><code>&amp;#13;</code></td></tr><tr><td style="text-align:center">制表符（Tab）</td><td style="text-align:center"><code>&amp;#09;</code></td></tr></tbody></table></div><p>空格字符的宽度通常有 4 种情况：</p><ol><li>标准宽度空格，又称”不换行空格”，因为它会禁用自动换行（或称回车）。（译注：这里的禁用自动换行指的是不在这个空格处换行，其它地方的换行行为不受影响。）</li><li>Em 空格，之所以被称为”Em”，是因为它的宽度等于当前所用字体中字母 M 的宽度。（如果你听说过 em-dash 的话，你应该知道它是宽度与字母 M 相同的破折号。）</li><li>En 空格，是宽度与字母 n 相同的空格。（译注：这里指的是小写字母 n；宽度为 em 的一半。）</li><li>最后，还有一种”窄空格”，它是宽度最小的一种空格。（译注：宽度通常为 em 的六分之一。实际上还有宽度比它更小的发宽空格（Hair Space），甚至还有宽度为 0 的零宽空格（Zero Width Space）。）</li></ol><p>以上内容为<a href="https://www.freecodecamp.org/chinese/news/html-space-how-to-add-spaces/">转载</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;center style=&quot;color:#00ffff&quot;&gt;首行缩进推荐两个Em空格&lt;/center&gt;

&lt;div class=&quot;table-container&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align:center&quot;&gt;字符&lt;/th</summary>
      
    
    
    
    <category term="Markdown" scheme="https://www.miraclerice.top/categories/Markdown/"/>
    
    
    <category term="Markdown" scheme="https://www.miraclerice.top/tags/Markdown/"/>
    
  </entry>
  
  <entry>
    <title>保持肿瘤体积以进行无监督的医学图像配准</title>
    <link href="https://www.miraclerice.top/posts/e15b908f/"/>
    <id>https://www.miraclerice.top/posts/e15b908f/</id>
    <published>2023-11-16T02:55:22.000Z</published>
    <updated>2023-11-18T12:36:40.449Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">  <script id="hbeData" type="hbeData" data-hmacdigest="21635439537a5970a0daf6d919f4d20ddf79b2a767bcbc51dde08f3b08194ced">ddc360d448697775a77dd4fde850a2c0e2808ef0978c01a27c380987b2f2c834ae9859920eb947e49f3883596bf1275e9479f4c791ab90d5170acc02bc50daa3a1a3c3d9fde905954d8fc0563c1f9ddd95c00c0266b589eeca463dbe332d498a58de34f47966c17bf536ffff2b24df4addc74e29e35a905a5406f1388b0253e04e7ebb29c7675260ca8c6e584908b3d08b18e991accf3c02efb9c05c570de17c29a3680cb9648f50eba7c425498631247ba1b76704af882f3c1b66f7e9d27752aef9ba92341a552327e11b7508799262379a9f5eceb879f60e60fe788c2889628d7e78a5a0caa71acf6f6ba339d848ddea81493fb38e2b5f3a5bd036a06bc594a4225d28428613567973ddc273434564e735cbc9d3172b58c00dad417b4ada0b1792c8a6ec150765044d647a01046888a383b3d7dca11ed79094bbe328ade61ed1c2c3ee7c47553289a4355f2563363076111eb90e89ff54397ff8eb002d492f14be2da5f7d2b399380126da02b40da664c4c76146fd850998a8cfbcc81b7dffbe570e28f815b6a998d49203ed2ed1bb9aee0a976c9046f4d9186904e1e0f9c55a5e4ce52445ef48c01df16c8aaf2287089bb7dbb750cabc385be5cedf042f1b9a7b7ec12c33303b507fbbe4b23af428cdf96ab492be1178b5ae15decade64d2b358517626151281bb8e19c7cc625a8576509189aed9d67a19e5ef4e5f4cdc15dcbb140bb9a9f24e8023178974a75f065002a5f63ebfc80cf7957eec42445bed19d1f2a7a0b7b91585ed898a554d124e0bf6187c99bcd32ace6736703f0720591e4f23f20ea65bab9f0fd770b76e2566ac3282b9263e3ee8d1e36b506923b2b60b9c4a144b96336a57aacacd77805e7a860e06b090c21ab7ecc13629928694030b9bfcfdab32691b5c0cba23f7ce6008f41f6333f2c3345942ac6c26bb10dc24fe26eef3481ea1f9de5e357263bfeec59f63661638bbf7c646f2121546d3f3e8765d1a25e35c6094b6e8d72c6526e460814a9d0b6e19bf4aaafffac9ec6fd126949b599123146d1afeaf7e339f85a3fcb3a81b1496561a4846387a905b0f64c0bed2499840f03ad6922ca01094f0a20b118fee749ddcbccd3af2847f9c60177ba2c547d58b0d775e2a1881a30b60705ce71fc450629d879f613cb23ee2b802d51485f897f41ce030aa5f209011fbd48739a1dc45043165bb7831f3ac56d9ed103f0f281ff3b1a12dfaf85fc1ff2afa243d92ea2511d7abbaf91e72f249455824c50b90f9dfb2946b350689b6dcb088f3be0b922e59bfafc3ba08e1066325151b9690fb50229f076162b5b68fbc1cfbdd62fd9930e91468a16b054e7c5867d2fd9288b449d13bf2c8d66feedd84ffd3f532b47b16172f522924304e077041be045fa6f7c47c4a2be0ef2140e04619ffbcb71211f3effe27ffabe14259bf0270729a5885e1ca232e2508898e56c98e29e761249553f759b0de75f74257a4cbfce993c2edafad9da2a91ce223c49aa4713046973eff39134ca22ace449023807cd7112edf0a7f30109655c97440674c7dde75f2f84a8284abb1bbbdc0711862a1aa001ee2c57bdfb34923311aed4eb7e61a8ad911f76c2f263719b5d0a6047f5a2891bfb58680694a58a9b7add3a346fa26c131e5091d8f13e052b71fd16101383edd21c95935a08fd8d112a6462bb18874ad7c01b5285e21ab12f72f8454a3048b0e5d0f391ee556d6be010167c63ec53198c30c4f7544003b54096a23c35743001e3004fc44b69d44c3599b90b1f3b60d7e1fa290cd749eb6014e34816cbfd85b317bfbf46e99377e4840412276f1cd76acb5f81dfb8c36806150ab8aa479c4be9c97e20ef12a5689c2dca994222798f191a2143e04cd922b73d5b583c0cfed6821b8306b39c2f067b83e79057542f692e572acb6e9865ab027321c3b94b6cb28f05aba5fc190e9406c42a36a7294ab3e61aebfaedb3ab6bf5554b04340fa298e752d17011d6f1a438a28c55b2ea166aac423997e5ae93c93424cb66009526c3d2dcaa9199a15858981aeef5b15eb65dd82d74b5b3ed8762463d37e795898c8f055aa4be2556faf5e5d423fb62be0a2b1186c45293c6697e49b20111b50511a18beaf478dbd2725e07419d69894b9b5281a67ab11f624354a8e8a91d23919356694131a3dd8e05e7c10865e2be30c2cf7c496c2d7dc74b26c9a9cdfc9c3e0ebc77670a30a127b4d1c6082b612d99cc155340313d236092d0e779151db12df0e70ebebf27a474807816122df711c1cff0bf7dd1c0e8b773e6000eeaeb2f51306b4f50af73adb1cb7b1f5f621431e44b430a3f4685a7abd5d2b79a2db9b2e4eb8a8219c87cb0a51819c366fdcd0b657ad9b8ea8b0945bc4863bcc739202282a30e6622c0af81d58ec112d1c9b35950cb955637f9cac460a21643496aa82d1cd2114e217734b678f3806f73ba20cb14431c22b34227c78e163bb1e4480a98779970bbe37e7d8c14ed7c505057ba853b74407d6515d885bb2ef3db5433877e98652e28c5c4b3258adb491f3ee51689fe100232b5658f0cda34766e5e149d3889b2e5263ebeff71e5cf0304429fa370cc61eddfc73585969df29651425346ab209342e67446c30e91bfd62739225cae8e42c97150e920b00ef1cc6fb939b299a8dc2d123d87170131a2da1611f3ef2022145bd46af2dc4c77b842519ee74dce50c83b6156d5ccf069e98b2d6fd30ab2a4a70208e535ad56437e4282898949ee1b515c89a6d3cbd691a9ef0f979288dd1f633b5933c5c2e34cd07f7f2cf4ddba7263a18c3be14c28cd87d0f467cf238ea8c2bb9c5e66a7cce8db7e0ffc64500be0115024d8bd16841d98319f73dee4b9a3c7a3a0c3a7eef911870af49ad55fd07ee6639233909799a8c90600218ca4a6b8a3b78e9107cf0bedd6661c427ade8c54e344b6d7aa31f8a93547d86d47f795877180e2ea0cd241aef521afc2eba4777cbba3b0501f1250adf9492572052d588aca656e37ee94cfd21711b985c65727ae704f24ebac9d095b7f47d6067ad4ef3d9782c9833c09ee9dece866297a9fa63c4432610dd028ae2e2f0acdc4cdb8231c22703b80a486d34eb7fac1dc2de8d2940671e5bdd12d66a957f4a32eca42c5778451f7555325a3fba3e7c0b48d8aacf4006a3eb2e6a60d2e96c1025c0c8847ad80e005b7b9bb4fcafc22f385d51f3832a1eedf24523c9c00cb2c6a410b7cf5935186d310a9683e0c4708847e936b1599b8e9607da41226abf3322791d19e9e3a8ffea2d88ce66ae530a757a6a134cd9df668dbe3e44b6a5f34e6a004920f3ce37758c1d57626c1e0227699df71e20c33eb7d53ead81f71d94dbccdf650f657be6c8068d70a0a8f38e909cac86d352f524d30f7bc42b103b6c6d7bc948926fe8969414c05d74f458d7339ccbe865b210cfcbc2facdc3ed19256f2524379ada70761eb22aa2ad1e92009c05079e4cdba57d60296db994fd05cd12830937ce1c52af983a829a99be0ee1273ff96dbaf62fa9edaa5c10b0717d71af157c67e63d55f223d3c7482bb34c6755d6144f9fad14d50928f125666682bf7ad9716b2979a6292e9aa39cc699caeebe4a2a8fb92f5c19e1f5fa0b37707d6fdab7d5b22611d113c15d0da484a0997c7479a22f0e10c5120e4d239966cfe2766abc30af0d2f82dc5d53d1794ffa1c4d68ca0069c9f26c1ce81ebdb966d889d7398a920e86986f21dbf08ab5e7fedb9b236a706d81d1cb8c3b89b73ec864d3c7ddab85f1ef0aaf2bf091cb39a1309458dfccd3e6057cfc87f7a675266c0431c74b2980b6186aeae6d8b09ef824a19d46123d4bdf77d3763f0bff2dd0b843620afbf1081196365961ff0fce7155c14a6543a78137d161c6d34f1e6829e43a46ccc7e0798ecf437f1edce87785f0afb36b30e512a99d6918afd4d261ce2d18f1f6d92aa138f8f815c969f1e7e9ca39f2efb37c9b4c8ec9f60fc84324875d8b0737ae2b876f1e21f0612daadf3915dbf72cb8122391b37259c23243f5867262cb8dcbb15cabb02ab4fd0887b4c277e89dcdb6b0d0a7ff67f9f0972fb03deafcb9412973d910aac234a249452cd3d78b9909abe8cf29446e95d1d487f8cbb3c592fc0d0f2ba94e3ddbca511618ee34d3ad781c4d0039f17e8c3831c0fb3c3693c9cc7f2e132d4692bc9cd92aa18a2ab643e38c6da788070019bc7ed900c7a2ba14f41e04ac27f43b4ffdc72620cf76c960bb507cf14711f558688fc35252cb810de33af53385a20123eabdd5e2c370835514135c841d52e13415ccac34cef0f9097990acb1351aa1a566d2fdaa816fba0a443442672e21b4d40fe646dcf12ef3b3373264a4ef2fb9950e146ad57fd7af4ba15529bf2eafa0e68132879057ffe2d9172717bbe9f5338261458b3ac639e5f72a027ca7900b29d871ec01c9460119632440404eb837d7f323f4aeb14ff5b474da1bb31271d7f3593f64b535de676615e6f597e0238d06af1ba7e8b1adfaa56c176951fb6791d95679ccdd6e9ec0c0d164dc756cdc07447b7a4873280c560c1073d60d7896250bb9c1872c1608c3847cd2ff0206afd7b3b0655743f6e6d6ca6b3d8407621db42aed43b02e9a719cf21f171e625936b8d7f1a143f20dcc3a04f7c59c796085bd10a50b748f6c595f6ab3cb025686b8f5cb188ff09a65c4dac293458866b6e3d6707c55acd71a2d7d4833ad03a9a17e3f7cdb61f5bb3c6044bacb05ef92564c50d5c86c902523b8505a05b10e1b8f22539ffb1d2d36f00035ef64164d9d16a47d711338e7515e3a0e90276e53bff3770da0a983c611760ae04f6b5e192cf98289201ba1add279616d08bca8781e4d474db37eb0dbb1081dab8c61314beb2b384fd6ca6ef63898e2e522270e616ab40f70cb1cb059b747ea3a6950328b76e627df048f4c2a9466fcb61ae3042da5bfb0681d5e6a08268e95692db8cb0b1737b7a8841df2c0bd250ee7d0ade4ca1b5380e6f3b9d8af05d2606f041a0cf3dab883d86cbcc59289ad64211a87f0ee1723e1044ef5d3f58c7e0c95e1ed124933e7796de3ac2a7bb9a6f3be6cc3738e37a7e434c46c6bc632a2c174610ba11210683b7eceedd336003c1de350c2e62b2e7efd9a247e17fe6c0a93a72be0d621e664bcdc8bd607bc5fa34680433f300feb0e5dd6f1eef871a6af088a5c5476ba13398ce321456067a3633769361e94a074fdf195c18679127e39e3089f72630130b9a64b39757867d478725d4ce7b2a25c31800b2bab6545f36299579ad26efc9699ada413dcc1141af740741fb2faa555922243badb3afbe4d36cd9163d03a64fbdc15a5bbdbc94ced675bf2ecf5f2860c149d30b0eea04f999c47e57a1626b114391ade0a568a92f07cc1bec40bc7d7ad2228a3d70299cef1e8e13f95003364bfd5f20b0b5acdd0701e436a6274df3a14d771a13c10dfd267f4543e1fbc0a72e61a1a18269d5f2dff0864d9600f5927c929be1cd933f4730aeaed5035bb6e1268d875e86e3ec61cae7da1221fa9e835bff16ac3da5210c0bb84441421806202abb05f4c77c92e6e53113acc74a45a89b32576adb20bfbefd11551e5548edaefed5959b79b38b2c7f67a82b2d291803735927e47fd622d88255add09fc44e9c0d6f08d1d48507f7c1748c002dfaac302d193a6c4eedaa73606cca1b38599117c23247a9b8f0faa1ca292be6d40e56309c2b2b82c616be3abb026c6592bc9c4b286d72d43f9b97d7d4eb5aa722d46c7bbac9c251ba45992cf2d51c24cd19d7d60502ebd51d3bfc2675a013478be14678e2fbd35b2dd2f77580a45e5ab4e5e30af12fba6dfd0f5132f02f020244fcdc54528230c5c012e288e89a64bdf8a36ae2df5584fdfc66bd7868e65b3439d31f929690a540ff3402155394cb42e0ace43102855c3f86b94966e6320bf5f24fd23535580a33baa003583b0a35c296b34dd5dfe49eb2b9723a738f26041c3c4c13ad9f9d523b74895ab584c27acd63dd6cd73055e7498c4a6a48dbae0365cc2a8bc47b127ca2793dfb816caad0bf06ca601caf5fcccc2c9d6c7da5ecf083bd6fe197540896bdd91d0d425babd904f40ba72a059a9caa40b03db21af2e2bf713de1fe0e65a8c90a9f1b806c481fc71012615409e0e6b7f42163ece0c0262a3fa4925854ce8ef3f56cce2646a86ce7a0abfc3b3a5dbd44eb99018d5cd490903a6747d89547d2d7de987ce72b507f54c4c8570ce608dded1d5e1b3153c20e11f1cfbc755882884ce06ea1d5b1fb15a058616586a7656b5dbdaf8056f97a2b4b170a676e726c1bd166fcee857662df4fe4ca6d1f69dc780658df494845dc3d26741d4a02ee266ba4322e23914c9724a280c76f2fee216e4bafb80e3fa4a716ae932a3b9017954413c9862019d25220624521d1166f65b78bf225f4e767342db7b0211e5f3b40022e528417216f26e5a155378df21ff0f37175a3923201acd5419b3bf6eeed612bb8846d9c1b01c332b3459cea7796d152a791ddd6f42ab91c8fb4b65ed9561939dc8a926975030ad0a3ac10af542fc25c5233f49ae47c394178e5817c99d628b301d6fa0b7fa5990dfd773184a04ff476cdea0ba171353e3194ca7f3509a4746079eaae1c85269a2681fed38145620af7bb46c282eb474e3abd62f5d16738b765304e6563b6c630d2ee1a84b656b3c0a019940b9cdd716ac3e5716e40b5c56f6fbdc2f698236c7fbc34d3469a92547ad3e2d12faaedbbeea681200730e2d6bc2c90b19ed0e65394bec117a5ab70c4bc0c42e804ce3050af94521bb5b6bb412aec6ba4ce2152b7a629de1995bc7880d62a2c884e6e54cf52b89b68331c4d9648a76188a214d6e98dcf37278ac40ffeeb16cfae3141f5b6160a6a271d4f9e9b04b0dbe4744d94f365d7d1c0155db50678a1988bc4dcad4dd0df32a16cf06ace54543f4bdd6625ac538e6ca08b92086b3bf37f292fc8273cf26cd81595e55c3f14b7bfd55b56670ce78bfa196f9344578cce6d7a580604d517a498533e2caa7fbfb4c2810d26fd53f8fbfa980771cefc6c762a2fabf19aa685d9288494ad140985cd2fd9efb91e2e4cdc3a58f2bea028f5dfb16b60976f56d9d56b71915525e652f1e6f7ddc8d0e61fa8ce02f579476b872e02e8dc0719a1cff9d7f0040343eaf456444c281c633d95b35cc1edeb04cd29ffa78fc1a2f0991aa232e53bf83db1f8f14363a13e006e2274253f36a3d7246241bfcffa14e33f231a951c6c414eb0b5985f574f12e95aaee6d7f392c5db616280c417368fe94f97ce123884be0642f4079519a10b6566754a8a12ea2fda37fdf25f8358161bdb0c4374ebec626a1d76698bca00c75ecc844a5c45a3977110706d510c4bda49c6867a45409f6d8cd910c13689713928466b93f42f1b62ee882d7e7289e4adff0765f50804b327ac54559625c11700ac34895aac7f03161fd0fa2b25dc99c0d9da170ad7337ef7949cf63ddabd1e1464d8cab281cf3c1da6dbe2ff30b347b5b2f13bd1d2482c3083a61ad8c267f0c772901a66a6efa79cf0e55801f7d7944dc842e61d0e7233e226f27b5469e4ddb378ae89479313b843bab74493e85571ffa5355662332ec702e63ce672df9a82b7615738ba94719a31c731f476f9501e3309fd360458c97ce0e0495f7989514e4786ab0d154c6125e6ede4de0a0b97096863365aca76b7969474c064dda25d16ad83c7d53257e753cfe360f80fe709892db709be01dd0cf11601e004045f5eac69e4aa0ca997b27fe6ebd220b4f414d325d9710adf16b2f2a282c76f63dd7a8dab3d195af5e6b52758a621077e464554c9900db22bd1c7ee981bbdbfc4c704b4267afac2d89b16fe494fbc885fb79b562a699902e4cd84ea048fdcbcc0da99fe19573c9f0bf55c9a403fcd9e50d8f0ad4902d23b585961087dcee234e633f44b95139dcfb354f76a482caa3c6bfe8cd7a076fc95330abd601f8762a5b4199c3c2237dddee606d267fc8b1cf8254f9818d8528e571fe220e5f8bb934b8f35b6e188331b6016cf0597444b2d7c41258fc0bd8d480c78433e0f3f485fac88f8a8a83886f5e9270609a6b476f2d5b42427fe064b5ce455cad2318ff9c5ac592aa8c72fa24be658f0e46880583eb174b6971f7513d99cd2eed69bae11736a7ea320669c75318ded7e5f4af2482011c97a0645fea0cfd615190b7f04b632ee48c8bdab12c17ea4019275b378d008232b9f2543f0d8f152ddd1853f212783e548342a3fff1368ed56eaa47b3e62c5d722b095aa420f4c6e4c58c479a1224a8a896ac7c146034bcf313a6b1f96e933375f4a42c39f6ac0aa20e30955115c02480980648082546b0451fd407a9c71b9f467f5edb2d2704100c1cc5b1d1ac70a76d59f926e473c0f7abbb604aaaa814a32b4921da97a0190c41478926c6281dba4411c88eeef29dda988a7c9f7d8ef09e9d70ab94472c0e7d34fc17b97860173654bf65e5c3938fcf2906b11561d9a71e4125cb5de5431382f8c74e33cc3313f375af181deb90ac627ea3b830692c0a5952d597b6ee088ab050dd2ce5775a2bed11d124f6b0526ddc5fb6d443b096bb3f46aee1cd84cbce5d75a80b906fcd44efd230d11bd8a6eed3c7be73b9c769e3e2e883bd6572adf073f14cf00edeb4bb5a818b06ea92cd135eee80e25facf122ac1ff3f781c902947e8d1fc650f5935edaead50e4eb953738850bed5f253e2a86ac32d43dcc2fce398bb2afdab10f4502b2abd0fc738310840e5c2b075a05e05ad3252b132cbcbf5305474e9393835087ad939bbc06ee4031a0b466eb589ffeb71e4719b22bb8a1bd694405c627cd0ec9bb3a3559084816069e4100b6af08cc060be403df4f950192874790d9161da1b5ee8ba89199808cf080a7e43f6acd420afad3595f1af76d2b21788a68f2f34e59e6363baf2e06002d4cf56e2d0b794763856286cecd03ddca1eb8cecc019a1b4f213fd5bf188b36137476eb3fed84ea0c2bf1b1d9d2805914aafcad57cdd20008f9673c21a077850916a9fb4043cecbeb31895e036a0237454d9632f6b56a9e2beb8036baff3a58da29476622ede4ef8f85836333e0d6fe3204f96da41da80c871a1249e7c24457853c7ebec61fb1a624d9709248c55c942a7abf05fd784aec888261850f574ad323de169020c0a684c433db139ea0685a068e9661a5dba9cf1c147df4222cf82ac3cbed831361e545a7ce8d78507833cd9465622d73c8b2f85b61d7f4bc6bc2c815f4ff4c4e704d61f2b1944477651ca463c368895f59591741559e5620b6a06b48f8fa0a20d9d5e4329ad65e936e1687f4e61f82b31738ea99b2b20460c42917d74e83083da4ee825bbcac8c9592502b5b62783f9059043712931d5f148f45986e07b31a899bab26b8421fbeb57b5d6dd83ffd79118a1f6fa2d3e74609c3ded41aadcba44e748aa5746bccb1626a110a6d4606833398d823529ed6d89cbe4849c87de8958f8e478bb5d513c261970be280c8e2181cd286a60ca02250d4d790912f2c331c70eb8a4b50b67cb659f9914d2f08de46697cee41618ece03e5012d6aab7a6f25f29d90f11032934fb46db27b4bb7451c8614b65e96f90442f458391c6f76da009043c3696a2dd53d2d631a875d6c737f4959fd5da0becb0d3399352d1e381fc2374686f359dc4e753d48e682519f8f086080e364626e599e89f1c851c62f2aaaca97f902c255ddba4ff9a01a93e5eb7694de46861fae000dc17d1906a3f0600050536deb9c975c68fa06dcaeea3f314056f95b9e9c2e61b768bbd6626d90c725d82d15a5f8824a95d15c5db688dae6572f45f3aa20aa27bb24697f4a560a2b4b545f7345c7987800191b2bcef7cd7ccd9ff1418373e8255de046a335c8baf9fa3b16491b40eeacd576375c9be0747605d595c4b4830aa83e602b0197a4d9495c65377f5a47814c6945e72e51097dcd24b7e5696e56abf5022962dd435d693766249dd25bd80a9f9f722d2a65ac215c542056306f816e8feae9e95a4261d1e6729c9d81abb13809de37ba4587faf3c81d4a85a70e4e722882aa2f5aaa0a979c64e297a2e246b6a877e048fc0133c708abc4e664b73cf1502592896dd62cad90f9003ff580aa21674b7001c4f06344420bb41dc5e934626ea421153cb85a5c908de7a477ab2b9819567193e4bd3ed80c4005b3fc8181dfd42a36c8af9fca53445e2ccdbf668afd9968610b38af77e05d10fb1bdbdd01a1463dcc3ed4539ddf262b7eabcc7dec52a99078ef5b42abdd7b5fcbd08ec977f946b6e5b214de779f9b96a0292b89d0649ee546c85ab7e216825afd60f20b461ed8d32a3209b7380637769985455d468c2939e0529fb97de31f9c2da6665241bdb6878ae79a06c4104bc0eeb22c6e5e3e5f4ec5e15415c0c1b287e8d7eb47af7ea1f7509e5327d9b397b20d08bdeb4b69c08e423c8ed158117d5f050bd969cca64334d85a9db8f579d2d355cd3b31b0c3ca19ca8bcb6bb068d87f02841f0b0652f753456f646c3ba1374e95accdde8f31581d0982548a2fc4a1de32deaf04f692565e30f7097c7e3ee39efed7634692d1458c6c62984abce4bef4f5c3295be6c0afd6cfe25bdd3952dc3eb28376c71ef549b98e111a20263453d495f67da2bb225166a00349fc4631704d48d0325b3dfef3bfd7a3e657538f9252aba51bb31a65da6aa03a76382e3112ae869f6b0e47211faf3dedb9b6e57f93fda3cf4e15120e70dafd79a44a1e4469f75886d0a39314fe66339dce6639cc9da13f5ef69c403724620a8a2a1bdab810e804105694ec8795682d489a735c061894345b751e96e64c10ebbd204df735e20c8d7091f06a5accf58b7a9d8957ceb40e4e22bbfca182a60f340ca1b05e5acdda45080e558697ab909b29c3384c7a82e00b7223094c6363a8a79060906ed2aca39fe631466250eaa62ff2ee1ef96d138eab7433f8ac6fa98c18d147a0e25ce9e8768a418c9304b806d624c31874cd8384ac06a04b3f1f6cea113243a3c7d5217c3953bf12d51373f39dc84163e849ff3f08034651c59dc2a50b8f14cdb3ca86a8fdc49c5d78c464bebdd7974981ba05efec344e12d3e4385522f5f3cc7f3d53daac3ae3beaa5223a16b1b8d4a4cff0bd5d4580f6fa142215324f9c18b4e4b0c8472a2c1bb29d5e5f4848da99b11c896748d7b98d848a819f615a0d4661e758f4816ff0eb5d45d7dd743626a18d9f8a0006d7f86c8627c800e946f7159015516a3f0a83c425c46d655b0741325b9c77bb597de4d7196fc4e985e87b0e99342c97d11f3872d3fb2aed1a8b6ea6f1bda32735b541342f39877903f7cbf902a4220b790fce286f04c4cbfa571a3d635613ad34abdf110c18f5568859b4876524e6baf0d359093967cd8e0042cabfa0c7e90864a7280e1e60eea8ffdcdf6e96df25f3d53700a256b1435de8a34b1940edc47b96306b224682e8f24869d82b324466c917da780923e7e62ae26aca3756cc7aae964c7d49ef24a807d6a29d7b892851eb8e1fc98b2a1078e1379535c8f0f522d7d8670e379ee9bd3375ae90e5e2429d0e995fd230aedabda7a2373f3ac011c5d3b0d67c406b2b250f507d384a0007e8d8a29ff0468583bffbe44562504a2e1ea8fbfd93c8c7f606f995e442a5332a4b5aa77bdd5d5d45b17a31d9eee863fb0018a2a80276665c1a60ab02745f7287c87e707fcd5998c98da62e0c9655dfe957f8dc55857c8113148b42e9e64c9543391e5904ef5ccb4efe0bf5eacd72b0b3946135b528be9100089b1e4904f3a943e890090a11f239850a27233b3cbe1571d1660442d5d2b22c3060e6092847bf86dd145507450fc7b89028bea3fe8f241a9b273a2f69d63ebc0b2485a8311f48ae6cd53f86e0aad4c9f19b5da1c4419ba71081ab4ea0ca4877f52889dc12ce9f0816665f116c9ee9c8afac5428b9531a89c9643810e5a1b72952fbd85ad2b4a5fe0acf2a8e3d65fd1a6d6501509f9eb1944ca6790fc8b44a31464a046bf4d9172b6264d618734c09df20f127a56c98ddac00be9926302bd9346a863357b4a2a43aa3ce811dba8311994f18a23197aae33cc414ef789436fd57b630d90fa058012a3597a6b665773fb3192f6d1f5ec7a2a399c6a701d02a6f60e1f722be43945c66c1a65e62b56dfe156a7e0b250d08343e9dfbe37e23934d5a99b936f0ca069db97c434bec8fb3c3c423d4cc3a1324f06e106a4aa2397deafeed2b823ecd3758537f9756773baaa336ba2d6e89ca7c975c806d5754de27c23c691bc8ff5d091327ce821397f2c6cea597e87002ad61b582085993874981081c598bffbae12cda05987d4d31ce1a082898c271ac6916a98a086f8ef16c2fdf6a558e10ce4e9f658276fec1f3d7233532dd88efb1230dabe6ffb8adc5eca7e724c2d26ceb50b367417216189bdb44fbb49d48a4bd57a443ceacfcd1a0ac5d64383c8748213828db36c9cf96ad17aefb3780125c48d14a3722f01f890cf0c400976b48d628d44baa87c4938e1e3b18fb5888480ffff0e511e126daa236c615ddf76313fbfd1368bb3f21df1a74ab77938e2124c09673f4c24a7c0c8e7a1e746f322e695039cc283fc373395b646869fb14d870986978ed1ee1a239812ec083980a5e1ac92dab7844e819c4cee9a2bc0009d2da7463f63753ec7c9e19089d3e11acb900a7356eb862b7aa9cc5b3f3b4f8d04e6f0044da24e5278a9c5de1f6e1ac441ead84196547392ec44f6f11f2ef5047ef5c93460b10abcbc3f77ee78041950ecce5b4236f087a267eb794f70df7be7e30b7f618f4432c346c104e38d15085ba077870a60068629be8d0fe34f08be94b1f26b4860a8698bb271af2f26aa75fecb79fc79027ca0ff9a73bce749b2133c261a0239d424a60fe5730dbdbcb353e9735959517db7b00993e1558258317c12a10c1139005ca8c2d6d751b0cda67a68db6df09ee4d8301c400eca3aa51a32ccef16aeb6c5264048cbd2dc02dc2810868554be8f47f15ec89528d212468d512c28e28a6b7182b4b6065229edb2141b54a41d990f4710cb3fe39a2cc57b5e20c34c4b6ae912961825148ce5a8c3c33693ab07d1a36ff65d01d4cb138f6fc7e8ba032861a4b6642fe6abcb6b7a67402fce4d4ed557348785769f0a6fecbe18ed899817ebb3c4d84152f0e937a3fe74f54d35fb3326c500f11d508033012b42dfb1e0c49de8c7b72ca5e1ea78f399c4823ba28bdde8cd9d42a2f35190aeb3ed651db2b326d7dfde93507d38d2ff0d3a5007a7f899f171dfd225ee038421db18a9a911d9f6d72984c2c93cba26157c21f3f669bb67f33a8ecbf43fa1c964e3b181abbd51ccf06f1a5b90a89a86d37d5807b0bbdaa87509a18f6e3ad12579ffe0cd34f4fed3fedc1390eaf017700188e0a074bacdb21cd500764d3af70032eac95de0669b694883ed08e3c2f23cbef0ce12b3153699005fe520731bbab382d4fc55c28fe88532837854374036b09c7782e24320ece55ae91e60385e6e6206b7c8bcf5ea000249ab81f7e574e2b5d1053301abe5512757070504e72466e303127de4465b89ad468630d5bf6f7de5a01ac9a4bc829ba67dfc07e5e93079630afa724cadc3a93755591fedbf9d56b34d5e913404b510c07d7c229b9ea72d2f70ed31914c2a9ad3e8b14bae33ff6c96f7c02be64e0792255b961dca7e664a38aec370b4aafeb49458bccb5b1d4315d34b8b48a2a962afbb604f6d39b4f59d69ce9e7fb73876d37b66d6af59d84b00b61bb5885a3a7db3538611b159c6e12f7f584064c6e3202334e0a6385b7a2ac6c0b820cc6cd6bcbe2cd27e3b0f65ff6f8429999e9ed42e3d2b523de9f462e2abc2e9ac2c5c405879fe522ba7be6ed36d0833b0ae7dcfa49a0c7210901d94d20417592284670a79c3cbd163f8b2898a08b0e9a01a9edf8150389ba9ab498e3b6bdf41891068bda12330d665629e90f155770ab9e3e167108cb0201db5ef344306b199f12448397a06a70807b758a82f3c7518a8cb11aaa73dba36d34cab8d19438c17aa460e64aaafc8ddba842ee5412df62c32a9e85e297d20091aa492d63701160abb25fd3275b8e81d3ed775e4bbffcddddc2578901e4f18e372fd76ffcc7515aa23e08142ecb96137a52b7493880d7e570372919804752972da74b418e7f015ba7d8332598b2053202005b7cd4b151c282b3fc79f2ea349e7d1c55db9b12509f749e63f1013e5dcdab1e48ab09cc46e245f9a24b901d2000cc8c4a5165ae82640a31e6b1ae7526203ac643b37da54ccd1e943b7deadc1f0ad31aa694e20716c2e7b49d1e195accfa38ef08d5f83983cd27e2484e2dbdc27a13fd677864b125e0b4bbbbf97806f4d0c511e87bce9672d9fb0a3ffa7e3b8b08d0cba41d5902a438b12caef3f360893bd59fdadbd2a42e6258cdc305dbc03628b983580f435f9d61cf5459b3e5ad672a078f0b6717fae59880762f9d7c7761b6c6a504c2aff910a5b11792de2fffe5fae3422bff5980a30bcf9e9b373a81003a16e637c47d63bce004812961c50a1409bd1c9ae2660227bd9daf73171f6fad7831ea21254c24fc03f499d945073df6c6488a5bdcd2fb95a165ddb112cbc17ddd2b5471d326baca20cf55927b594e568b2e81378fc3d524de55ef60b9ce6d8af1080a717d8d7f435ab1f9522259d3bd6ccba7e9f2b1cbce33486986b66121c0e6d160d412a2cc35172b06555944ca5582654e8bfaba970b259e11753fa1549dcb3ec96af3b695ea5df4f96b47c0d50fc1e7e1690533fe0e378d0a07bf544e4ae06c879ed483b03a81acd55830f58930eb6e839ef08ceebf509bd8e1c9dfcccd83012d03bdea7d3f491238dd70f3db48300d88aa1eb78e926108dcb0437b0f5f8413df7368efbac5de7047a0714b59b4398b288fe3f927227dcf7bffd11242c349eef72e71de13098fea8b18ec9f254d86ad1696e9de27a96016a8da6f1b3afb335be4b46590a6db141c32f1f54fe0e67d982f5b4415e2dbb8ae27bf74b6b5ae3d936872ff15dcfa7258797b7fee3afcf3c4bffe28dbdabf32b36f8c49324a9b4a0b279afed32ff7d19bed39dcf8745273a59cc1cdba746fedff501877d92def870931637be6ffc4fac899741b0e7af2b38d575e82bad90f58e0800704b1ea4024963719e3cf603d160a017b39f32b0caf1e64cad82db07d4af41c2a7d470f88a2020b603793dc324e454c189ac9561a4ed073d123f712298ded4fe2c0e19831b2b02cdd2adf671dca1858e2ae2e4f8347dd347ba51125bd40f09b3871f26e959dff6f9c76a9bc16085e91e44be353533d893242611256ac788dc9529b11e4876743bab766101c78af93bae3ac77d25d26a15dabbeecdd0b4eaf6ed45cd7f911c9e43c78a066beba3e2d37c5927bdac7f3da59510d2c1b4ee52a8bbd86bae0111093ca0828a94205ff8ead385c16fb76909cb6d1c30542b64a8702556c7f0524489fcf1f1480fd2b35c0af17a4f2af0cb811cc231ece1e509458e065685a660a66788ac67bcaeb633a1fe907b7e70467af4d0f2033c9da1cfc6bc345332cd3caeb65d785973485c2c0a22d8df73a6baafbe6f7bfb145521e702fcb1ba1ee93e545b7c381b3649e59ee9b6826d4f275c069053abe59a5190f2204d84e487afba3a89d03745f8a015790c115a0a6e55d690ad4915a7d0ec83305309fc4a61ef23b38b9894731ae0c5975415a34bbcd9903eaec5b673a6bc07ab947b7b3e647d821233c8921f2d9204f88fdb1ea133f3848db4bec0603287229f8a643a92866a0787129c59e6ca7a73031fc83ee866fdd6bb7d037d420dc83d53cd4d547253289dce096b009ba5d8fe4367ffa39b58e7a88db612c9e0818de4d68e811e7f6487d2b111f028875097c42e9d119eabb732825119d04c4d4439aa39403c0c9bf479b04bc765b1d8a1751a8143221c71618fb18cae9b6700694623d959789efb44b39bc7ae3f7bf7a080e970673ca5160b4478d46dc7863a81ce01194dae8a96c262d0b371328d6bd2cee84697835f43ed446bd756cf011976311274f0fef7bb5a60a374d9d3ba40695bf523ed10ac3d5526ea67f36002391eb3c3b688a7e7303c47636f1f11ea1ea4e4f7dc3ee379560fd22af10108842338e8470446abda6013a447d0c40e02ecea8a0bf89d23a22df18d464d37bb2ee19f943463355ed7f8bb5eb5a91c3a857c2addef4fb4792e9edde544984466b44550f1dbe10da26f09df02097f77fb6644b746ff7fc53a5bc1dd12df392f81b7079bbe98411e04794eee528bf2462f98a021f059701374efa8e16422b38bfde1b20f12fe5bf18becead090a067f30a152b28e2969b2cd16ce55f32bc486b5dfde0ddce3f43860ac00316c4d3357cec2517a4063777db5b115b34a74a0c543cdb223db31911c20ab76f7d1cddb8cdf1bda05ccc13dee449e66c1d9a549ef5f2b1584147343ce25f14e158860a08e946f221012447262fa8c8c9257d077f6658dba225a185ba0a0602dc7683e7a193cf9576d27ec71c54fa2540d77fb3cb2d97c2e9b521437e38f33bdec6405c31ab0489f2bbc28de71646000ca34a237499d879ebe9fb56385f3647d859fb6d468da94d8424229b53600a4a9bac0749a5c9bea3e16c440c9220214d6f840862aa8b2104957a13355f9d214e155017578b7a597faaa139e4af4a2edb225203aa255a2bbb34280af5d23b7756c2d557cf830d311314c1a22bbe0ebd5d7cad6e4c7bc74b24c48e62adcda8f2e5b53dafee3228897bd5b10ae445f75be814b74e97e22d6c1bcbb892f500fe333720980f3fcb88e2d7ccc8a6b538caec9c0ada50148b5605a1241671d6a421e5bcbd7cd213cc1ea286dd4013385d3405626ab0bc55e9db1a7a45494320c1af6115958037d2b71e5e378025ebff82ce8671262dd221b2c35fe9c69d0a277b716b196af15aa4e8c2dc8ae162bc07825b194a45740fb8aef681044dc2d937d45b45ffc88a7ea87d29bd8ced2552fbee3d01a68bb7e6735afe0018e6197b7727723d056eae2cac1048e7091ad6b7f0d4b3e7a1966e205d6b33838c338caed27566cd997c5bf70f85c37b90e233b7ff894d11009a4612ac280006b3031999af2d4940edd994799572512750ee3b783a698cf124b731a78352b269768c5d023b578690b474a7053aadfd50184e257a23c3a8e32ceb42fccb8bb7993c8e2486ff4f6e03b6f828f19bd36c6a50fe02528eb3e9c886e561ff518a4b33a3e5e8da1cbb94eb1a325494e9b119aefa38ddc32a61113f1278f6d7fc3d6d448dd2e4100809d1215bd37b28021ebc222c3f14cb081d8456da7d461c136f36a5b77d416bd9d529f9c1d1dec6679ad34b502e3d6bb63108a281037fdbf759a6db217e34cc02390ed0e6ace7c334cc8015fb7e0f50b3b62302ae3591e28a23824fa5e6313be43d8f9337d834f2c54510abe6178b800ea19fbbdcc442b934abc2d1907336cd92e1d1b6ff58bec52c2f8b9d9f0632c8e1b3ba55af0b0b99949a4d7b47797e9a866bcdef593ff539cc3a60e0b65b0db6ef084e64123ceb22deeaf6f14044951359095c3da275344c5d716be8e0a1c22e344956847424f740b82cb0b8a6a57673a49b997cd34e5b37087c98f7ef529533bdc0ccf42f980d864268accaf74954a1bf763856dae57df62909746bb791cfdbea01829f06b94e7203f8fa700aab8c915e1f6d0b2f83c8c2ba366c66a36f696bff43ef1b39abf3db997ddc71e67715497849324b45efd6054f2125972545c929a2be156510115a0921dfd5ee1026383f95ce4e9afdc931888ee5740d94770237f455667fbf5b14241d814099dca9a35aec8d5b7be377abe51cb75f5f9918b218397def2972c014fb58da340665cd61cbfb0091b2b0cb1fcbebca2082205bab923a816f66516e3b1fa30d06a2c3bf99808dd50c5c9582a5d29c2667e6c5b105f2ed6541abe084600cd5cfb25d205f6d7f73bc79a0003a4bdca921e3b77225115a12ad5c31ab0c4afd3e3d9052032e3ba9a9e070c5ae77409424829aa61e5018334fde26558cc7e954d75f6e2a712fd50ad6f1228f74b521460d67568730d6ae1b6269d8b8c08a741d5f42258db283192bc1111716a79c0b93d1b41ad88cbec71a4282ada86366d69a77a5804ed3239054d3fe56d1642bd2c5cb44239ca684713c9847912603060a1200883434acf6dbec240c2399f66ac770e51e4c5a0bb57f6255008d3660d9f44741517a0e730266ec2df662a7a6c0509f0990036bb8c2a80dbf46918bdde3993af8594178db876f077cd4a991cd03cda6c29a6a57a9a1ba7db94406d3d2db8ea6f95d406641c611f8eac3faf3d9679a8c1dcc0bcff02ee72595bdb2be3a20afc34822a606f218221afccd86cf309a58ff9c4c2037bd91aba0adec801b24f73393137f3c05bdb7a3870b3d2f1bb6e190b359e7a720499b8fbd6cce3424591ccc1e74a87f533a74bb781335e53268a5cb79c98ac24eca9d9128ad4e40168caa141ab7c5996f755edca5081694dcc455748d3f2eff889cef1de425ddb4cd8b259b66f60dd105c1c3a422be0e855f350ebe2d923a623455a07f1a8366832487cebb1c4feef87c308ab974d4c25dc50332f5d68824b4198326eb0824d7b53b16dcf508aa1d2b01b10fa75ef7ed342d21391f9d605d237c8ae0d87367e0415f518e8a3ddd24b1c3545c2007c9085aef54994f52ba9f5f839d5920b6fa4e1e077308ed337c1852fcdb498dbe31727e22bb80a8b81a836d37add3e3b02730c2f73462fa07e3a8966d91c82a284bd247c4762757197e8459c8c96024641c641ad6edcfea72e50e438f0c1c501ae18006df96734cd69d54ccb80f11450b8e4067752319e354e0db0067f595090ccb9e0b2664fa84a07377eb44bce80fcfc85e9e603974d996d409e2fe33aea4e93a7792341a37dfa0c53187a7d56b8684e4cd7f0e1707cc57ded3431f2ab768e2b54ee4fe3fbf4e399768dfb88038ec2220206f0514b239f1ef84c679bd517a24d010c3cadada4adc54b307f8a6be5fe61d78e0d36701cbe8d6cb6ed98a94a0d1d3a590987ddc30ebd31dad0c59f87f4e76e13018eeb3d25244ca1e5172ade9b29d19d5968d3045ec3038117c09c8805c03520bccb4bd480ee748e0b34f2e0518426e52c7da34404432659a31d1995b8c73fa45f28cdbe9debe6c2849a9d542954dc73c1f7dea3c8b5db89950b6c451c77ed45423e0ed70a38d6b2cce537d6ac8a16b158fe8bb8ed4c5e7f9d8f02e50d8f888aaa3348f432d352b12d359578a69445fed425a1d470243cc045afd2d62fe0ff052e736c041266109397089408381188674858d5d0bff59a83c25588d0a43f0e489062270e7f0a1805b88b7746842b770d847bd16c3045515936b3be3416402798513034293cf0925e192b42266982f99d0f34739fe0287108ed539a0b7ad79e32e7e4e0becd9046ceecd27bc69fa140fd8292613091cf04bf53662a0a8b4d189276595c4d19482f382b7a0ebcd1cef8c2920d6510102d456b53366995360d7ead7394fe5427846d140dd7f2df5fd4ee49f1971bb9d2ed6b7146985b98386dded509a93a5d8bcd937456aba8f02ea3ad2d184689178e8dc5948bf316d22fb951053bd5925c18564ef1fc8ebc26a1f20fd219e38e199b95a3759467c3029e50f1c18171e2535d68c593585af1011cf176fd9945d7aef8a2a36d2fa554425a19b95388293571e1b0c805ef56ad118b11230e70eec947c50e1e4d42df278d43c11897eb7e74e7792019512a060dcd20c30d7faf40b95eafe25aa93592dcd3810ef20e69af0f280a20cd200e21409350b35232565418aac59692d984db287cab8636bb0e2a6edf0312a10cca2e65c7e09b16b150288d9453d7406cde4c60cf507313b594960261f39768279d2576ef65b2b102ae5c72fbf9ec0e0bf994b796e8bd3e119b950123d62d61100eb28d3d772c8e981498d1c419ec0e54dac602528445bac08ea391ab69c4c500994aae1418b6849f7dd8b62c5f58cf481ee516ceafc6368ad451aa7afecac8c72f797fd88757a8359c0f1a8aabbc12a81773b4b1ca8a5f44954911f3649549c726bdb901d1d9d6b2c73c3696d3fb7a677718e520f2b66bc1a909c153277c7333e9fcf46ac3e233d9048936fc0a3f5bc7f54685306047a371552860644264ce80e8fb0fc2e3986647f2b4f11fd2d035661d2e565be93770843ff4d79bce373c97199d828832522c3ae19adbcdfbbf676842c4e80bf4d6f74d7500ec0b5b7d8ca527456b7eab15f94428d4e7880479c5f2b885c96e2fbe5dae44df9ee528480de7fbb782727c2085f5100b9c4504fae775ed185c2f11107d6e2f03f51d0b271cd581e8e9b9dfd207edefb6e19b2e89a730c2a845fd5491fdbc0582a4d29b79a9268d44134088b8e37a0cd16ece547048f75071f106f222c46c6e7db55aee6f23c933cccba27754293232a3230d0a3a3ecb07681a1a60e2d7aa6077b002dd8429e9ad930ae8da1f26821d25193655de8ef3731d412d19c2fe2aea219fd1e24b2953294e078f8854c8e0497287a9ce013c5d531145ac2ca97965fe68d4570065c12acbaf57b4bc90167a536bd6b1c53999f656333e41d6cdb68c7a74e7249f633433a254410ba320b4be32a6dad6f23017731c5e612807d2c1f2766e4dfe62f55e062d8ce5e3ade0580fda2be30ca761368d466e5538612b7a4089cea02276f9098028c5da7841922210d248d097b42591d89f72238b5dc26e5d448c832c644a1f9d489df9a6a97839ba8479787458e47488fdf46e683b94b8d89673d93769a7de56c67d3ffaf93b140a7e88050d5f4a6f81a4e2206a6b1855a7174b8cbc57362749258a6aa9183bc3241b3d04ede57c0ae2d0e3ebb2a777c498660a601f8bd6918e60cc15aa0432b5ec283a708c0e331d6fa10fbdc4494c352c18b2c3e9c31e04d84e0538171ab80bf6f8e3fa13c199caf136d8563298d09a339b65f5095d46a2f86aa5bb86334dca874b2397c5c31f2af4620c37d0795196df233c4ca78deb98708e05675184de1189806567890ff16f3b65ad20a2c5ef80219d0dbf2cc1422864987945154aa97084f3952b91a7ed0dffc2d5052980d86144a1e63eb41c6da7fd846f3de6d565aa9184933f1dcdb867ffc8bada867478d2432c2af3e0bce206b1006f5a3befe7d79f29336ce5d3d4af73305ee7f13a3197745618ce03b8407d25b92eadf131548d151f1a45dba15da27542412010c3de0ab808a5602f5d74a6f3ece0e2df26443e32aecf1e7507bc35f9998a809eedf1670d14079d9f9b912e267ad37312d4639a27438ba2300cea0c10117fe69176ba394d8ebb1c9e1b08d1eda01f49928968cc98810d27d33aeb77dbdf181e95e26371df485ccbd364c70753ebeb761b6b1226998b70dd3ab04dd816a498a526e69d9dfc7744747418644329693ace191595503158985d171bc8988c0c09f600e9b1148ef628d257bd25d2f0c68399f1bef09413c856a34f93f65b77985f75c4a9e8dd21c9f15e463c72faf6b7fc8b6f455b771936b434cce700e8dbe1bf36fb17576b2d99a00a77adc848b3e1b2ea32844fcccd366437ddad596fdbd73496974454c74dbab692e79ba3e8920b24bcb16c12bcdb83d33f57491d6d17dd60c2ff20625c0c77bfe2395b6d3fbf255c5ce430d1a143882d6d15cb9d37703b51143adf3b6c100411ef5b097cdd97ae86f1b7373a0519fe8e454d4a7ff7b76bd5d8ae2dc63777eb0241143987af1e6353ee1ebd2b648480d506cbb1cb41720c3a658f33e5cd5874623c8e5fbdcb08664ed583cf9b655f3849d378214abf4839517cbb129903241e1d396cd0a43c0200a2ace7ceaa705187dbbf355e8d6b0b28081a4be2eff1fae0ecedaf63b7584a1f7e307bbdf318599505a6e4087e1afc0d1134fcc745e8f63ad993adb1dd307709c4d9bb61122d926458c0cdbe040dda95c270d6d532a251454327fbcbd2c0b559d01b504ac9aab68df2c050371ca65bdddfaccf86840b5e1f0e80439b138b9ab066611c41a1483d754c3ea3e7f73eef94e38e9e0a9cc9330bd144a735f3d6699fc0cd7608a8e318ce177a57f6396892dfd3b7cdafa4f0304fe4fac36acdc6dcb05d4617edd2af8d7a5c9e80a397384c73fce8f166648cbf7632db07238c9ce7852385d896b37007168a73fe0a85da5ab129dbe44c472c6b3b221bf754977376e46acc13fef414b97a11b2ac37b0da2c81328805a06c22fde31d98d23dae5879a391932c472f97fdc0c9e562031403518576c48834a2e7c57fd8c11a9d98f75b1e1fe8105b2948d3370d323b493a45a5e4b78b03362bc8eb75b83562a3f3db33284bb0632332a1b086acde1fdf62b2d7b1a4b63e80937a267d0e172b3ce5e5444543e41cd77db2ddd81c52adf77895f88e573cc2c4ad7a74aed7492d434b8fd75818febc8d5f52e410259451072b63ae79579a5a02595757bf964c2c23945f84d5b482a317ddfaee1dc6664f311051f211e66fbc7d3076aa3ef5aaadedc095f529e5f27e740f2533bf26e82fbaf1018a9bb9cff80b94e43bcd726d4c445600021f7d29607b500dd260ed687605e3dfb1c90bd0b75fe491f72d32a50e14d24794b37ecb7c1a4b5d984e4898379a52dd3983ca6e4653fdd11badd06b31cee7954b6b9cd51d5ddf51b698915cce14d01923a3e33cb880240ff99a38b371e010ebeabd8ee16af60eaa1f6371d4e2801ee439d37bb087c48f1658512b8c0c89ca2283065ebf6ba8a0ebd23cae495f25440a6c274847e42cdb5d9cd218860d5078d58319ee6ea5a586dc190f7c2dd826fa92f080bb5413e51b3e04676f6c38dc11dd877f2325f175699130995316f1574c4465a02f78bac6fcb9e801ffa4e3fd27c245dc6d52a206c218f15c36af3bc211d6cc72bee4351beac1f31696f84c1f9e1eb4e954f9e3733785cadde925b1b853281443178b1f225d48e54678bdc6398227d78fc2adcfa55e3202942e2567d92b1a9854457e76204a3c4d96e83066242f85b5e9224320089cfba9ba461c04563d770672e7b24933a519197c290a582e2ea604001d9c1db0ee66e281cf1a46dc47abe8123205a9fc7d52974e4c7376dcda8947f56fc03c8f8c69566e63cda3b53cb320d949d3f0a1b9d1bc5b853b1f9cbdb8c409245d9ab1d89435aa04ec248051764c714c0bcf2d6f4ec24d54b776c01e4be0f3bffd6462efb466d9fc1d830909e4736c7135a808bdf82b1c2eb5a5f52479bbc37eea33e6f853c35ac61c70141666c2a9115389ae273117a1cfad116613766f1b102ce53aad871fed464610a44d849074446530f9cfcdac10096c8e0e9ba5894724820c07426dd1c55b00ebe086285aab316ffe04222c1ccc9f2a8e0886efeab17bf143281efb7bcdf0f811c33d2d6619d486a60cadccf6a3b79e3fce3504210fcbe16abeba3307d7ceb9fd631cb9192c2075efce9e5c7bdf2cf066f8d72f2d07f2bdade3ffe9a0791656ef43237681a265b1147a9a210eb35b102bddf99b42c96524120ecc487a009a44d9e6a9a82d5a30684331239e3caeb3b051ce5e055da312578946be45f6582340e5c1344b528d043acde4efa8137df9a6ce0009ae58aff536c37310c5167d0ae1304d8dda283e1404889b2b7a967bb6a4c48f9e843d2c6cfe17ea403fb098dd3c6c0ae07e9f4995efad5af1fd5de4d62270d470fff451cc0328f49196d2ff66c8eac8829d4102f899442a60ec6b1775b8e28e99712b2372f9180eb2dd890c8a88c21aefba017df42c09835dbd0ea6e7518b4780c481babaca705e7814921efad0dff863f04b7a9f2e572f2ad6a64a4dbe6d042eabb38d4a3f160d38a9675b5acc2f748228c3c3b66ae3c548f5fbb464ffe96cd578ce772d09ee25a1ddc9c03c37e70124b00b996ba113feb35bf94d3b719c185498d7b2da998d09a00124c9495b90e4b0571cd311fe13696f3e4262155cc1c3658e425bba06665005c4baad5910a686b024b285a82bb1b6606012b35ef2df6eb5020b15de28b84e32553f2e2fa0c7bf273a6ed257d11bb29e9683349c4fe8ab210dbdaf9855ee59fadb15730a03c51bce164f96261a82d8c5907b145a965a439315bcfbae6beff7d2effc6bd981d01a6e0e9c9f478cce1b7e80610a4f8e1060179461776676de1527c13b31a3f29f7f45729b2d73456cdf9a7ff8a98f07bf8351694e9281df7aad8e060fc28380c6023b6ad6ef8b7bbab36b800e1bb30ae326836c025664d0fcc567dcf77bbaaa0c604463369cc5f3c04cb0a9d58868276c3b2c22148eba9bb155ca60e2f6c1b42080678978d02302dc1dbdf9f09475db9d6a6b6d00283eeb80f7f192d15bbb423aaa02642a8abc171f2b25bad4a4dbd7232b3f7b26dd68c82206c563a7e74d654dbef046a04386d8ec2bbe3237142e214d0d8a2c30ca0c4f64855b5c2f69329f663797eb85fc7a5bae0420bef61ae4021b8d37933f218289733b4d9da241c86e6fa8b0fd9b071d66862709d05aa508f2f18f9e5a56e6d2d4967eb63987a61c34a25ace6c1c1806893710eeee13538550d417015d9e9591fad30699a6dde51e7b6f44ed6f0a1825941df1b6cec65ae64a150fe622443f06cb88bd249e85c46900ba2553a20a28aeda9f083f841780cc283f8a63a5517e4cb16737325090ede8a4af71e2b27c3ce3ecd8dfec0c4cd0c2a235d9d2dbef0ffc052ff28fa7ed79516aa781303dd29f33b0874f8759cce469a110e05b911fb8f9de821f0cdb21d41f7f42d49763296b2347f9d9d91c1ed510cea7ae5e4d1a68fd6d04b17207f0cb60e0f184841f58c350c4b6c9c84c4f636987d497ad09a2827d9297fd40185787b2cca2c148bb2f67df6582c80890ca81c8aab193d5b3f0d2373e66bcf462128e00e36af9e94b54d722938bef2b1d97111b73dece795dc553bac32e1a9db7936c7a3a741609a02d30241aaebf9ebed57cdfb6e89c8ebae05269e246ae60757ec88fb84fd12a294d1ea90943a7583e0f80934a8ae96defa8777a85eded76321233a70d4df46a11f19f0c3c400d98b911c91085fb86e00d1ede07d0a9ebfdc37ac9f403b93757f3d0243e1ca627b3cb9cbbadbdc828390c106c78a945b0ffd737befc8e173f19b24a9f4ccd091ad1568cf2a15114d4f58269578ad2226e01983e84ff173a86701ec37b2485244547a7ece3decf57cc115a714bbaf7731d4cf8d2664a50e4e051826207c4e42e3ebcaf013d8d1f5346344ecb7c7852a3a4dfebf425f441e1a33932b9565df1b5fd68cdd4f0f9dc935522755c99181981f28445aedce6ea9a65ec9ac225ab1b0a5baec60aafe78f7d7e04a290005101721aeb1ca8589883e1f978b0013518fb72017c191880c1222d5d75ee02fddeed237f056d60222ab8b237c664001ab12a7f5c6805c1a4bc746b91ffe54b318cbd444a75b19ab314c7383d48f845733aa4a43882f7f79c22e969267a5ee6c7b0a135c7c9ce58dcd915173dabfd0a9fe10b0d524047250abd3f53916ef81486d783962a3ab964b41f6584ac223c46b4573b16c4b164964a029bc0b411c62a5f8601f3638608780dc044eb66850a643b4917641f110b997252f9a458b43035e9e29a8805098e9b39e5dfa8c920598cdaf983af54ef1a5138e30880bf35710bb87592eb153b895b9de6bec339f509b5680b4ea82e2521e542d93fc1f272f9c86cb5cb6ce8a1f84b0401ce0096dd3d850d22257122bcfc74d57208eb696f7e1b79787f12dbe8d10a72078d5ef6192043e849b337a950160a1e5cdfa2cd8f186e035720390c48e4baec960df78b843165bb92f6f1fc1c0b3e366fbe25cd4a7f754268a7594022a7f99b46de202172be30fba840dbb47bb9c87cc7c7fdd87829c6f29e7cc6062c5bcbbe3015f63ec5e265dffd75f6b2bb2ac0b1f89cad809b9fe0e3a78a54ca9dfabf2a11a30ddbcfdb2f170d9720529c5ae0f79f8b6fd52c1e90e0c7357c6f696c92b6eca2fddd57ef1bde9def52963110f8a24f5f394b19da980e9a77772876da9e00ed13aa4504f5b053f5374e2d002cde761d526f9902f1407d14b6c36671ba6ef510a071c4b851cc0e20eda042a06fff1230fece21c3fc51ff0bfcb68f6b8fdfbeae5dfc67ef6e91de559d5bc715aa2069a4de129872226764f00554b904655d2a04e0e02924fbc827c6e35a26ec6b931f8a7ad632c0176c3683ada32ee599f94cac3b8698a6b205c3c16af44742c4d63e48c935e0d1ee5fe7978757bea40106026163f4a03a71601fb35d2bfcdccb40538e77124fb7f1c55066331c9571c364638d7997921b87c2f0e7761c0d7fa5c8652ae44f5afe08c9ae3e0bbd63e14225f324ff1a8eed32d7a5463088da4bea1c1ba0cc5eeca2a8b749e877989fab0d17b4125a2da10511a01ba75fe4f6ebe62409738bd0279847ac3b4245807834da4f0483b77ea0c0fcfa5a718ba5a45db8b2c362de2f54aefa7e33f6f631804828d2fcc08db1fadac0ca57a91086db58e0f263ecca6015807e839c8e5b1cf56d7bd8d2f4e2dfeac0ac5a129ab607f4ac28449a412fed804d6a4bf4aae20bab7ffe4a20bcc44cbf62cbff6185fa88e5c2ffa2c1de58cea58e3c1228cca5165cadf288762e02134401300ab01444476b3e5304566b1ce52221345aee07202fd7baa9a1070c04c432edd3eba5ab498ba830351e06cf2e5e8a488fd473b67689fae9f372675c27c8d2ae0f7a461da261e346f93a95fb011eb3aa1ea0bb47e31ebe8d0e528f51e63b801d16ceb52a290561f3e1c9e6ed26b21b181dd9c4f207e63e02c84705381936871e10b62bd0d2d573732a926624442f1244193dda8502f5509ab0de788fa9ea5ede90bb6bae12bd44d8779d33f60450a390b4fbacfc032b38fbf76946daa77b8984e86b167242fff26b082f909cf45509bf3a81a04049e7c877299e6afcc7c41251c400ca9a1dd9c1dcf325c34bb239af52b2e927b273c29c4cc72d7b5a35571a1349985ff141461ab3a19d0534d8c1f5945e636a09ad49968403018e75cee3b2c256b8c973a208db547f4e40f1d58fc3c8b7340595da4db31813b2c19ad55ce67bc38cb32860860cb0f3eaffa3647c8bc84d293711e900271ed85801d1c47684762dc6690d56e76f5d17cf982bc1f6e8e1d887b3266697ba7f69a2e6055cb359920364fbf75481c33fcf0f6efea65c895fb78d5ef5c58430d4638fc433f85ae55c5f1908086357c60fb50edab694d66f46aacb0e91858c7c7550ec30c7eec25969adf8c359f17afc98986400090851836a8c613550f879306e75e29b41b0875c685dda990e4cca94ec194b07a78a86f894f7c6c7692e30ffe445c4dda388d909308cf0e60f9fb3547778ad0687e2c71c8ec6d251f061a0decb16514de648b7e6c1b9f6d4de84000173c2b9ba58b447f9cebd59a8a4865f4ffba0a83454acf12962ad9a3554503b195775fa6e8eb243204d980d81082f6f1e7d67ceb766f02e93e608dbec9c6298c47225245e28b7c5872abd265c2669274b8cb6c32697eec697b7bc8361d436c164c4a9dff558d11fa52db07611c0d2980589aceb6327a91e4b430eef0cf9b9e4e277697489e03fc5fc0fef7a3efc30a86fc209cbd37ee05c1fab70c16556d339ee9fa458327cd0ee321b4ab4901c9df5f67b60713f7379d108deafc5e1bfb65a5694f0c7e55ac97d6af1dc4334a10f2840dec37e06905fd4374b3f5b87db71075a6da94ca1915bf6ec29cb073acd166a4ca9a9f6f99ffac1f5821baef6ba53a0d5564e5fa5fe135f5f9f7ded7805eb4388424ec96fe925727a127065c87bc09cf64865ef819641a242bd54ab547a07bc60a3a7080606604187693140188ce46672939498969595fc65b74885cf7511ad603a572b5a598eae2d68c1d26fba9cd31a7fee3b4ba109daa96f9efbb9eacb2f59e8a5d203fb50f84b9560b0f4e09cf73bd0cb51382611bc335d4a0ec2de5aaec1712bf16a2072533cab29aa8b03c3d19470dc3284066d9744b9878ee2a4212fd457c8d31a2bc048fc91a1bc05381df8414deac26ff798399290281962fba2ae28b11d24ce6c380ab19d7050416fc60e1aa4f453b4323783ba99053659afd7789fbc70a53f75531fb45abd8fce6eb393e2f0e436808200cb6b87ffeccdfa26a2706fffb0d40c304d5e9dde55b349b4729c66e938b5275e283dcdbb79e27051d2f54474ca1dadc297a8e4259925f00fd5e8f45020502bced046f281483313e8bf2ccb5af29b1b3fd8fa395e7a4ab058387698c1d16c9a9e25a5e45486b03b30c623e8c0b3d6f96d67b4964d8901e524365d959eef577ca049153fed782dc68f92442b8e3d57610d9a772ec44ad29f5b6bf1fb6020113d8ae0dfa11bdfbf10d05d706d223341774dff4e7bd56b0f98be7746c329c85a5f964313add4b8f255b4c30773071f98208934426ea141e98e8d597c749323210c54cf5b7b4151eb01ee8dd646635311ee834b0baf9e22ef15fa268cf3e1227929c54c58c4b2fb0ddefefe06c24558a363ab0013f6f1e1da6737d7db585c8fee5772de7112b43f0f0e8831d9210ee42d107fb4dd6b6b70c98765f25004bcdab8e62c6593cabecc0695e057b5147a02530171bd74ff2b8a8e7de8935722aa62327b1b5bed5132bd3b40974a3d4ca608a8ffdb4d488829f094b54c41d1a50fba32dc83b44b463472ce6786495f0195eb5edf4e03db7300e2cbd4a27ef49562d8ab5449d6cf70f375e0ee8e38555a7991a34629856bb4890808c4eb9ed95a2bcfe4e2deac5ec97f6bac0b02f3c8b7cc605ff527c6d602c5612e1b2089830f9fcb28a00254251a7552c0db93e37f0a2e729d6de561cbccd73246cf81518baf0d5657cb776beb4373de7abf2eed5c3bfeb91c8525b606ad354ac1731b9693e1c1fda1d6c12a83b691cbac74c78a981e21c68360d87aae4bc2a1f26d60cbebc90d031db3862b24e4ef09c1372f6cb627fc6311f7c1e73d604356ff77c8cc5352286a737a7ad896beb64866bfee4eefbc46a7776b077f21ab3aca51057633f329c29bddc7f3370988b9c65abf8446083387b823c99ecb6c315193148206ea1d65ab024cc90809ef5d1e9eb4dd98cc763f9396281930b0a55471893b22312d84ccfddc182313a9e3ee0eb8abc39a2041bc82e9acc2b5a37a45a19e053624880be515978424ce4fc913666c3bd119b1a975d266037d59ae97a5deffc8202d95abc3b55ec7d6f0e5b8726e3b50e441601400477f3fb7ce0ca4b6740094883ec58a6e4bb3765df85d96bdabd83870e811c13c50a1b65784ea49e12d04ffdb3daa92beaf5dd5404f9cc2fbc4cbe6ec548d8086eb443c03a7b94f2bc5a460348106fe3574a55b7223800ebf62930780c830304bc271e2cdd6d105a034d558e12adacaf5475f0fad2075313486d37308236522d56fdb4273452e1f927215ed97b55dfbf49b69959f03372d0749f2de30d03e8bba4e0c90c9c475cc7d8786350001607afee5fcf4d50bb32663ff42dd83222e52f28e9c8815053e94c544888716fcf5d7e037c711945e8db64cb5a62dca0ba1df28d14c22adc18bdbf295876679d47fc773dc3801f76109325995dbf2b0bb932a8ac8531ce229b9bf5b5fc7bd35b0c3b81b3015fcd7a751f8503adf9a00666be8d968a117634db06aa3cff585559c63ebb5e91362813b60f86181b95fb940017a988e7401ba1422fb82aa9a34eff1577e0dd2da3acc2954906d841144c426594b12ce69b18eab8f2120701f9df10bdf38cd386af265cc97f78aafabe8f25c374f3a7b83d67aa69fa0b890f5cb49c589202b38d24de36bd5ff971ef20d5373be8d7aa188071193bc6803d8bfd7c9a343ff27e3b5ce6516217b5421aee156d57320c8bc9d2510968b987282df1f6e4d7b4e6c65f09accaaaa6cf3dc78841c1dbed36e2af7ab64ce9ceaadd903758aebfc52c7ea433d16ff24d0a80ba87789a99044c2737c9b688932fc919e1ade13f2b2ab84beabb88b2e015bcbc90ccabcb502796fea6d28786368c36e7625a3c5048c4c441dc67bd2b0aa62c68118516d56d38f270f88395a475bc05959bdc764acdf5aee86bc9ab5abdfaa08db0f8189ad2601108e1117d78ebfe70d3fc863b52a07430b421582f68823fe69c49fdd67d8151707570af9ce1ce6d63d4c319fec3d89086fc31e708b31ade2a218c6195cfbe5f0bd8c82660817ed133c7a38b766de6b7c419937ece25ec941dc51d95426669b33cff9acb78740a5f18ae34544cc356e8c057bc69b5ea3aaf06fd6389e95b4d2f550e8f73a406ec6753b550e4ed9b9487ffab4f4b15573dfb36c815743db6ca1520f49cee05230b5a9d674532f6fbfa1a81a902b1c31ade4576bd905e1f65614d3677f5c41f8c99cba22bb101879efa0bc819624dece4a0f0c9acb36e5f0ccd40957016f09a634b80eeb6ec33374c311d12097ed1115bd02ae96ab95baeb4a6aabaa773aaf3dc3373c002d8dc6e15d7fa36ddd42ad4c3703e7349da266c66d57646c1475ec7d6ff4ca0137b05ae0f8f5fe1b9d59a444113d32d7db63219d798a8c41ff82a11382a5e2aa34c58bb5147407f7bde3c26916e1b49b08d132e24972eeee8032548b1eef08ac7201401b712f06c91a5d13e7ded9821ab071860faa32d5752c9e8aeab29bc99129e463731f18805a0057244766e043df0fb20ee3bad0282739dbe3373deff1bca0d83e00a0431bc41fe7eff67048805449752d65194153e60bcbf3a11c1a78a4626c87449c0067dd20ec07d6242977aa0bfb36ce31f03dfbd01e5167de141cb7604a1378cde44bdbacf1b139b6d86135eb6e5e67493b085c196b542c92960f1b60154cd1175d8dad04dfa216a3464ae166b7735f5da48796160001a5e139ed89c68e8697b61be1b6291d5852c73b31c3677778bfc2a8088a55aafac9e4e2cafadfc23b64b1f20cf1fe69ce3a5425a2c93814205f4d803b8da7644a1c2ed5fe17dd457e4c492a9e131220b1b89768607421fed456715056c44870257ba3ae5b05e156c2afb5b75b320b4f83d98c411af66f1ff21f21bcc061dcd558ffd2fb1b3738b77bab0d57d56ec3834e03f71250de3e8a90f0fd8496c3121715a842d2cf744dc4fa74c62e69d97c371f36b0f96f458fe2aa6ba2fd33dacae1f58ea88680bd42c9cd8d2a609f104ff17781c54c9e50c160e3032ebda7d8fc1567aa915463f24fe373d1c68e2e4512a86891bd266950e4309001ae1f6ab089d5375fd5c72ccc12bfac2a832bd0f6ed2618dab12569a1afe0024c20800b471f4c9377201dab7a2c3cbffd116d0f44548105a53cb1b22d9e550c7dc8cc605bc4dc5215e288a06d93b25b543f19ee60618a2f166837761289ded013cad81e2750cbf4189d8b5be319c9a189f94c4e345ab6987ce7b2b9c8e43e4bebc1220c0bdbc21a332beae29d888833007f6a3aee9b662f571aa9c3f338654406fad5d79f9cdfbcc347a0c7a1220361dcf6375588077540227b98bddcc29e2c10e552315d80a104449af5755768e359f886ef52f0f79d1f9045e187fea4f0d614520720f8a2f0b3f86948e66e504ce434c667cbd053a4ede8911b48d6cb5e36adef9938a84aac1637ed290eb161dab58023e253d6355ac8c92ce0f9d5d913799df0db5bcf319f01b6a46fc0e06540c751ce43f5e27eaa7688b42e83497145db318eee4baf654745ec7b42fd3e09f83f5056232d73018aeb8bdb5a052f94965c8eb11c78f9ae6b2b62ba0d9627de411bfbb186bd8dbbb6f21a19fef3d7d5a480b2cce02c5b9aa643f263810525ce5b6067cc7bd38cbef263b7bd2fc5d191906bd67d65ee946dfcb55a8a14b6e96e168e4796578775f02e392e935604bb25bb8965a274a2aa4d49a5fa99db95c3aca266343cb179c31fdaf157a0ef35baf1d5a3d6811a17f60213be4c470738461b153297b0b6466ec5b5d7d44f5541001828c7d2afc5f30891cf2817f1da7f8b0a43fb7a1d6bc9a416a99b9127d01065bbd99cfcd21f3a540babdf65a3f21db4f0350d5101b70f797abee83675e69102419a81934b35b95fb285ba092f3bcd6f81cf6081287cb0e20c1677b9caaa2b940465b999a7f6e9522ad48e47b77f511cd42e4173e984c8f6b451fb1ebc555d9bd7fc05403a21e6a5fe19f65f5f7e517af39918a83ae6caab0883457630223c5d64689cc6f503baefd18206b73d9fa6a1dc6325f95798e98ce8f24d5f1f1e92ca9bc510d4c93c123372bee1fc61f08984865fc5312125d03306f94eeb97803b2c1f522c99e9499d9b0d524cf39397c7940994ee3bf452f7f63337c8a2f23093c4f613b02c17718021858f952ce53d906ceceac07fe7ac2f6837151f1945ac5879acde64f4b2ebffbdb2f313c33dda26d1eea15ee7109d1989f7695cbc97e85ce472e407a50b4d36ff28fee56179511db67e5e55d3b9db7e162052271adb728175c273e70ce9011a167681909223dab7d9a69512e6563babf26f3ec87254386c997beef6f356d4845d37f23fe4b2a1b1e5d32c42934ca6c914550fc29461fcc7922f21fd669698a48b212a2951db7311a0730307911fcbd361108c0608673355c39cee9a2105a6b271d133b627291e05aaf539065f673b6a006e845b235c7813e1c427d5b2f479d4c14d3532d08decb3df5dfd6ef62221cd043911b86d9c90266ad3fe8294e9b7308c96dd5f127316d034856b7e70929620e390e245a66932ee7231b91d4da0e6310e918b126207c412cdbcd95cc600ccdcc9da3a1f14256101eceb19ae369e8867fa44c10ab9c45db392f9d72c3f56e2102f810c05cc7935a1d4d4f927a56416deb09ce32157c04e58a94f98ad166895e11877bc407d5cba75a547ad5c53d8de7ae51e1f4d941ecd7f6bfc978513612c050534f51baa0281fe93335f7e79720a2788948afc156c5a593fe747127796da299e9db2bbefd7126fdb0df5b5a4a64f17b27d94dd9ed6c5bb2a653267edcadcd6c418addc2236aa10fc0c4816654fce29e3b19cd9bf27b9c6553ab0d2300455f8f22293cd99baa706bb7dd6f7453563ddd9c66c91fd55a19ce602022201c0ac04dab8c0958c8a45d4e7635ddbe10c7647e05314854de80012bdee83d99484a59044e554e239337bb04f4205bb6c175b01e327a56debaac5634bc23a2cfb9532c1b37bd3f2d6be3311ccf574e94ab99fb278331b924b821d062d30ff05416f69f113aec2c2da7746bc85195366f0ad74cf56a50596565b6039ed30cdf5329313346af1bddb7a1a38e7535732579370ccef92f0807264d08cde05a2e4b8eff8076dc9b74c40280e782c5e63e236a47e36760cce1302bf3b0c3a59204f33df64047108b499c56d75898f6d265b795b42322e0a87d2344ecad254cc4be14b39669f53eaed62f6f1fc7d44b035b968afcc8b5efcb4317b7477223211a714a51442e46aa4bd13e26de94fe82ad1818faab43b89dfa0a9a35d5ded9651aace088dc42be6cfb665e3bb3ee6e2457318346a4e2d461b408531b00946e1ffaf7ee4543417c8227c498b4c1bcb2582afdda9d428db76af70eab86738c8e57339c46793a2fa3e12d4f8b20d28c50adac92837e844182848384970a51d89ec2572306223990b986849e15cd3fbc09156f69ddf8137c3d9e01c656a88b2a48937938e85f0f13aeeb0b179f2a40c3f1cf2cac65ad6b8f1bca2eaf6065f3b61e30d9df0b61a5222251fc9f7deb77439e429e043e4e7fff671c7a468a9397b99a6745b57ef49fcc329b7f8ab7715379164e88b54ece69cc22ef8896947fff1728be164808f3057b3983bd30debf2d6d99187a66d42124c182648234957352b43fcd54d77d1efc518444fa0e147de6a080292cd6bd503d2cf0c0bdcebd8babc0096ee8155fdb7717819a67467593472f28520228bcaca654e9f57142ec2bfb513ef81329a004a0dbf05e38e088d64b3570eea87ca62cb2e9e7c9bdeeb9abba4dad51de11e7f9bc8e87b8fa0f2c23bd4b59b64f3381253775344b1596e5e71870239eea8b2a43c3300c4601fab598a0fd6135a953fc6a1f17cfefc10f4d239dadfe9713d2322ad434f9baef5116f757e49f72371b58f5c7c91c132ab6ee326abca74e475cfd9838041cb80b9db4a0e717425a157e410f8ae11863632ada104614a5a4154c2782c260349ec438ac53b324b1a4e692caea5f6215152916637b2ae3a8e1f36f9a6f0b73c714e7569bb97c3cc5ce98d9c0bbfa36563bd1516405842bd2fe35abd524c55e1f3eae8ba524ca36da13acadb5c68bf480761ced570e7ba19d88a601de2dd5af8f10c4534df5950b3d80d0ea1de262bbea80595c279df2ca37576004f99584cd1fa53ea856ae093ad20f6734b38d46e3d8447f0d500330f69111b4a148756fe0980371dca2f0a0a55a3001c2dbebdde7f246c1d7ccfd5134898b7cbd53daba81538472f9295a4188ab39be2e20c41e40b4cf95fd5fb4e4f1a018eca2b2c96e645d01e7808eadebf1ae31ac8e9f4a6eea147742756ee1fe9ad71748f3add573e430c22843a39ab27786ae1dbc52e726ef3ca4169ca851c131856f107c1cc72c5355a71e89e630b51abda60b7fb20f6512a3c1e8d6eb8ecea8fa32b2e38024daac117222e29833206ac8f0388a5050ca7a60e877ff3f7229ba9cb1293a7811d4319de57bdf07fe29999aa91a2c3f013159374dca2ed0364b90d0ac88ce1d7f162349ef3f4afcc292a7b643591eb7882d7254c72941a44cd77b888c23d30433ed7909eb80862a493e762ae726d03627e4fb0368bd41dd10f9722b81c311ddacf8f9880341c362c664db25973ad5e1d90460aa6af75111774a4394d32d786dd3bf01f70740d15668f0ae512599434cb211ef0093e8324f88e967c62b0392595834ec35dc4591328cd660fadee7404237b6369120dec6579db6204fd20522fa13c4687c98b73d5381a9c196e6d2637f04b54f3d1a4d433486b0e5f09fd0c7c3bd4505c5a824676a3cfe88285c218b3c9721975ca85376b4d3d61cf1a44688a45a5bbe416d0a90361927eb5a236e8038240e68c00ffd570d9ef258ea4be73cc4c024807d935b835dd8653e8954b6b26dbae7ab45fb05842e2ddf0e8d355d0211b82a17ab86bcada8272bc4f11458de9c403fa3e70b7944720bdf9bb18ae9768e2c2a9c10e01c399e911ed59fed7f1db8bd2dc7f6f47e05c9fb74d4bd50390c81d47f10a6cfbc09d9223028f5b1c6191cdf58563c530f83e3b06248f6ec60fd02e68c1f2694a79d5b4416a186e46f4f3ede684b7e78030f1f6e472215cbd16649e16ae261762e6098e209ae885879360053f0c3c9ef1ec5e335c4ce854d7958dd6e6c0fd3b4e657d0a2064c7eb63f6a91f830d4fa1d517fbb00bcc39935ff0975a0b9bfa5bb050ccd1565dd52b5ba6fffe29fe7a0efc5a6b6034f44ce39609b9e3c99b304b0aa8f6a1b2f0a91ac4f665c1d9ec76c63133cdc1e04c151593ad8c5b2a52781dece2ffb9794ace361a71ba923c97d74c1e0e486c7ebdcef924d6b266ddff48d094688e935884fb589169b3a97ee2cece3ea6e8f5f685a8dec831155cb7a81700f71abdd6f8f78478a9f44046d773c01d4a2b90f9835b2dadfc07b3424342330f95fde4acc74a1c14e86b805adca7db28b01ebeba72f40a050365d2fbe453ee8b5d9940a9d93770af85ba2d4d8cfa5f3e71312a21e5050abc66e364e1bc05bc5ee0ff2ffacd558cba333673746333f42f41aefb1f67d7937e4042f7feceeef0a3b403748a6afd187926eb5387d091bc8825e74a326f433944d2b72580be189a40769674601488934eef42654140daa5078d99732199cc9cee76feeaa8110178d4229417ac3e883dc54db523b59ef6c5dc9be59275af2bfac75c59b140f947b397603b26558f3e539140a8edc848208a6612c7ad3ff9198f7aca6f374289802960c2feeaf7a407d0d748ddae42ddd7d42c7216122bab843fda9c870989a4a8dfaf43eef3ad9a1b7ea032a73b78b850dc4cc617cf56215a4a5c6c910663f62e072a2a59fe1c8b3edba91b21ae134a9916e7a7faa7ed30106d15c358215d2168c6ba9508e344d72d889300ecc23268a0803f1baeb51cd7010420280678258a30019bce699a09c82b8b7110009915b1f06ada7516d53415ad28d32b4ab16a56a20e27681295b45819ad393ef1179d11ca22e1b3ebc7f9d3583904270c8a9f142b38141985156f60b4b23fc920814970afbd897fd91c0ee4be78cf795a53668e6daaf9d8bd22f80231e6939e412facab3d0feba139133b04f7f9cf4abdb2ce1d20a655a271735bdcad9c0601f22fc9bdd8d87b6fc6467f666bf5588bf40d787837a0b29c8c46681a30a06bce0d43a16392ae6c6a68fdcda20f2758fef758b2e9baf373c5472614c6a37fdb95cec6e641883aee108cf41e831feef2e4c9cbb0289757c60a432505e93bfebd5cef73a9acb268bb586d2accff267b15262f0f067a48cf3168acd93aa4374cf5d1db5117d35772896d752ac82571734752bc73350bfa30beb4c203db901e7ccf99a033357a4db87931a906f9d9de9085a419b7d1f5f4d55f830154f78065e7d431c942e793675af7fa744431edf769fce9879d9f4f36427192f34c4b336ebbfbf91a6a06adf2e774405d2dcd3fe9207486438af72c3b4e408d0169b0aca852f37555f15290b66e3f05faa756d92802cc0a1a5e0a14150a4d9e7a9f40fc44fe4bad103aa11ab5836b4fdd0abccf747fe89558271fd13a78808077e229cf1ae2c1bb82d4fab9a3003761e66e7c4d9118cfdcc386c6353b5cf862e1e4ac02b1132ee5c3ade2e382de30c5d29eafeb5e5d5128aeae3a6c9ad43ba05f609fb69bc6acda7bc13fd03ae4da6d9408778b58fe0babaf34ab67c62eae8d82e95fc723bc34c2f157f106bcaa647468ad4de214e7529be3d7d45970408af52dd703e2a4fc3c32877fdc0da992dbb6891b9aaf95b32190fe12e1ba82dca96aa6a6fc37657446be72c9d9461aa50fd10e0232732eb877c5ca32077cba485a6dc7b3fa13d3f6fe28e1b9e1aaca3236d4bc30ae9a8a4c1b745202f3c3ab8acb53d54403c3e2353b61e11d7d259538abaf628ff5b36624dffe0f60d6e2c796927fecbc4ad86c6f24e4f549266264f3cfba3f8ae137e9bb09b871ee9f6fc52c99fbcd1475707c57e0a03c1f714e3e8e47662caa0e9ad23bf891bbffd0c8110ea2a3dd10ea52774f79b79c5d0cb0e4d35ba1e766119670f19aa8baf12d333c0400df76ae3cc285fb51511a5dc7b2609b31fc0f11dd7d8bf149a474d65e4cfcf7c49dfc97220e4f9f739977214c0e051ee6a77b29555d52d49636a3871dcce6e459339efe113afcfda3db56f86007cb120d9c19a86df439ae472d483c770ae69392bb31470fb2ee26bb7a123d2af42e8bce405f8c55ebadc48e78f3f859f8ce1ec76c7b2e194ab1063021e233490069387aa23784c4df5da28f4e9e31bedffb238dcc262ce2a926b055d534416782e3401470030d4c16ba50c1c29cf877c73274da3224158f8784d8639a3b2b59c787d2bbcb0107f7f39fe54dce0cc9eee764d62c971686d08873a2975b92dee3ed267f27ae1696775a162ad8e0a13651ccf1e3bcab50760de7bf996e6a4c7d7dc51bfd30557e97743ba33459948921098f9738dba9930269e51b8a190345481bc73cafcf9f6ab1614573f0cc1334838c30df985b2e8fa666bab004325f5aa7790c5091a9a34bc15b3aa7aa465a55969099aa7cbb0a29c2f3b2d542551f744c75279041294b04a50ab578cee984caccaa2f04633ae63b0e924e86b0c3b2a314d7cdf527940670a854bde2d0485be7a6ba4da91b040aacda7d92b3f25a0f9e65855042198427a374dfb45f5d722f4d3464a52615022962b7855c514bf1c5b10c3204ce0ff260d614d35910b5c781805f40dfccc2dd39254c02bc5c0799bdd4d9adbfb661e7b67d72f115ca8d4d75f150535cc523574d4855ebb1193777bbb1f505d6b8196dee742808ab6b30583ee6f9ef5fd3f6b4a1d64f9afe6ee28dce098bc87d02e39b07aa9445d76f841203cc9c22c9e9ec39d382964192447ec548570f12091227a43a80b59b094ee5486cb9e5f4eec646d8867ff04483822909863248517a2ebad8e7418c2ba687cec5f5dfd1f76db5ee74dda4e08066d18335937bea758e4f65e88baca63eb4b852deb81a56abfbfd74a8b8fcb939780a81977a1cae90137785bc1467560740a510632e85b247fb37d6b8128a773e23fa2910072bb620510711cf0b9f526c5b03d2f852b22caeafeb7fabf9d95900242c6f8e003413a3f63aa76affbf73f96471505cad3c7d8aad4f1c4a14d0bf5138a30f7cc381bafac817f72c28501c5b8503d327b3a941d95768140fae44c4f1ec5d9c5ba82557b37c3044c49d6c5d630f08f0621cfe04080c6058840454ebea29260edb7e9419be55eedb8c581b6568ddefda74ffcc30e4adb276175cc74826fdade0a1d1af3c114cdaf3127391307661c3eb3ad37887c6b793d5b1887fe2dc542688f1f0337083a91c5e414e6a1ae37d262e7c07ce0afa199a45c18df057356bb48fdcca8ed247edbdfbbbd56f4e03582167d7cc4d4b98b3f71fa2c4326d145ca7941a2489cd6638f51a381a26bd66b3f46096dc0d14a99c8ce98b7a6d8fbe629a9cddd950fab1ed0734216aa78417296aa10b2367b27d5ccb26fc8543521582dcaa8ec373b184a5fa13e19bc76c4ca9d712a6563eb826e095866fba6b5fa7a5675868a02e2bfe0efb140efcff4fa82c28d02f9e45b5297d5892242f05aaf79b0d4c97ea4f3063894f5ff715f3c797696fec9c10acc4352c1153f3a966c2f5737cebe5e1acc907f46b666dcc0209a6513938613e637a1694412ac4719b25f31626191cbcf9f7fd93f0b3748464f3ed383f097ee301aaf675d92497cab80ebc1c8c8a17ba025815f02b6368ed227bb7f676ae79cdaecad25cea3e5b01a3bb9ebd5165d8aefef33129b71fbc9e936fb5f784497878985ae6ef16985f450e181205a9efd529410a19c8a8f13eafa9a5aa17d186c4b1a7aae9dd5a060983336b04cb80f4dca5f5168be63d7a91c9518cfce0009a61900b7f962644abc4e0804525e8a5d5dc77790cbd87e6971a931e08b0560cfadfb89c77bda573ff622f12cf9749ac485ff4daef936b224d5d02c715bdc6a95a02d3db8f1066b7c9ca3004f3b5c860ce21ca810815fa33d1b2524b960297714072e613663d0b86ceed2038073fe931d8c3e239a09b70d75d685e8d125ce245919c00e9926f3b75422c9da499d28fe1a642c569afb5b7a34df47a076b4b1918ecb2740e72038dd0fdaf0f1a3aa18b2ea2c9a3acf937625130501fecbba0d53b1e23338dacad7a76411ffbea8f021d613c1a278147197f04083210394766c21c3cf6e6aa54f092767323ee7fdfd631e56cea7af2f6c554872ddaf95b155ab7d39084ee1c2d53b3d01ff9de1bcf6813fc0213adc1f21ac0f900baec21e8ef84b42d867394f31420fd749912bb7ab42edee1daf4dc85ed718cdfe0cb23b6c39a2a333849acc5a470cc18f8c54cd56068c3a51f72f38aa1562a2ac9b71eb12b72e8a6d66f07f703b4120f597b7212422e8661a636ef7163dc7f00616dff40c22ca1f8fcdb04dcf55f623ffbff0946f0be1753d573a0effb229c9a5fb473f382fe1e7a65736908c28776c9ac7b534870fcec5724ecfc514c976dcc0b5e8f67882cbf4240b2e17e7480b4290e9bb7f7cdbb6412b1b21950c2818413702b0793137a957f97a4118f09ffcbc2fddfbf2477d912cfbabce152b06cd54439e67d590560765e75432fb977ef60023133acf27e4f967c471cd3f2cd603803653aaf28115443a1fd569978798cd3b474eea9664e83dfa5fbd946818e752a4d0ee08739ae0b3cdfe9dd825de6e4d591570942bdaad5ad5cd00fcf3bcbdff1e4ac092daad9d9aafa88baac7ad16145225b6731e191475fc773a6dc3ed3381101238586af0c41927a24a17caa965d975618026e6be4e2f989a96da605b4ca8da0e1f6d31aa77ccfe62fb152f108ad03c3161ec5da2910154e7645a241c72eee397d0f6c280a5079f4d2c65f512b2693a16f4d3fa93704df34007ef3b7983252ab3e447dc3abf99c15efe271f2698d69bafa890786f3f758369e647e4e00980a394d04f98350ce51b982e48505f5e4908e45e3232f955796e1d2e94155466a81905c5feda14b5b154730a417e0d3c8120046a9476a3e5123adaad3fa5f5374b24cc1e012f4b365bfa186d26d61f5fb9aa5abec86422f967a74f4acda350adbdb94b3f8a832a0a0499ec34263e1f5515942702d97dfb0eb08c961ed01490b1ff0b22d3812be939eed71ad7595f1139a22287e04506e2567c548bef9454b38219dcf4c8f129e0f633fc6e665d3cabee19f3eaab6ffd280751ef71afa4d2389a9c6cace9c4b9dd97fc402ea4cefb424e339137408255ad146d5965bf925e4af7ae803f6c562f777ec5500f15ab05f554317ca68577bd53891e2aad95817d239f092b68f1ed1e62184633eada645b9569d6e9390bcce7af90646e582182bc18227417eca2f584f94c77b53673d35081cd44627215a4f4e0a66ef9da66d9ccc9d256fff4d6951cf77ab3bf368f99eafec7b65a48db2e4a131aef94dda80ee51655da93523d949720ba9b5c019152da00b29c68fa0b07597d01d45541f1c6b010c21ae5a0edcd495de578f14233fcb4c3ee2f12857e77e93039799e2941f78c669fb7a3907eeec10bb31b379c4553f376c9b71f76f7f7af285a9c2758a725e5440a726128497db981f30ee92ce6e59f5253cece4498e9db8b930c925fa80f2928c25f9e89d0e9f716c3a02d61545fe86d24ff25797d0647edbc68912d1daeeb52691fb5afa1febe415d4da50b1dcda8e26625ff13161b75ec9f04e18367db5fbce74f4c649cd19609908ef415cf7603349026465ce5a1d87148314e6a1188aed55fcc2dfda55943cfb179ce2741141b11820ba1b5a2a48b6f42a9233c642852d5e5fead398a6ffb8aad99358172849c43d3747ddaac26a20524d67f19b6bf687ff7bfef212c846b5b0d772142c60f4595800d691afdab1cf5f88687a0208abe3f84c3bea0a729ace3810069b1285bdc82e567ae40d0ecb11c6c2001bf5e8ab928e7521918f21a7a844df464210ce4db34b3e27060ea1906e26e987b26999e766cacf66d269d35d3aac109199c603bb97e576faf9f409ddbe8590d90855c8314697289594f6adca936814bdab0a92270b722fa407d1941e09d51296aa2efdeeb4cfed849d8c47a5feca4dcc8194189e7035d10bdbd157464e7ddcd14195d0e82b5d9c183a487e837f947a8f6b18468acd67660a6438d900e537cd3f546765d0f7d7799a0e2928bfedc577ac61f06e89a5b58f8c01b5698c14a49661c8b3b1b06d24596312d2d248a46c21a7dc09a3e92931da990072c1e8a96a25649d038608006f233643e8cae5414f51542809e69aa58bb0153f8697d492d65559c846ef077bd8c2acca9250ab803689a26d0f55b78eef8995a30296033f256707865ed08bfdcc9e2dbe956b21d0f60e194fe546af1f073972b54d2aa0cdfc814b364cd1c150d7eac69c2edd530e80e7597251ca359ea3246fbb90e3e1ceb39daff88edce3f35485cec647f49d7b323d71020a9b6e74b4ad742e975f1f94a33c5791ce65de1b38f1c1f8f78de2db771c3190e7d8d830e7e8f6f5c1859cff96e95e74b9b7c57b9b81238d77d5bc9f4cb074168c41e47cbd2d7e782850c91f2c897e0f3852ca8ecf7cdb2d0a9047a715f1b69f6a45a62d0768c458f1db5bd6cdca93add4854503f1eb69256b10fe1042bdb2089292e8c2c465c928554f9dd8434bad325e3d921ab12b19a6cd8d3b0ffc4b422d21e7eac34d1b94721dfe5776fb4c7c6b66f873b3fd5cdceaf6a8f4fd812cebf2f24ae3b0c5857903ac4282c290d854c52f08a7cddafa44275307d7a52cea5ebab124f4a90155997b0d1b77beb76fefe7bedc889af5c652eab088f11f2d9eb65c89f33e12aceee43f7506a8f15a1d5a4ab9d196ae1767e259980d0cdb455c577e7c94f93699d687e678c8db889b275a23100761a9038fb7b590f5b62da82fe9227a448459040f69e554e66e1b5ffaadfe01556a4cf3869d81d5ee2ed966d66e590c161949a3f222c4e0d4b5eff94788f0c71db9022cdfd4dad9d9029969bba38f3de081004c4c252252a78e55b7b710a061e821666fe91c472125925fa841b6c5677ea9c19f1c3fa70694c451d87df630a003f4a8339b6fdf002b49d69915d73386900a43a2c617bdf263dbe0b0ffc166d973025c3f01e18096fe6f0311f8400d9509d8ac79cdf8b74760dda08c0ff38fb7f29203a6045f2b50e00d569ac2d9f74534292b7bc1654e7ca7279653d3554e910be87d1fcc6e6df5370392813b751c4cc93a98384a7a67b92a3a71548f440b2ebcc9e723fec3744b5d614bbed6efe8d9dcf31f82de460ff4c870ec8df419feb85c672ff62c9791bb1469c00e2a69e985f4ddc47bc255152f3786d79da2b06f5de57bc108541ae97a40ed79c93a7fd99095629327a3bbb289959ccafc0085ecb03916cc3a5c36f8ca68886dcd97466222c8908222fbaa032872ff4b01390cd730bbc0678fb77ab1f0c9cc3ce179007f59932ef5418ab040ee2c0da119630455c9cf219e03fbca4fc6ae5b9b2f12963aa0ea6819bdc75fa7344db2cd5fc152f3c7881ccdd58e744f449433eab322de38506d685a70e30320d3b822ef60ae2ea4f5fc6855d66014643a2ecf43299fe12c656e3620a488e201b0615aed320bb0e7779a413e4d8f74d4f23fd4044540bb3af988f55b4d757eaa0964e9b041370c34bc5b33c223d71f14c55ad03e823f398cc5e508382673bb58c6b489794bc410201779c7fd42dd635e7a550b83036a4cf9641136c54dda453786a3786f988a11cfa15a14c851536acb5438e3a77deaf20e00e1e08b5168ceb2fc97d993b06e17de150be7e86f06daa2390bd9f31f61be159a69f3dd17bb7ba24181f2a076a3168174fa5e869ff12177662897dac41b159c1e6e22a2fa55e6d0c97e03c18d18eebf0c798d000744f7dec3c4682df038b9ea8aa01261f8c3ea73e9d76ac22dbbb1b06aa0711026efa9489a22259a751145dd1b98a70a8d7db3c9811168688c77253ae4a3778096653b5f11383c19af649dd217fcbdc547257db9e51321d1f7ca5baef3a152b9a03635270d0ea3e11287269110217a4b24f14dca427ad796f23d7e7d181ab0c205a9f567a9cebcec542dc90a9c5695824416c49ecbbd4400338005aa78a4ecd9c005178cf0fe27d80ba62fbf9c93e569401ed8fe146d4dbe5b6d4f140d8c0aabb24eba317bc5e19adf093d03865349de0c56c443afb8022a892342c2a63f75107042292b36589360572a992dc4b653502b9a157731aece1d4f8cec13158e162d4763809051ec0bb81784f81ec07e3f5fedd981fb8a53d1e5830be19ca4ee5822b69119aa53b22263d6ba226ef6f3574e8ea340d905acacd23de30e5150fd28943955634492f5b2ed64f415591dad086f0e3c8c357a87a503d4ae7629fa5771be6b47d0f9aec260fd151c8c238a8884fcc88dceb1910b8d47783f2be067177e829597532a6e22bcfdaec2492ff0c5fbd462fa7642ffa3085ca6b8e41d19df306f09822bda49a17dd9a6a5cc2605d8427a8cba81d6b3df6db21d1dd827575339ca8e6bd7c9326a05d79084e90021e4cad32fbaebe73330aa4ecad3fc10e467d442c507128908500c052624d1dcf512a2af8cb27d9f0efe5facd83cbce67a81f7b681a52455adf2db9f9b3705121669cf796ca25de5dc1d90fcc94c45c1bf0259d42a2cd7c46617e568ac86c3bd721ef39839ec5853ac746ab00291f7d584e1b46894c65e215b72c8c1f92f96d5eee0361e22c9eb0e7ab727b3b1e69fecd25672b67f62ac8d4c096ddd0e68919afe8eba0c22e3d141b0e3f2de5d206168530fec1f4aea570e28efe744c534e1dc37e6d0790191eef9bef745f5cba16b1f087b97bb7fd9eaa9680a7599d9f87be4c1d2a1e6e8efaffbf794c042f4b507dd042de884b597de19d0333160174821d10c6b1ce28d8ac2e607b4ad05d285b875ed5a05866dc21a4198c340da3515d54e5b16119baa0086073492c107d998d2e9e29ced74882c9ada03cf3ab55037600490d2be6bad8845ebbf015180e4cf94030ddc8eebab91679794ac884d0685489bdc4cbbe6401309875405e45c69b3d1f4e6d485620e6a223d559cc966970e3378b7cee045b2e24788ee73a4c8856e21f43380bfadbd84d127e670f7e74960a437d0445c42edaa4588303cf427cf21ed8aa829e0355c254895cbf12a904d58256a10e4f2edb37be9fb947012547b890b0adc6e84e18c001fd1262cdb5171c9920549be28e8c511886370f04bd7a0e4b21aeed36f7faaa17a82f3f9899b9e0e83001a65f7d3f01ab5fec35497cfeab476390878d0d5d212b89cf8f0cb82a4aeb6d51de6dc9717a8f364c26391d5e0adc14ec976c1312a0cfd68469b1208e85b3126f58516dceafcd9ab571b28b3b35186406a4a77513bdb04790172c3e58e2d8780d07918c3b8d37d503681b7bd112bcad55ca4e7c41bfef800c62bbad735edf212e79808f5edd3531b0899831fa53fa7eccf67850e0ba8685811054b94f7ddb53f2c3eaa7f9af507644f3cc197aa05b830db5bcd36269983d646a64d145f3f5d0aa0441315c3fa67b1787449e30c42820f436867841d2a21800ff067af02a87b34ba436e6e14b74f942cab988d893511aa6807431a830073f55b31a6d8a67a9b2ffaa001589cab2f115fed7f5c0d14ff56ea73c53801fd408adf2595c08d1fbd542ddc91edacfd39b8ec782cf388283db2b18cbcf45600f373d7fe6d361bd25f9ae0cf67567b61237b96734109563eace08752db49f1a258e3bad80f12a1d3a71f17fbc044a295b9ab117c46b7b4b7b8b6bb0043ba9378583205cf2eb69d11c7957f557df583ffe1fc276bd474f797cf5f4a36a06d1af1724543edecfd5417624caf26d9d5df8ad8653249833e3771d1d7704f1830470024a01b35a701223805d187f311ce0f0f4a88c3aebc7f68d98d407e0aaa791b54c03d9458706272c3244ce4b7ab65bcc82fcb5f6e2c1957ccfe96523f2caf42b43500c7b220d59b7a3b60dc9e7ccdb3af03763db6cf9e3fb93526ee69822f143f1cfc4411cc1218c3084ec4bf8d9c2d86e888568d91251e5dfe59ebd950846a903b4f70f085d7b1ede8b67c7aa005f9fa4246467cbcbf4f726dd415b679d0b0d075db716644e0dfe141bd03d31d71970e0d4f56e2854bb1232a47f2bf2fea322e72b52893f8473c42485de38ae7fe9909af217634b8802b6d6c9a45f043e92bb12e63f98832b0a9f588217d7d93da00037f882c6b8f37b0d41e676b5314ea88bc1723450d3255fe8b15f86767f2083e7663e33dcfa1805ed37848bf19137f987705c9d2f2d00013d50d0474471cec55ce34af02c0b6ee8592a63582e92a2836291240a72285eacdca0f2f69b63eb82828f5cb21a0f5b87b8790e19d3529711fce75a7f83443938bfc8d7c2e448b2003240cf0f227c351cc4462087bac5c3fcd16b6a863aab723996c09f53d38acadb8d7afae18e2cc74e1cebe56c4fb775a77c44dba9cbffe9f8570039308ba5ef2337d551518d14b88e94a84bdd1ddc182d51b9c6d8c0488d60dfd09667e482687f122254f44df60dd051aac3a50167974f381ae983971ce1f87ab93a0db18957f7ff649f96802e596d1016662615b74d9de42826d720560ee056c633d10e6b472144ad5f340c0ebdf33a62ef0ba1685a9c06726b2bed14875e879a3a542144bc16a7be31e51efd9f0e98d17c29d676a0dc44913972c12cd48ee57b9b43b3dd5bf559d66051b1c0aca5c15951162ec09e7fcb69f62b5a32222ceb63245370e26dc55fcf9e5e234b84308c7d85ca62bf161c2964d80becbe7885f4aa6e2f9374cfbbe66ef3cc74feb200f6e623e8331940310f9bf20f849d3240709605d4a846aed3f8ec520a582a4f0fd101fdb93bbefa383719ee65f2fa3d87b54160173656aae7b89015a59f5517a12887d078411529db3719c48b08f6773a57156cd2ced858abc7237ac775e739aaee136e6e7c3bf28c3be5abae2d8fbc0e5f33293038a1e8462aa8c5dd23c82f6f246d038720f05c3b0b55497a413ae705377a25dcd6a55afe04441fdd98b9495efa26fccaeae946bda8e198f5d9626f26e672a20571c3d17f031454b8276f1be438c1d73be0b4ef56cc661f04f9cf6961d523f0824f29cc3c3b9d1c11c37927a6f5dfeaf5f6de9ee49b8a393565fc89a1bd7ecd72bc2ac889e5e9d61fea3d6984a2cd2d3c8e0b9dd4995d54afae6dab1941e0ef178fca2be7f95ae0911cbf65d4c6afa39e97e4c5e1e0c0264948e75e0a088607907daae2319b4c03e72696d146456af6a9546c47ed069dc8f0f68b343969051035120741f1e82318d9cf823a38686f1559227e53643a90bf22262b4badaefa61d20321c134cfb2c222132bb1f3295f951545470c621a94ea7811daf4ae390b01108af48ea7c6482477f009d3b67a0420668890d5f8dbd0b9b17406202b32d139955485dca178b31a8c61e885a8757c4bd79e4888a517c8a5fd5d6518b2768a612f4470c9f9c56df450e992a22150d35a5cf626415ca284b3b78f5034dc21ff59e95d0e7182d9bd2395c6d182d5e2eae5692211af063faf7ad08e251649f42838e58205b0853db7d9b3ce2e1090f2048b2596daf53fd0f8e502c6442d8354ef93666caa710019cac9e12f5736cdeceb20d0282fc82cebca23f02c96c47f286bbebbc13f7e6afb8ab04bccacd688ff97e447dd18cf391aeab31482e6a395363f75103101fb9f2db88bf32e488d35e108560135706225d00471fcbc161705aa80f235b288e4365fe045bc3c54f3f47aa5215d6bd58f0f46f39bb425a623e4f23b211552d8a930f4b1d6fb7f6faf58e279d62a024825e683576358b8a8c8423710fce30b2e08754d5d94de7da2a1014b14a3d5500de68717cdadb34565b38198886a2e8953302fa7e933a1089071199bb6c78fe4ae50ce4d7c183b32178d8beec9eed67c23e9fe28bd790a5c9da9c2f516ada3eb86a7aff03f985b47bdb577f8e4884ba47d58687eb9056b7a655a04155d61a3b1e2f4c56288eb4d1dbb03e0fd9709640324690ea386a8f03756cbca775ea4735d9ce6f91e3f008bca3bf6648b74211caf1ab7c46c505c38c605de16442b078a7011650324db533c6c4860a14368a599200b0138eacbcc639c1eef36634bc422e8010b1b614f68e41c7813e0131251c2979791ec8ad4f5cf13a94c0b39ba4032c48c558f841a2dfaf2ed50ed3c91d57806e8bf9e722bfacff104b5950ab281bbd5d124dd299b4a09a469775391bf690168e36b94cefcfc21e3124dc5274ea4b90bc0d4d87c86c723586525ffe1b22f5808d7aed0ffda11d6bdb0b8b6f05690b870ed4b51ebca17b30e53f237995724e2bb7cc3437dd0ca0ac0c3c6ffae7d86524fd2d684844b5b3dd4e8bbb903488deb8771f523fa827f2529415013a7b01694615c8417c18a6708b1846b84e648f0545ee8fefbf7a8ed64a8a2a79bbc3ab2dbdd8ff34c9c6166526d789bdec9f25396eabd81e4b39084737e81acb75e00654dcfcd1935fb7fd99f5703cec493f879fa0aae0e10fcd45f1d8cf6c2f8660605bf958ad0bdbc3ccdcb9ee8c36e66d2b93a1f4df8b61238ba8680505f8b9f9406d2c13e5936f53ee465c0515d6acee98bd79f8fd5ffe0194bf992856576da5475837c64c781412e1ee22baec4403c2213c250fa29b990db5927064082303c0c261a910ca12bf3919445833065fe5daaee8301fa5de27e9a55e49ec6020344af00fba769a90d085fdc36ed355be1d2ce60341b4f5967d6eb67e7702323f8b509a17060d8201d3caa3acd9680eff8270a4058aa321da3fd157f031887b632649853d5c1de652daad3a86f8237eda430d5faa19366959394592ed745c38f3b9f24e1bb3e89343de903f2aa572b3bb7207c3574dea29451c3f8e0a284b0fef4107d78d1440edc7ee7fefa4eadc4ed2fb1df74c318f2a007e8e109548d372e863393e46fdad89295f30e917fee4b6167af493193b98e9b816e1b26fa8121e4ab49253432be42fe91385b5bcb199fdbe34f725c71ebc6605487afcfe289de1064ff65c4d564d799f0873ed828eedd0bb39d4c53f3eaf544641490ce30b377d45fa23549be241300a80e76d8e6911638b13595c5cb3db87e35c79b1a49012973affc9592d8bc0306acdee2ee293610d2890765d89e0495f94cbc6a4237949a43ead87619d65daae4af71369e50464e78b3bd1edef38d760b35ff10838d2f9ddf74dd7cd6367792c5336eefe1adf9fcbb7df9f7dfe29e1353271e4503d483722d2cb6b9b0d46f1d2b0cb59cad448ed0f57a708b1938ac04220ea6af03463a36aac65dd77862934f4197c1ed98290770f0eeaf1d2aff1cbe22452f12843178d73eff54749637da66c6a0ba20a7d2192e1f51bc9ce0c4d92bdbddfcd12b64</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-xray">      <input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>      </label>      <svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">        <path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>        <path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>      </svg>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">论文阅读记录</summary>
    
    
    
    <category term="Medical Image Registration" scheme="https://www.miraclerice.top/categories/Medical-Image-Registration/"/>
    
    
    <category term="Medical Image Registration" scheme="https://www.miraclerice.top/tags/Medical-Image-Registration/"/>
    
    <category term="Unsupervised" scheme="https://www.miraclerice.top/tags/Unsupervised/"/>
    
  </entry>
  
  <entry>
    <title>MySQL</title>
    <link href="https://www.miraclerice.top/posts/c24675b4/"/>
    <id>https://www.miraclerice.top/posts/c24675b4/</id>
    <published>2023-11-16T02:40:22.000Z</published>
    <updated>2025-10-03T07:38:20.856Z</updated>
    
    <content type="html"><![CDATA[<h1 id="MySQL数据库"><a href="#MySQL数据库" class="headerlink" title="MySQL数据库"></a>MySQL数据库</h1><h2 id="1-数据库相关概念"><a href="#1-数据库相关概念" class="headerlink" title="1  数据库相关概念"></a>1  数据库相关概念</h2><p>数据库：Database，简称DB。按照一定的数据结构来组织、存储和管理数据仓库。</p><p>数据库管理系统：Database Management System,一种操纵和管理数据库的大型软件，用于创建、使用和维护数据库，简称DBMS。</p><p>关系型数据库(RDBMS)：关系型数据库是建立在关系模型基础上，由多张相互连接的二维表组成的数据库。</p><p>非关系型数据库(NoSQL)：Not-Only SQL，泛指非关系型数据库，是关系型数据库的补充。 </p><h2 id="2-MySQL数据库"><a href="#2-MySQL数据库" class="headerlink" title="2  MySQL数据库"></a>2  MySQL数据库</h2><ol><li><p>安裝，从<a href="https://www.mysql.com/">Mysql</a>的官网下载<a href="https://dev.mysql.com/downloads/">社区版</a>，下面是<code>MySQL Installer for Windows</code><a href="https://dev.mysql.com/downloads/installer/">安装</a></p><p>下载<a href="https://downloads.mysql.com/archives/installer/">历史版本</a>，使用离线安装“(mysql-installer-community-8.0.42.0.msi)”</p><p><code>Custom</code> $\rightarrow$ 将<code>MySQL Servers</code>下的<code>MySQL Server 8.0.42 - X64</code>移到右侧 $\rightarrow$ 点击移动过去的可执行文件，修改<code>Advanced Options</code>的安装路径 $\rightarrow$ Execute $\rightarrow$ 下一步直到修改配置信息，修改密码 $\rightarrow$ 直到点击Execute（<a href="https://blog.csdn.net/weixin_44512005/article/details/135777754">参考</a>）</p><p><img src="https://raw.githubusercontent.com/Miraclerice/Typora_img/main/assets/202509262210298.png" alt="image-20250926221051880"></p></li><li><p>将MySQL Server的安装目录下的bin目录<code>D:\Program Files\MySQL\MySQL Server 8.0\bin</code>添加到环境变量</p></li><li><p>MySQL 服务器启动与停止</p><ul><li><p>通过服务的方式自动启动： 右击此电脑，选择管理，选择服务和应用程序，找到MYSQL右击启动。</p></li><li><p>手动启动的方式：cmd–&gt; services.msc 打开服务的窗口</p></li><li><p>使用管理员身份打开cmd（mysql80为默认指定的mysql的系统服务名）</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">net start mysql80 # 启动mysql的服务</span><br><span class="line">net stop mysql80 # 关闭mysql服务</span><br></pre></td></tr></table></figure></li><li><p>退出： quit 或 exit；</p></li></ul></li><li><p>客户端连接</p><ul><li><p>方式一：使用MySQL提供的客户端命令行工具</p></li><li><p>方式二：使用系统自带的命令行工具执行指令</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">mysql [-h 127.0.0.1] [-P 3306] -u root -p</span><br><span class="line">参数：</span><br><span class="line">        -h : MySQL服务所在的主机IP</span><br><span class="line">        -P : MySQL服务端口号， 默认3306</span><br><span class="line">        -u : MySQL数据库用户名</span><br><span class="line">        -p ： MySQL数据库用户名对应的密码</span><br></pre></td></tr></table></figure></li></ul></li><li><p>下载图像化界面<a href="https://dbeaver.io/download/">DBeaver</a>或<a href="https://www.jetbrains.com/zh-cn/datagrip/promo/">DataGrip</a>，下载对应驱动</p></li></ol><h2 id="3-SQL"><a href="#3-SQL" class="headerlink" title="3  SQL"></a>3  SQL</h2><p>SQL全称 Structured Query Language，结构化查询语言。操作关系型数据库的编程语言，定义了一套操作关系型数据库统一标准。</p><h3 id="SQL语言的通用语法"><a href="#SQL语言的通用语法" class="headerlink" title="SQL语言的通用语法"></a>SQL语言的通用语法</h3><p>1) SQL语句可以单行或多行书写，以分号结尾。<br>2) SQL语句可以使用空格/缩进来增强语句的可读性。<br>3)  MySQL数据库的SQL语句不区分大小写，关键字建议使用大写。<br>4) 注释：<br>   单行注释：— 注释内容 或 # 注释内容<br>   多行注释：/<em> 注释内容 </em>/</p><h3 id="SQL分类"><a href="#SQL分类" class="headerlink" title="SQL分类"></a>SQL分类</h3><p>SQL语句，根据其功能，主要分为四类：DDL、DML、DQL、DCL。</p><div class="table-container"><table><thead><tr><th style="text-align:center">分类</th><th style="text-align:center">全称</th><th style="text-align:center">说明</th></tr></thead><tbody><tr><td style="text-align:center">DDL</td><td style="text-align:center">Data Definition Language</td><td style="text-align:center">数据定义语言，用来定义数据库对象(数据库，表，字段)</td></tr><tr><td style="text-align:center">DML</td><td style="text-align:center">Data Manipulation Language</td><td style="text-align:center">数据操作语言，用来对数据库表中的数据进行增删改</td></tr><tr><td style="text-align:center">DQL</td><td style="text-align:center">Data Query Languag</td><td style="text-align:center">数据查询语言，用来查询数据库中表的记录</td></tr><tr><td style="text-align:center">DCL</td><td style="text-align:center">Data Control Language</td><td style="text-align:center">数据控制语言，用来创建数据库用户、控制数据库的访问权限</td></tr></tbody></table></div><h3 id="DDL操作数据库"><a href="#DDL操作数据库" class="headerlink" title="DDL操作数据库"></a>DDL操作数据库</h3><h4 id="数据库操作"><a href="#数据库操作" class="headerlink" title="数据库操作"></a>数据库操作</h4><p>C(Create)、R(Retrieve)、U(Update)、D(Delete)</p><ol><li><p>查询所有数据库 </p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SHOW DATABASES;</span><br></pre></td></tr></table></figure></li><li><p>查询当前数据库</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT DATABASE();</span><br></pre></td></tr></table></figure></li><li><p>查询具体名称的数据库</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SHOW CREATE　DATABASE 数据库名;</span><br></pre></td></tr></table></figure></li><li><p>创建数据库</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">CREATE DATABASE [ IF NOT EXISTS ] 数据库名 [ DEFAULT CHARSET(CHARACTER SET也可以) 字符集 ] [ COLLATE 排序规则 ];</span><br><span class="line">-- utf8mb4 存储四个字节</span><br></pre></td></tr></table></figure></li><li><p>删除数据库</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">DROP DATABASE [ IF EXISTS ] 数据库名 ;</span><br></pre></td></tr></table></figure></li><li><p>切换（使用）数据库</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">USE 数据库名;</span><br></pre></td></tr></table></figure></li><li><p>修改数据库的字符集</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER DATABASE 数据库名 CHARACTER SET utf8(可以换成其他字符集);</span><br></pre></td></tr></table></figure></li></ol><h4 id="表操作"><a href="#表操作" class="headerlink" title="表操作"></a>表操作</h4><ul><li><p>查询创建</p><ol><li><p>查询当前数据库所有表</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SHOW TABLES;</span><br></pre></td></tr></table></figure></li><li><p>查询指定表结构</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">DESC 表名;</span><br></pre></td></tr></table></figure></li><li><p>查看指定表的建表语句</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SHOW CREATE TABLE 表名;</span><br></pre></td></tr></table></figure></li><li><p>创建表结构</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">CREATE TABLE 表名(</span><br><span class="line">        字段1 字段1类型 [ COMMENT 字段1注释 ],</span><br><span class="line">        字段2 字段2类型 [COMMENT 字段2注释 ],</span><br><span class="line">        字段3 字段3类型 [COMMENT 字段3注释 ],</span><br><span class="line">        ......</span><br><span class="line">        字段n 字段n类型 [COMMENT 字段n注释 ]</span><br><span class="line">) [ COMMENT 表注释 ] ;</span><br><span class="line">-- 最后一个字段后面没有逗号</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">#例如</span><br><span class="line">CREATE TABLE tb_user(</span><br><span class="line">id int COMMENT &#x27;编号&#x27;,</span><br><span class="line">name varchar(50) COMMENT &#x27;姓名&#x27;,</span><br><span class="line">age int COMMENT &#x27;年龄&#x27;,</span><br><span class="line">gender varchar(1) COMMENT &#x27;性别&#x27;</span><br><span class="line">) COMMENT &#x27;用户表&#x27;;</span><br></pre></td></tr></table></figure></li></ol></li><li><p>数据类型</p><p>MySQL中的数据类型有很多，主要分为三类：数值类型、字符串类型、日期时间类型。</p><ol><li><p>数值类型</p><p>|     类型     |  大小   |                 有符号（SIGNED）范围                  |                  无符号（UNSIGNED）范围                   |        描述        |<br>| :—————: | :——-: | :—————————————————————————-: | :———————————————————————————-: | :————————: |<br>|   TINYINT    | 1 byte  |                      (-128，127)                      |                         (0，255)                          |      小整数值      |<br>|   SMALLINT   | 2 byte  |                    (-32768，32767)                    |                        (0，65535)                         |      大整数值      |<br>|  MEDIUMINT   | 3 byte  |                  (-8388608，8388607)                  |                       (0，16777215)                       |      大整数值      |<br>| INT或INTEGER | 4 byte  |               (-2147483648，2147483647)               |                      (0，4294967295)                      |      大整数值      |<br>|    BIGINT    | 8 bytes |                   (-2^63^，2^63^-1)                   |                       (0，2^64^-1)                        |     极大整数值     |<br>|    FLOAT     | 4 bytes |       (-3.402823466 E+38，3.402823466351 E+38)        |         0 和 (1.175494351 E-38，3.402823466 E+38)         |   单精度浮点数值   |<br>|    DOUBLE    | 8 bytes | (-1.7976931348623157 E+308，1.7976931348623157 E+308) | 0 和 (2.2250738585072014 E-308，1.7976931348623157 E+308) |   双精度浮点数值   |<br>|   DECIMAL    |         |              依赖于M(精度)和D(标度)的值               |                依赖于M(精度)和D(标度)的值                 | 小数值(精确定点数) |</p><p>如：age TINYINT UNSIGNED score double(4, 1)，长度为4，小数1位</p></li><li><p>字符串类型</p><p>|    类型    |         大小          |             描述             |<br>| :————: | :—————————-: | :—————————————: |<br>|    CHAR    |      0-255 bytes      |          定长字符串          |<br>|  VARCHAR   |     0-65535 bytes     |          变长字符串          |<br>|  TINYBLOB  |      0-255 bytes      | 不超过255个字符的二进制数据  |<br>|  TINYTEXT  |      0-255 bytes      |         短文本字符串         |<br>|    BLOB    |    0-65 535 bytes     |    二进制形式的长文本数据    |<br>|    TEXT    |    0-65 535 bytes     |          长文本数据          |<br>| MEDIUMBLOB |  0-16 777 215 bytes   | 二进制形式的中等长度文本数据 |<br>| MEDIUMTEXT |  0-16 777 215 bytes   |       中等长度文本数据       |<br>|  LONGBLOB  | 0-4 294 967 295 bytes |   二进制形式的极大文本数据   |<br>|  LONGTEXT  | 0-4 294 967 295 bytes |         极大文本数据         |</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">/*</span><br><span class="line">1). 用户名 username ------&gt; 长度不定, 最长不会超过50</span><br><span class="line">username varchar(50)</span><br><span class="line">2). 性别 gender ---------&gt; 存储值, 不是男,就是女</span><br><span class="line">gender char(1)</span><br><span class="line">3). 手机号 phone --------&gt; 固定长度为11</span><br><span class="line">phone char(11)</span><br><span class="line">*/</span><br></pre></td></tr></table></figure></li><li><p>日期类型</p><p>|   类型    | 大小 |                    范围                    |        格式         |           描述           |<br>| :———-: | :—: | :————————————————————: | :————————-: | :———————————: |<br>|   DATE    |  3   |          1000-01-01 至 9999-12-31          |     YYYY-MM-DD      |          日期值          |<br>|   TIME    |  3   |          -838:59:59 至 838:59:59           |      HH:MM:SS       |     时间值或持续时间     |<br>|   YEAR    |  1   |                1901 至 2155                |        YYYY         |          年份值          |<br>| DATETIME  |  8   | 1000-01-01 00:00:00 至 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS |     混合日期和时间值     |<br>| TIMESTAMP |  4   | 1970-01-01 00:00:01 至 2038-01-19 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值，时间戳 |</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">/*</span><br><span class="line">1). 生日字段 birthday</span><br><span class="line">birthday date</span><br><span class="line">2). 创建时间 createtime</span><br><span class="line">createtime datetime</span><br><span class="line">*/</span><br></pre></td></tr></table></figure></li></ol></li><li><p>修改</p><ol><li><p>添加字段</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE 表名 ADD 字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ];</span><br><span class="line"></span><br><span class="line">/*</span><br><span class="line">为emp表增加一个新的字段”昵称”为nickname，类型为varchar(20)</span><br><span class="line">ALTER TABLE emp ADD nickname varchar(20) COMMENT &#x27;昵称&#x27;;</span><br><span class="line">*/</span><br></pre></td></tr></table></figure></li><li><p>修改数据类型</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE 表名 MODIFY 字段名 新数据类型 (长度);</span><br></pre></td></tr></table></figure></li><li><p>修改字段名和字段类型</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ];</span><br><span class="line">/*</span><br><span class="line">将emp表的nickname字段修改为username，类型为varchar(30)</span><br><span class="line">ALTER TABLE emp CHANGE nickname username varchar(30) COMMENT &#x27;昵称&#x27;;</span><br><span class="line">*/</span><br></pre></td></tr></table></figure></li><li><p>删除字段</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE 表名 DROP 字段名;</span><br><span class="line">/*</span><br><span class="line">将emp表的字段username删除</span><br><span class="line">ALTER TABLE emp DROP username;</span><br><span class="line">*/</span><br></pre></td></tr></table></figure></li><li><p>修改表名</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE 表名 RENAME TO 新表名;</span><br><span class="line">/*</span><br><span class="line">将emp表的表名修改为 employee</span><br><span class="line">ALTER TABLE emp RENAME TO employee;</span><br><span class="line">*/</span><br></pre></td></tr></table></figure></li></ol></li><li><p>删除</p><ol><li><p>删除表</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">DROP TABLE [ IF EXISTS ] 表名;</span><br></pre></td></tr></table></figure></li><li><p>删除指定表，并重新创建该表</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">TRUNCATE TABLE 表名;-- 注意: 在删除表的时候，表中的全部数据也都会被删除。</span><br></pre></td></tr></table></figure></li></ol></li></ul><h3 id="DML"><a href="#DML" class="headerlink" title="DML"></a>DML</h3><p>DML英文全称是Data Manipulation Language(数据操作语言)，用来对数据库中表的数据记录进行增、删、改操作。</p><ul><li>添加数据（INSERT）</li><li>修改数据（UPDATE）</li><li>删除数据（DELETE）</li></ul><h4 id="添加数据"><a href="#添加数据" class="headerlink" title="添加数据"></a>添加数据</h4><ol><li><p>给指定字段添加数据</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);</span><br><span class="line"></span><br><span class="line">INSERT INTO employee(id,workno,name,gender,age,idcard,entrydate) VALUES (1,&#x27;1&#x27;,&#x27;ItXIE&#x27;,&#x27;男&#x27;,12,&#x27;123456789012345678&#x27;,&#x27;2000-11-01&#x27;);</span><br></pre></td></tr></table></figure></li><li><p>给全部字段添加数据</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">INSERT INTO 表名 VALUES (值1, 值2, ...);</span><br><span class="line"></span><br><span class="line">INSERT INTO employee VALUES (2,&#x27;2&#x27;,&#x27;张无忌&#x27;,&#x27;男&#x27;,18,&#x27;123456789012345670&#x27;,&#x27;2005-01-01&#x27;);</span><br></pre></td></tr></table></figure></li><li><p>批量添加数据</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 给指定字段添加</span><br><span class="line">INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...) ;</span><br><span class="line"></span><br><span class="line">INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...) ;</span><br><span class="line"></span><br><span class="line">INSERT INTO employee VALUES(3,&#x27;3&#x27;,&#x27;韦一笑&#x27;,&#x27;男&#x27;,38,&#x27;123456789012345670&#x27;,&#x27;2005-01-01&#x27;),(4,&#x27;4&#x27;,&#x27;赵敏&#x27;,&#x27;女&#x27;,18,&#x27;123456789012345670&#x27;,&#x27;2005-01-01&#x27;);</span><br></pre></td></tr></table></figure><p>注意事项：</p><ul><li>插入数据时，指定的字段顺序需要与值的顺序是一一对应的。</li><li>字符串和日期型数据应该包含在引号中。</li></ul><ul><li>插入的数据大小，应该在字段的规定范围内。</li></ul></li></ol><h4 id="修改数据"><a href="#修改数据" class="headerlink" title="修改数据"></a>修改数据</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">UPDATE 表名 SET 字段名1 = 值1 , 字段名2 = 值2 , .... [ WHERE 条件 ] ;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">#案例</span><br><span class="line">-- 修改id为1的数据，将name修改为itniuma</span><br><span class="line">UPDATE employee SET name = &#x27;itniuma&#x27; WHERE id = 1;</span><br><span class="line"></span><br><span class="line">-- 修改id为2的数据, 将name修改为小昭, gender修改为 女</span><br><span class="line">UPDATE employee SET name = &#x27;小昭&#x27; , gender = &#x27;女&#x27; WHERE id = 2;</span><br><span class="line"></span><br><span class="line">-- 将所有的员工入职日期修改为 2009-09-09</span><br><span class="line">UPDATE employee SET entrydate = &#x27;2009-09-09&#x27;;</span><br></pre></td></tr></table></figure><h4 id="删除数据"><a href="#删除数据" class="headerlink" title="删除数据"></a>删除数据</h4><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> 表名 [ <span class="keyword">WHERE</span> 条件 ] ;</span><br></pre></td></tr></table></figure><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">#案列</span><br><span class="line"><span class="comment">-- 删除gender为女的员工</span></span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> employee <span class="keyword">WHERE</span> gender <span class="operator">=</span> <span class="string">&#x27;女&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 删除所有员工</span></span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> employee ;</span><br></pre></td></tr></table></figure><p>注意事项:</p><ul><li>DELETE 语句的条件可以有，也可以没有，如果没有条件，则会删除整张表的所有数据。</li><li>DELETE 语句不能删除某一个字段的值(可以使用UPDATE，将该字段值置为NULL即可)。</li><li>当进行删除全部数据操作时，datagrip会提示我们，询问是否确认删除，我们直接点击Execute即可。</li></ul><h3 id="DQL"><a href="#DQL" class="headerlink" title="DQL"></a>DQL</h3><p>DQL英文全称是Data Query Language(数据查询语言)，数据查询语言，用来查询数据库中表的记录。</p><ul><li>查询关键字: SELECT</li></ul><h4 id="基本语法"><a href="#基本语法" class="headerlink" title="基本语法"></a>基本语法</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT</span><br><span class="line">字段列表</span><br><span class="line">FROM</span><br><span class="line">表名列表</span><br><span class="line">WHERE</span><br><span class="line">条件列表</span><br><span class="line">GROUP BY</span><br><span class="line">分组字段列表</span><br><span class="line">HAVING</span><br><span class="line">分组后条件列表</span><br><span class="line">ORDER BY</span><br><span class="line">排序字段列表</span><br><span class="line">LIMIT</span><br><span class="line">分页参数</span><br></pre></td></tr></table></figure><ul><li>基本查询（不带任何条件）</li><li>条件查询（WHERE）</li><li>聚合函数（count、max、min、avg、sum）</li><li>分组查询（group by）</li><li>排序查询（order by）</li><li>分页查询（limit）</li></ul><h4 id="基本查询"><a href="#基本查询" class="headerlink" title="基本查询"></a>基本查询</h4><ol><li><p>查询多个字段</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段1, 字段2, 字段3 ... FROM 表名 ;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT * FROM 表名 ;</span><br></pre></td></tr></table></figure></li><li><p>字段设置别名</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段1 [ AS 别名1 ] , 字段2 [ AS 别名2 ] ... FROM 表名;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段1 [ 别名1 ] , 字段2 [ 别名2 ] ... FROM 表名;</span><br></pre></td></tr></table></figure></li><li><p>去除重复记录</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT DISTINCT 字段列表 FROM 表名;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">#案例：</span><br><span class="line">-- 查询指定字段 name, workno, age并返回</span><br><span class="line">SELECT name,workno,age FROM emp;</span><br><span class="line"></span><br><span class="line">-- 查询返回所有字段</span><br><span class="line">SELECT id ,workno,name,gender,age,idcard,workaddress,entrydate FROM emp;</span><br><span class="line">SELECT * FROM emp;</span><br><span class="line"></span><br><span class="line">-- 查询所有员工的工作地址,起别名</span><br><span class="line">SELECT workaddress AS &#x27;工作地址&#x27; FROM emp;</span><br><span class="line">-- AS可以省略</span><br><span class="line">SELECT workaddress &#x27;工作地址&#x27; FROM emp;</span><br><span class="line"></span><br><span class="line">-- 查询公司员工的上班地址有哪些(不要重复)</span><br><span class="line">SELECT DISTINCT workaddress &#x27;工作地址&#x27; FROM emp;</span><br></pre></td></tr></table></figure></li></ol><h4 id="条件查询"><a href="#条件查询" class="headerlink" title="条件查询"></a>条件查询</h4><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表名 <span class="keyword">WHERE</span> 条件列表 ;</span><br></pre></td></tr></table></figure><ul><li><p><strong>条件</strong></p><p>|     比较运算符      |                   功能                   |<br>| :————————-: | :———————————————————: |<br>|          &gt;          |                   大于                   |<br>|         &gt;=          |                 大于等于                 |<br>|          &lt;          |                   小于                   |<br>|         &lt;=          |                 小于等于                 |<br>|          =          |                   等于                   |<br>|      &lt;&gt; 或 !=       |                  不等于                  |<br>| BETWEEN … AND … |      在某个范围之内(含最小、最大值)      |<br>|       IN(…)       |       在in之后的列表中的值，多选一       |<br>|     LIKE 占位符     | 模糊匹配(_匹配单个字符, %匹配任意个字符) |<br>|       IS NULL       |                  是NULL                  |</p></li></ul><ul><li><p>常用逻辑运算符</p><p>| 逻辑运算符 |            功能             |<br>| :————: | :————————————-: |<br>| AND 或 &amp;&amp;  |   并且 (多个条件同时成立)   |<br>| OR 或 || | 或者 (多个条件任意一个成立) |<br>|  NOT 或 !  |          非 , 不是          |</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">#案例：</span><br><span class="line">-- 查询年龄等于 88 的员工</span><br><span class="line">SELECT * FROM emp WHERE age = 88;</span><br><span class="line"></span><br><span class="line">-- 查询年龄小于 20 的员工信息</span><br><span class="line">SELECT * FROM emp WHERE age &lt; 20;</span><br><span class="line"></span><br><span class="line">-- 查询年龄小于等于 20 的员工信息</span><br><span class="line">SELECT * FROM emp WHERE age &lt;= 20;</span><br><span class="line"></span><br><span class="line">-- 查询没有身份证号的员工信息</span><br><span class="line">SELECT * FROM emp WHERE idcard IS NULL ;</span><br><span class="line"></span><br><span class="line">-- 查询有身份证号的员工信息</span><br><span class="line">SELECT * FROM emp WHERE idcard IS NOT NULL;</span><br><span class="line"></span><br><span class="line">-- 查询年龄不等于 88 的员工信息</span><br><span class="line">SELECT * FROM emp WHERE age != 88;</span><br><span class="line">SELECT * FROM emp WHERE age &lt;&gt; 88;</span><br><span class="line"></span><br><span class="line">-- 查询年龄在15岁(包含) 到 20岁(包含)之间的员工信息</span><br><span class="line">SELECT * FROM emp WHERE age &gt;= 15 AND age &lt;= 20;</span><br><span class="line">SELECT * FROM emp WHERE age &gt;= 15 &amp;&amp; age &lt;= 20;</span><br><span class="line">SELECT * FROM emp WHERE age BETWEEN 15 AND 20;-- 常用</span><br><span class="line"></span><br><span class="line">-- 查询性别为 女 且年龄小于 25岁的员工信息</span><br><span class="line">SELECT * FROM emp WHERE gender = &#x27;女&#x27; AND age &lt; 25;</span><br><span class="line"></span><br><span class="line">-- 查询年龄等于18 或 20 或 40 的员工信息</span><br><span class="line">SELECT * FROM emp WHERE age = 18 OR age = 40 OR age = 20;</span><br><span class="line">SELECT * FROM emp WHERE age IN (18,20,40);</span><br><span class="line"></span><br><span class="line">-- 查询姓名为两个字的员工信息 _ %</span><br><span class="line">SELECT * FROM emp WHERE name LIKE &#x27;__&#x27;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">-- 查询身份证号最后一位是X的员工信息</span><br><span class="line">SELECT * FROM emp WHERE idcard LIKE &#x27;%X&#x27;;</span><br></pre></td></tr></table></figure></li></ul><h4 id="聚合函数"><a href="#聚合函数" class="headerlink" title="聚合函数"></a>聚合函数</h4><p>将一列数据作为一个整体，进行纵向计算 。</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> 聚合函数(字段列表) <span class="keyword">FROM</span> 表名 ;</span><br></pre></td></tr></table></figure><p>注意 : NULL值是不参与所有聚合函数运算的。</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">#案例</span><br><span class="line"><span class="comment">-- 统计该企业员工数量</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">FROM</span> emp;         <span class="comment">-- 统计的是总记录数</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">COUNT</span>(idcard) <span class="keyword">FROM</span> emp;     <span class="comment">-- 统计的是idcard字段不为null的记录数</span></span><br></pre></td></tr></table></figure><p>对于count聚合函数，统计符合条件的总记录数，还可以通过 count(数字/字符串)的形式进行统计<br>查询，比如:</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="built_in">COUNT</span>(<span class="number">1</span>) <span class="keyword">FROM</span> emp;</span><br></pre></td></tr></table></figure><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="comment">-- 统计该企业员工的平均年龄</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">AVG</span>(age) <span class="keyword">FROM</span> emp;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 统计该企业员工的最大年龄</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">MAX</span>(age) <span class="keyword">FROM</span> emp;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 统计该企业员工的最小年龄</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">MIN</span>(age) <span class="keyword">FROM</span> emp;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 统计西安地区员工的年龄之和</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">SUM</span>(age) <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> workaddress <span class="operator">=</span> <span class="string">&#x27;西安&#x27;</span>;</span><br></pre></td></tr></table></figure><h4 id="分组查询"><a href="#分组查询" class="headerlink" title="分组查询"></a>分组查询</h4><ol><li><p>语法</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后过滤条件 ];</span><br></pre></td></tr></table></figure></li><li><p>where与having区别</p><ul><li>执行时机不同：where是分组之前进行过滤，不满足where条件，不参与分组；而having是分组之后对结果进行过滤。</li><li>判断条件不同：where不能对聚合函数进行判断，而having可以。</li></ul><p><strong>注意事项:</strong></p><ul><li><p>分组之后，查询的字段一般为聚合函数和分组字段，查询其他字段无任何意义。</p></li><li><p>执行顺序: where &gt; 聚合函数 &gt; having 。</p></li><li><p><strong>支持多字段分组, 具体语法为 : group by columnA,column</strong></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 根据性别分组 , 统计男性员工和女性员工的数量</span><br><span class="line">SELECT gender,COUNT(*) FROM emp GROUP BY gender;</span><br><span class="line"></span><br><span class="line">-- 根据性别分组 , 统计男性员工和女性员工的平均年龄</span><br><span class="line">SELECT gender,AVG(age) FROM emp GROUP BY gender;</span><br><span class="line"></span><br><span class="line">-- 查询年龄小于45的员工 , 并根据工作地址分组 , 获取员工数量大于等于3的工作地址</span><br><span class="line">SELECT workaddress, COUNT(*) address_count FROM emp WHERE age &lt; 45 GROUP BY workaddress HAVING COUNT(*) &gt;= 3;</span><br><span class="line"></span><br><span class="line">-- 统计各个工作地址上班的男性及女性员工的数量</span><br><span class="line">SELECT workaddress,gender, COUNT(*) &#x27;数量&#x27; FROM emp GROUP BY gender,workaddress;</span><br></pre></td></tr></table></figure></li></ul></li></ol><h4 id="排序查询"><a href="#排序查询" class="headerlink" title="排序查询"></a>排序查询</h4><ol><li><p>语法</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1 , 字段2 排序方式2 ;</span><br></pre></td></tr></table></figure></li><li><p>排序方式</p><ul><li><p>ASC : 升序(默认值)</p></li><li><p>DESC: 降序</p></li></ul><p>注意事项：</p><ul><li><p>如果是升序, 可以不指定排序方式ASC ; </p></li><li><p>如果是多字段排序，当第一个字段值相同时，才会根据第二个字段进行排序 ;</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">#案例：</span><br><span class="line">-- 根据年龄对公司的员工进行升序排序</span><br><span class="line">SELECT * FROM emp ORDER BY age ASC;</span><br><span class="line">SELECT * FROM emp ORDER BY age ; -- 默认升序ASC</span><br><span class="line">SELECT * FROM emp ORDER BY age DESC ;-- 降序</span><br><span class="line"></span><br><span class="line">-- 根据入职时间, 对员工进行降序排序</span><br><span class="line">SELECT * FROM emp ORDER BY entrydate DESC ;</span><br><span class="line"></span><br><span class="line">-- 根据年龄对公司的员工进行升序排序 , 年龄相同 , 再按照入职时间进行降序排序</span><br><span class="line">SELECT * FROM emp ORDER BY age ASC,entrydate DESC;</span><br></pre></td></tr></table></figure></li></ul></li></ol><h4 id="分页查询"><a href="#分页查询" class="headerlink" title="分页查询"></a>分页查询</h4><ol><li><p>语法</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数 ;</span><br></pre></td></tr></table></figure></li><li><p>注意事项:</p><ul><li><p>起始索引从0开始，起始索引 = （查询页码 - 1）* 每页显示记录数。</p></li><li><p>分页查询是数据库的方言，不同的数据库有不同的实现，MySQL中是LIMIT。</p></li><li><p>如果查询的是第一页数据，起始索引可以省略，直接简写为 limit 10。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">#案例：</span><br><span class="line">-- 查询第1页员工数据, 每页展示10条记录</span><br><span class="line">SELECT * FROM emp LIMIT 0,10;</span><br><span class="line">SELECT * FROM emp LIMIT 10;</span><br><span class="line"></span><br><span class="line">-- 查询第2页员工数据, 每页展示10条记录 --------&gt; (页码-1)*页展示记录数</span><br><span class="line">SELECT * FROM emp LIMIT 10,10;</span><br></pre></td></tr></table></figure></li></ul></li></ol><h4 id="案例练习"><a href="#案例练习" class="headerlink" title="案例练习"></a>案例练习</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 查询年龄为20,21,22,23岁的女性员工信息。</span><br><span class="line">SELECT * FROM emp WHERE gender = &#x27;女&#x27; AND age IN(20,21,22,23);</span><br><span class="line">SELECT * FROM emp WHERE gender = &#x27;女&#x27; AND age &gt;= 20 AND age &lt;= 23;</span><br><span class="line">SELECT * FROM emp WHERE gender = &#x27;女&#x27; AND ( age BETWEEN 20 AND 23 );</span><br><span class="line"></span><br><span class="line">-- 查询性别为 男 ，并且年龄在 20-40 岁(含)以内的姓名为三个字的员工。</span><br><span class="line">SELECT * FROM emp WHERE gender = &#x27;男&#x27; AND ( age BETWEEN 20 AND 40 ) AND name LIKE &#x27;___&#x27;;</span><br><span class="line"></span><br><span class="line">-- 统计员工表中, 年龄小于60岁的 , 男性员工和女性员工的人数。</span><br><span class="line">SELECT gender,COUNT(*) FROM emp WHERE age &lt; 60 GROUP BY gender;</span><br><span class="line"></span><br><span class="line">-- 查询所有年龄小于等于35岁员工的姓名和年龄，并对查询结果按年龄升序排序，如果年龄相同按入职时间降序排序。</span><br><span class="line">SELECT name,age FROM emp WHERE age &lt;= 35 ORDER BY age ASC ,entrydate DESC ;</span><br><span class="line"></span><br><span class="line">-- 查询性别为男，且年龄在20-40 岁(含)以内的前5个员工信息，对查询的结果按年龄升序排序，年龄相同按入职时间升序排序。</span><br><span class="line">SELECT  * FROM emp WHERE gender = &#x27;男&#x27; AND ( age BETWEEN 20 AND 40 ) ORDER BY age ASC,entrydate ASC LIMIT 5;</span><br></pre></td></tr></table></figure><h4 id="执行顺序"><a href="#执行顺序" class="headerlink" title="执行顺序"></a>执行顺序</h4><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">#验证</span><br><span class="line"><span class="comment">-- 查询年龄大于15的员工姓名、年龄，并根据年龄进行升序排序。</span></span><br><span class="line"><span class="keyword">SELECT</span> e.name ename,e.age eage <span class="keyword">FROM</span> emp e <span class="keyword">WHERE</span> e.age <span class="operator">&gt;</span> <span class="number">15</span>  <span class="keyword">ORDER</span> <span class="keyword">BY</span> eage <span class="keyword">ASC</span>;</span><br><span class="line"><span class="comment">-- 不能写成下面，报错，执行顺序</span></span><br><span class="line"><span class="keyword">SELECT</span> e.name ename,e.age eage <span class="keyword">FROM</span> emp e <span class="keyword">WHERE</span> eage <span class="operator">&gt;</span> <span class="number">15</span>  <span class="keyword">ORDER</span> <span class="keyword">BY</span> eage <span class="keyword">ASC</span>;</span><br></pre></td></tr></table></figure><h3 id="DCL"><a href="#DCL" class="headerlink" title="DCL"></a>DCL</h3><p>DCL英文全称是Data Control Language(数据控制语言)，用来管理数据库用户、控制数据库的访问权限。</p><h4 id="管理用户"><a href="#管理用户" class="headerlink" title="管理用户"></a>管理用户</h4><ol><li><p>查询用户</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">USE mysql;</span><br><span class="line">SELECT * FROM user;</span><br><span class="line">SELECT * FROM mysql.user;-- 等同上面两句</span><br></pre></td></tr></table></figure><p>其中 Host代表当前用户访问的主机, 如果为localhost, 仅代表只能够在当前本机访问，是不可以远程访问的。 User代表的是访问该数据库的用户名。在MySQL中需要通过Host和User来唯一标识一个用户。</p></li><li><p>创建用户</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">CREATE USER &#x27;用户名&#x27;@&#x27;主机名&#x27; IDENTIFIED BY &#x27;密码&#x27;;</span><br></pre></td></tr></table></figure></li><li><p>修改用户密码</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER USER &#x27;用户名&#x27;@&#x27;主机名&#x27; IDENTIFIED WITH mysql_native_password BY &#x27;新密码&#x27; ;</span><br></pre></td></tr></table></figure></li><li><p>删除用户</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">DROP USER &#x27;用户名&#x27;@&#x27;主机名&#x27; ;</span><br></pre></td></tr></table></figure></li><li><p>注意事项:</p><ul><li><p>在MySQL中需要通过 用户名@主机名的方式，来唯一标识一个用户。</p></li><li><p>主机名可以使用 % 通配。</p></li><li><p>这类SQL开发人员操作的比较少，主要是DBA（ Database Administrator 数据库<br>管理员）使用</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">--  创建用户itxie, 只能够在当前主机localhost访问, 密码123456;</span><br><span class="line">CREATE USER &#x27;itxie&#x27;@&#x27;localhost&#x27; IDENTIFIED BY &#x27;123456&#x27;;</span><br><span class="line"></span><br><span class="line">-- 创建用户xie, 可以在任意主机访问该数据库, 密码123456;</span><br><span class="line">CREATE USER &#x27;xie&#x27;@&#x27;%&#x27; IDENTIFIED BY &#x27;123456&#x27;;</span><br><span class="line"></span><br><span class="line">-- 修改用户xie的访问密码为1234;</span><br><span class="line">ALTER USER &#x27;xie&#x27;@&#x27;%&#x27; IDENTIFIED WITH mysql_native_password by &#x27;1234&#x27;;</span><br><span class="line"></span><br><span class="line">-- 删除 itxie@localhost 用户</span><br><span class="line">DROP USER &#x27;itxie&#x27;@&#x27;localhost&#x27;;</span><br></pre></td></tr></table></figure></li></ul></li></ol><h4 id="权限控制"><a href="#权限控制" class="headerlink" title="权限控制"></a>权限控制</h4><p>MySQL中定义了很多种权限，但是常用的就以下几种：</p><div class="table-container"><table><thead><tr><th style="text-align:center">权限</th><th style="text-align:center">说明</th></tr></thead><tbody><tr><td style="text-align:center">ALL, ALL PRIVILEGES</td><td style="text-align:center">所有权限</td></tr><tr><td style="text-align:center">SELECT</td><td style="text-align:center">查询数据</td></tr><tr><td style="text-align:center">INSERT</td><td style="text-align:center">插入数据</td></tr><tr><td style="text-align:center">UPDATE</td><td style="text-align:center">修改数据</td></tr><tr><td style="text-align:center">DELETE</td><td style="text-align:center">删除数据</td></tr><tr><td style="text-align:center">ALTER</td><td style="text-align:center">修改表</td></tr><tr><td style="text-align:center">DROP</td><td style="text-align:center">删除数据库/表/视图</td></tr><tr><td style="text-align:center">CREATE</td><td style="text-align:center">创建数据库/表</td></tr></tbody></table></div><p>官方文档：<a href="https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html">https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html</a></p><ol><li><p>查询权限</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SHOW GRANTS FOR &#x27;用户名&#x27;@&#x27;主机名&#x27; ;</span><br></pre></td></tr></table></figure></li><li><p>授予权限</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">GRANT 权限列表 ON 数据库名.表名 TO &#x27;用户名&#x27;@&#x27;主机名&#x27;;</span><br></pre></td></tr></table></figure></li><li><p>撤销权限</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">REVOKE 权限列表 ON 数据库名.表名 FROM &#x27;用户名&#x27;@&#x27;主机名&#x27;;</span><br></pre></td></tr></table></figure><p>注意事项：</p><ul><li><p>多个权限之间，使用逗号分隔</p></li><li><p>授权时， 数据库名和表名可以使用 * 进行通配，代表所有。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 查询 &#x27;xie&#x27;@&#x27;%&#x27; 用户的权限</span><br><span class="line">SHOW GRANTS FOR &#x27;xie&#x27;@&#x27;%&#x27;;</span><br><span class="line"></span><br><span class="line">-- 授予 &#x27;xie&#x27;@&#x27;%&#x27; 用户itxie数据库所有表的所有操作权限</span><br><span class="line">GRANT ALL ON itxie.* TO &#x27;xie&#x27;@&#x27;%&#x27;;</span><br><span class="line"></span><br><span class="line">-- 撤销 &#x27;xie&#x27;@&#x27;%&#x27; 用户的itxie数据库的所有权限</span><br><span class="line">REVOKE ALL ON itxie.* FROM &#x27;xie&#x27;@&#x27;%&#x27;;</span><br></pre></td></tr></table></figure></li></ul></li></ol><h2 id="4-函数"><a href="#4-函数" class="headerlink" title="4  函数"></a>4  函数</h2><p>函数是指一段可以直接被另一段程序调用的程序或代码。也就意味着，这一段程序或代码在MySQL中已经给我们提供了，我们要做的就是在合适的业务场景调用对应的函数完成对应的业务需求即可。</p><h3 id="字符串函数"><a href="#字符串函数" class="headerlink" title="字符串函数"></a>字符串函数</h3><p>MySQL中内置了很多字符串函数，常用的几个如下：</p><div class="table-container"><table><thead><tr><th style="text-align:center">函数</th><th style="text-align:center">功能</th></tr></thead><tbody><tr><td style="text-align:center">CONCAT(S1,S2,…Sn)</td><td style="text-align:center">字符串拼接，将S1，S2，… Sn拼接成一个字符串</td></tr><tr><td style="text-align:center">LOWER(str)</td><td style="text-align:center">将字符串str全部转为小写</td></tr><tr><td style="text-align:center">UPPER(str)</td><td style="text-align:center">将字符串str全部转为大写</td></tr><tr><td style="text-align:center">LPAD(str,n,pad)</td><td style="text-align:center">左填充，用字符串pad对str的左边进行填充，达到n个字符串长度</td></tr><tr><td style="text-align:center">RPAD(str,n,pad)</td><td style="text-align:center">右填充，用字符串pad对str的右边进行填充，达到n个字符串长度</td></tr><tr><td style="text-align:center">TRIM(str)</td><td style="text-align:center">去掉字符串头部和尾部的空格</td></tr><tr><td style="text-align:center">SUBSTRING(str,start,len)</td><td style="text-align:center">返回从字符串str从start位置起的len个长度的字符串</td></tr></tbody></table></div><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="comment">-- concat : 字符串拼接</span></span><br><span class="line"><span class="keyword">SELECT</span> CONCAT(<span class="string">&#x27;Hello&#x27;</span>,<span class="string">&#x27;MySQL&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- lower : 全部转小写</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">LOWER</span>(<span class="string">&#x27;HellO&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- upper : 全部转大写</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">UPPER</span>(<span class="string">&#x27;hello&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- lpad : 左填充</span></span><br><span class="line"><span class="keyword">SELECT</span> LPAD(<span class="string">&#x27;01&#x27;</span>,<span class="number">5</span>,<span class="string">&#x27;-&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- rpad : 右填充</span></span><br><span class="line"><span class="keyword">SELECT</span> RPAD(<span class="string">&#x27;01&#x27;</span>,<span class="number">5</span>,<span class="string">&#x27;-&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- trim : 去除空格</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">TRIM</span>(<span class="string">&#x27;  HEL  LO  &#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- substring : 截取子字符串</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">SUBSTRING</span>(<span class="string">&#x27;HELLO MYSQL&#x27;</span>,<span class="number">1</span>,<span class="number">5</span>);<span class="comment">-- 索引从1开始</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 由于业务需求变更，企业员工的工号，统一为5位数，目前不足6位数的全部在前面补0。比如： 1号员工的工号应该为000001</span></span><br><span class="line"><span class="keyword">UPDATE</span> EMP <span class="keyword">SET</span> workno <span class="operator">=</span> LPAD(workno,<span class="number">6</span>,<span class="string">&#x27;0&#x27;</span>);</span><br></pre></td></tr></table></figure><h3 id="数值函数"><a href="#数值函数" class="headerlink" title="数值函数"></a>数值函数</h3><div class="table-container"><table><thead><tr><th style="text-align:center">函数</th><th style="text-align:center">功能</th></tr></thead><tbody><tr><td style="text-align:center">CEIL(x)</td><td style="text-align:center">向上取整</td></tr><tr><td style="text-align:center">FLOOR(x)</td><td style="text-align:center">向下取整</td></tr><tr><td style="text-align:center">MOD(x,y)</td><td style="text-align:center">返回x/y的模</td></tr><tr><td style="text-align:center">RAND()</td><td style="text-align:center">返回0~1内的随机数</td></tr><tr><td style="text-align:center">ROUND(x,y)</td><td style="text-align:center">求参数x的四舍五入的值，保留y位小数</td></tr></tbody></table></div><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="comment">-- ceil：向上取整</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">CEIL</span>(<span class="number">1.3</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- floor：向下取整</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">FLOOR</span>(<span class="number">1.9</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- mod：取模</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">MOD</span>(<span class="number">7</span>,<span class="number">4</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- rand：获取随机数</span></span><br><span class="line"><span class="keyword">SELECT</span> RAND();</span><br><span class="line"></span><br><span class="line"><span class="comment">-- round：四舍五入</span></span><br><span class="line"><span class="keyword">SELECT</span> ROUND(<span class="number">2.344</span>,<span class="number">2</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 通过数据库的函数，生成一个六位数的随机验证码。</span></span><br><span class="line"><span class="keyword">SELECT</span> LPAD(ROUND(RAND()<span class="operator">*</span><span class="number">1000000</span>,<span class="number">0</span>),<span class="number">6</span>,<span class="string">&#x27;0&#x27;</span>);<span class="comment">-- 补零是为了解决生成随机数不足六位</span></span><br></pre></td></tr></table></figure><h3 id="日期函数"><a href="#日期函数" class="headerlink" title="日期函数"></a>日期函数</h3><div class="table-container"><table><thead><tr><th style="text-align:center">函数</th><th style="text-align:center">功能</th></tr></thead><tbody><tr><td style="text-align:center">CURDATE()</td><td style="text-align:center">返回当前日期</td></tr><tr><td style="text-align:center">CURTIME()</td><td style="text-align:center">返回当前时间</td></tr><tr><td style="text-align:center">NOW()</td><td style="text-align:center">返回当前日期和时间</td></tr><tr><td style="text-align:center">YEAR(date)</td><td style="text-align:center">获取指定date的年份</td></tr><tr><td style="text-align:center">MONTH(date)</td><td style="text-align:center">获取指定date的月份</td></tr><tr><td style="text-align:center">DAY(date)</td><td style="text-align:center">获取指定date的日期</td></tr><tr><td style="text-align:center">DATE_ADD(date, INTERVAL expr  type)</td><td style="text-align:center">返回一个日期/时间值加上一个时间间隔expr后的时间值</td></tr><tr><td style="text-align:center">DATEDIFF(date1,date2)</td><td style="text-align:center">返回起始时间date1 和 结束时间date2之间的天数</td></tr></tbody></table></div><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="comment">-- curdate：当前日期</span></span><br><span class="line"><span class="keyword">SELECT</span> CURDATE();</span><br><span class="line"></span><br><span class="line"><span class="comment">-- curtime：当前时间</span></span><br><span class="line"><span class="keyword">SELECT</span>  CURTIME();</span><br><span class="line"></span><br><span class="line"><span class="comment">-- now：当前日期和时间</span></span><br><span class="line"><span class="keyword">SELECT</span> NOW();</span><br><span class="line"></span><br><span class="line"><span class="comment">-- YEAR , MONTH , DAY：当前年、月、日</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="keyword">YEAR</span>(NOW());</span><br><span class="line"><span class="keyword">SELECT</span> <span class="keyword">MONTH</span>(NOW());</span><br><span class="line"><span class="keyword">SELECT</span> <span class="keyword">DAY</span>(NOW());</span><br><span class="line"></span><br><span class="line"><span class="comment">-- date_add：增加指定的时间间隔</span></span><br><span class="line"><span class="keyword">SELECT</span> DATE_ADD(NOW(),<span class="type">INTERVAL</span> <span class="number">2</span> <span class="keyword">DAY</span>);</span><br><span class="line"><span class="keyword">SELECT</span> DATE_ADD(NOW(),<span class="type">INTERVAL</span> <span class="number">2</span> <span class="keyword">MONTH</span> );</span><br><span class="line"><span class="keyword">SELECT</span> DATE_ADD(NOW(),<span class="type">INTERVAL</span> <span class="number">2</span> <span class="keyword">YEAR</span> );</span><br><span class="line"></span><br><span class="line"><span class="comment">-- datediff：获取两个日期相差的天数</span></span><br><span class="line"><span class="keyword">SELECT</span> DATEDIFF(<span class="string">&#x27;2023-12-22&#x27;</span>,<span class="string">&#x27;2022-12-22&#x27;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 案例：查询所有员工的入职天数，并根据入职天数倒序排序。</span></span><br><span class="line"><span class="keyword">SELECT</span> name,DATEDIFF(CURDATE(),entrydate) <span class="keyword">AS</span> <span class="string">&#x27;entrydays&#x27;</span> <span class="keyword">FROM</span> emp <span class="keyword">ORDER</span> <span class="keyword">BY</span> entrydays <span class="keyword">DESC</span> ;</span><br></pre></td></tr></table></figure><h3 id="流程函数"><a href="#流程函数" class="headerlink" title="流程函数"></a>流程函数</h3><p>流程函数也是很常用的一类函数，可以在SQL语句中实现条件筛选，从而提高语句的效率。</p><div class="table-container"><table><thead><tr><th style="text-align:center">函数</th><th style="text-align:center">功能</th></tr></thead><tbody><tr><td style="text-align:center">IF(value , t , f)</td><td style="text-align:center">如果value为true，则返回t，否则返回f</td></tr><tr><td style="text-align:center">IFNULL(value1 , value2</td><td style="text-align:center">如果value1不为空，返回value1，否则返回value2</td></tr><tr><td style="text-align:center">CASE WHEN [ val1 ] THEN [res1] …ELSE [ default ] END</td><td style="text-align:center">如果val1为true，返回res1，… 否则返回default默认值</td></tr><tr><td style="text-align:center">CASE [ expr ] WHEN [ val1 ] THEN[res1] … ELSE [ default ] END</td><td style="text-align:center">如果expr的值等于val1，返回res1，… 否则返回default默认值</td></tr></tbody></table></div><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="comment">-- if</span></span><br><span class="line"><span class="keyword">SELECT</span> IF(<span class="literal">TRUE</span>,<span class="string">&#x27;OK&#x27;</span>,<span class="string">&#x27;ERROR&#x27;</span>);</span><br><span class="line"><span class="keyword">SELECT</span> IF(<span class="literal">FALSE</span>,<span class="string">&#x27;OK&#x27;</span>,<span class="string">&#x27;ERROR&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- ifnull</span></span><br><span class="line"><span class="keyword">SELECT</span> IFNULL(<span class="string">&#x27;OK&#x27;</span>,<span class="string">&#x27;DEFAULT&#x27;</span>);</span><br><span class="line"><span class="keyword">SELECT</span> IFNULL(<span class="string">&#x27;&#x27;</span>,<span class="string">&#x27;DEFAULT&#x27;</span>);</span><br><span class="line"><span class="keyword">SELECT</span> IFNULL(<span class="keyword">NULL</span>,<span class="string">&#x27;DEFAULT&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- case when then else end</span></span><br><span class="line"><span class="comment">-- 需求: 查询emp表的员工姓名和工作地址 (北京/上海 ----&gt; 一线城市 , 其他 ----&gt; 二线城市)</span></span><br><span class="line"><span class="keyword">SELECT</span></span><br><span class="line">    name,</span><br><span class="line">    ( <span class="keyword">CASE</span> workaddress <span class="keyword">WHEN</span> <span class="string">&#x27;北京&#x27;</span> <span class="keyword">THEN</span> <span class="string">&#x27;一线城市&#x27;</span> <span class="keyword">WHEN</span> <span class="string">&#x27;上海&#x27;</span> <span class="keyword">THEN</span> <span class="string">&#x27;一线城市&#x27;</span> <span class="keyword">ELSE</span> <span class="string">&#x27;二线城市&#x27;</span> <span class="keyword">END</span> ) <span class="keyword">AS</span> <span class="string">&#x27;工作地址&#x27;</span></span><br><span class="line"><span class="keyword">FROM</span> emp;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> score(</span><br><span class="line">         id <span class="type">int</span> comment <span class="string">&#x27;ID&#x27;</span>,</span><br><span class="line">         name <span class="type">varchar</span>(<span class="number">20</span>) comment <span class="string">&#x27;姓名&#x27;</span>,</span><br><span class="line">         math <span class="type">int</span> comment <span class="string">&#x27;数学&#x27;</span>,</span><br><span class="line">         english <span class="type">int</span> comment <span class="string">&#x27;英语&#x27;</span>,</span><br><span class="line">         chinese <span class="type">int</span> comment <span class="string">&#x27;语文&#x27;</span></span><br><span class="line">) comment <span class="string">&#x27;学员成绩表&#x27;</span>;</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> score(id, name, math, english, chinese) <span class="keyword">VALUES</span> (<span class="number">1</span>, <span class="string">&#x27;Tom&#x27;</span>, <span class="number">67</span>, <span class="number">88</span>, <span class="number">95</span>), (<span class="number">2</span>, <span class="string">&#x27;Rose&#x27;</span> , <span class="number">23</span>, <span class="number">66</span>, <span class="number">90</span>),(<span class="number">3</span>, <span class="string">&#x27;Jack&#x27;</span>, <span class="number">56</span>, <span class="number">98</span>, <span class="number">76</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span></span><br><span class="line">    id,</span><br><span class="line">    name,</span><br><span class="line">    ( <span class="keyword">CASE</span> <span class="keyword">WHEN</span> math <span class="operator">&gt;=</span> <span class="number">85</span> <span class="keyword">THEN</span> <span class="string">&#x27;优秀&#x27;</span> <span class="keyword">WHEN</span> math <span class="operator">&gt;=</span> <span class="number">60</span> <span class="keyword">THEN</span> <span class="string">&#x27;及格&#x27;</span> <span class="keyword">ELSE</span> <span class="string">&#x27;不及格&#x27;</span> <span class="keyword">END</span>) <span class="string">&#x27;数学&#x27;</span>,</span><br><span class="line">    ( <span class="keyword">CASE</span> <span class="keyword">WHEN</span> english <span class="operator">&gt;=</span> <span class="number">85</span> <span class="keyword">THEN</span> <span class="string">&#x27;优秀&#x27;</span> <span class="keyword">WHEN</span> english <span class="operator">&gt;=</span> <span class="number">60</span> <span class="keyword">THEN</span> <span class="string">&#x27;及格&#x27;</span> <span class="keyword">ELSE</span> <span class="string">&#x27;不及格&#x27;</span> <span class="keyword">END</span>) <span class="string">&#x27;英语&#x27;</span>,</span><br><span class="line">    ( <span class="keyword">CASE</span> <span class="keyword">WHEN</span> chinese <span class="operator">&gt;=</span> <span class="number">85</span> <span class="keyword">THEN</span> <span class="string">&#x27;优秀&#x27;</span> <span class="keyword">WHEN</span> chinese <span class="operator">&gt;=</span> <span class="number">60</span> <span class="keyword">THEN</span> <span class="string">&#x27;及格&#x27;</span> <span class="keyword">ELSE</span> <span class="string">&#x27;不及格&#x27;</span> <span class="keyword">END</span>) <span class="string">&#x27;语文&#x27;</span></span><br><span class="line"><span class="keyword">FROM</span> score;</span><br></pre></td></tr></table></figure><h3 id="窗口函数"><a href="#窗口函数" class="headerlink" title="窗口函数"></a>窗口函数</h3><p>窗口函数，也叫OLAP函数（Online Anallytical Processing，联机分析处理），可以对数据库数据进行进行复杂分析。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&lt;窗口函数&gt; over (partition by &lt;用于分组的列名&gt;</span><br><span class="line">                order by &lt;用于排序的列名&gt;)</span><br></pre></td></tr></table></figure><h2 id="5-约束"><a href="#5-约束" class="headerlink" title="5  约束"></a>5  约束</h2><h3 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h3><p>概念：约束是作用于表中字段上的规则，用于限制存储在表中的数据。</p><p>目的：保证数据库中数据的正确、有效性和完整性。</p><p><strong>分类</strong></p><div class="table-container"><table><thead><tr><th style="text-align:center">约束</th><th style="text-align:center">描述</th><th style="text-align:center">关键字</th></tr></thead><tbody><tr><td style="text-align:center">非空约束</td><td style="text-align:center">限制该字段的数据不能为null</td><td style="text-align:center">NOT NULL</td></tr><tr><td style="text-align:center">唯一约束</td><td style="text-align:center">保证该字段的所有数据都是唯一、不重复的</td><td style="text-align:center">UNIQUE</td></tr><tr><td style="text-align:center">主键约束</td><td style="text-align:center">主键是一行数据的唯一标识，要求非空且唯一</td><td style="text-align:center">PRIMARY  KEY</td></tr><tr><td style="text-align:center">默认约束</td><td style="text-align:center">保存数据时，如果未指定该字段的值，则采用默认值</td><td style="text-align:center">DEFAULT</td></tr><tr><td style="text-align:center">检查约束(8.0.16版本之后)</td><td style="text-align:center">保证字段值满足某一个条件</td><td style="text-align:center">CHECK</td></tr><tr><td style="text-align:center">外键约束</td><td style="text-align:center">用来让两张表的数据之间建立连接，保证数据的一致性和完整性</td><td style="text-align:center">FOREIGN  KEY</td></tr></tbody></table></div><p>注意：约束是作用于表中字段上的，可以在创建表/修改表的时候添加约束</p><h3 id="约束演示"><a href="#约束演示" class="headerlink" title="约束演示"></a>约束演示</h3><p>案例需求：</p><div class="table-container"><table><thead><tr><th style="text-align:center">字段名</th><th style="text-align:center">字段含义</th><th style="text-align:center">字段类型</th><th style="text-align:center">约束条件</th><th style="text-align:center">约束关键字</th></tr></thead><tbody><tr><td style="text-align:center">id</td><td style="text-align:center">ID唯一标识</td><td style="text-align:center">int</td><td style="text-align:center">主键并且自动增长</td><td style="text-align:center">PRIMARY KEY ,AUTO_INCREMENT</td></tr><tr><td style="text-align:center">name</td><td style="text-align:center">姓名</td><td style="text-align:center">varchar(10)</td><td style="text-align:center">非空且唯一</td><td style="text-align:center">NOT NULL , UNIQUE</td></tr><tr><td style="text-align:center">age</td><td style="text-align:center">年龄</td><td style="text-align:center">int</td><td style="text-align:center">大于0且小于等于120</td><td style="text-align:center">CHECK</td></tr><tr><td style="text-align:center">status</td><td style="text-align:center">状态</td><td style="text-align:center">char(1)</td><td style="text-align:center">如没有指定值，默认为1</td><td style="text-align:center">DEFAULT</td></tr><tr><td style="text-align:center">gender</td><td style="text-align:center">性别</td><td style="text-align:center">char(1)</td><td style="text-align:center">无</td></tr></tbody></table></div><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> <span class="keyword">user</span>(</span><br><span class="line">    id <span class="type">INT</span> <span class="keyword">PRIMARY</span> KEY AUTO_INCREMENT COMMENT <span class="string">&#x27;主键&#x27;</span>,</span><br><span class="line">    name <span class="type">VARCHAR</span>(<span class="number">10</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">UNIQUE</span> COMMENT <span class="string">&#x27;姓名&#x27;</span>,</span><br><span class="line">    age <span class="type">INT</span> <span class="keyword">CHECK</span> ( age <span class="operator">&gt;</span> <span class="number">0</span> <span class="operator">&amp;&amp;</span> age <span class="operator">&lt;=</span> <span class="number">120</span> ) COMMENT <span class="string">&#x27;年龄&#x27;</span>,</span><br><span class="line">    status <span class="type">CHAR</span>(<span class="number">1</span>) <span class="keyword">DEFAULT</span>  <span class="string">&#x27;1&#x27;</span> COMMENT  <span class="string">&#x27;状态&#x27;</span>,</span><br><span class="line">    gender <span class="type">CHAR</span>(<span class="number">1</span>) COMMENT <span class="string">&#x27;性别&#x27;</span></span><br><span class="line">) COMMENT <span class="string">&#x27;状态表&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="keyword">user</span>(NAME, AGE, STATUS, GENDER) <span class="keyword">VALUES</span> (<span class="string">&#x27;Tom1&#x27;</span>,<span class="string">&#x27;19&#x27;</span>,<span class="string">&#x27;0&#x27;</span>,<span class="string">&#x27;男&#x27;</span>),(<span class="string">&#x27;Tom2&#x27;</span>,<span class="string">&#x27;9&#x27;</span>,<span class="string">&#x27;0&#x27;</span>,<span class="string">&#x27;男&#x27;</span>);<span class="comment">-- 检查id</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="keyword">user</span>(NAME, AGE, STATUS, GENDER) <span class="keyword">VALUES</span> (<span class="string">&#x27;Tom3&#x27;</span>,<span class="string">&#x27;-1&#x27;</span>,<span class="string">&#x27;0&#x27;</span>,<span class="string">&#x27;男&#x27;</span>);<span class="comment">-- 检查check关键字</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="keyword">user</span>(NAME, AGE, STATUS, GENDER) <span class="keyword">VALUES</span> (<span class="string">&#x27;Tom3&#x27;</span>,<span class="string">&#x27;121&#x27;</span>,<span class="string">&#x27;0&#x27;</span>,<span class="string">&#x27;男&#x27;</span>);</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="keyword">user</span>(NAME, AGE, STATUS, GENDER) <span class="keyword">VALUES</span> (<span class="keyword">null</span>,<span class="string">&#x27;121&#x27;</span>,<span class="string">&#x27;1&#x27;</span>,<span class="string">&#x27;男&#x27;</span>);<span class="comment">-- 检查非空</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="keyword">user</span>(NAME, AGE, STATUS, GENDER) <span class="keyword">VALUES</span> ( <span class="string">&#x27;Tom1&#x27;</span>,<span class="string">&#x27;121&#x27;</span>,<span class="string">&#x27;1&#x27;</span>,<span class="string">&#x27;男&#x27;</span> );<span class="comment">-- 检查唯一</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="keyword">user</span>(NAME, AGE, STATUS, GENDER) <span class="keyword">VALUES</span> ( <span class="string">&#x27;Tom3&#x27;</span>,<span class="string">&#x27;120&#x27;</span>,<span class="keyword">null</span>,<span class="string">&#x27;男&#x27;</span> );</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="keyword">user</span>(NAME, AGE,  GENDER) <span class="keyword">VALUES</span> ( <span class="string">&#x27;Tom4&#x27;</span>,<span class="string">&#x27;120&#x27;</span>,<span class="string">&#x27;男&#x27;</span> );</span><br></pre></td></tr></table></figure><h3 id="外键约束"><a href="#外键约束" class="headerlink" title="外键约束"></a>外键约束</h3><ol><li><p>介绍</p><p>外键：用来让两张表的数据之间建立连接，从而保证数据的一致性和完整性。</p><p>准备数据：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">create table dept(</span><br><span class="line">      id int auto_increment comment &#x27;ID&#x27; primary key,</span><br><span class="line">      name varchar(50) not null comment &#x27;部门名称&#x27;</span><br><span class="line">)comment &#x27;部门表&#x27;;</span><br><span class="line"></span><br><span class="line">INSERT INTO dept (id, name) VALUES (1, &#x27;研发部&#x27;), (2, &#x27;市场部&#x27;),(3, &#x27;财务部&#x27;), (4,&#x27;销售部&#x27;), (5, &#x27;总经办&#x27;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">create table emp(</span><br><span class="line">        id int auto_increment comment &#x27;ID&#x27; primary key,</span><br><span class="line">        name varchar(50) not null comment &#x27;姓名&#x27;,</span><br><span class="line">        age int comment &#x27;年龄&#x27;,</span><br><span class="line">        job varchar(20) comment &#x27;职位&#x27;,</span><br><span class="line">        salary int comment &#x27;薪资&#x27;,</span><br><span class="line">        entrydate date comment &#x27;入职时间&#x27;,</span><br><span class="line">        managerid int comment &#x27;直属领导ID&#x27;,</span><br><span class="line">        dept_id int comment &#x27;部门ID&#x27;</span><br><span class="line">)comment &#x27;员工表&#x27;;</span><br><span class="line"></span><br><span class="line">INSERT INTO emp (id, name, age, job,salary, entrydate, managerid, dept_id)</span><br><span class="line">VALUES (1, &#x27;金庸&#x27;, 66, &#x27;总裁&#x27;,20000, &#x27;2000-01-01&#x27;, null,5),</span><br><span class="line">       (2, &#x27;张无忌&#x27;, 20,&#x27;项目经理&#x27;,12500, &#x27;2005-12-05&#x27;, 1,1),</span><br><span class="line">       (3, &#x27;杨逍&#x27;, 33, &#x27;开发&#x27;, 8400,&#x27;2000-11-03&#x27;, 2,1),</span><br><span class="line">       (4, &#x27;韦一笑&#x27;, 48, &#x27;开发&#x27;,11000, &#x27;2002-02-05&#x27;, 2,1),</span><br><span class="line">       (5, &#x27;常遇春&#x27;, 43, &#x27;开发&#x27;,10500, &#x27;2004-09-07&#x27;, 3,1),</span><br><span class="line">       (6, &#x27;小昭&#x27;, 19, &#x27;程序员鼓励师&#x27;,6600, &#x27;2004-10-12&#x27;, 2,1);</span><br></pre></td></tr></table></figure></li><li><p>语法</p><ul><li><p>添加外键</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">CREATE TABLE 表名(</span><br><span class="line">    字段名 数据类型,</span><br><span class="line">    ...</span><br><span class="line">    [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名)</span><br><span class="line">);</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名) ;</span><br></pre></td></tr></table></figure><p>案例：为emp表的dept_id字段添加外键约束,关联dept表的主键id。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept (id);</span><br></pre></td></tr></table></figure><p>添加了外键约束之后，我们再到dept表(父表)删除id为1的记录，然后看一下会发生什么现象。 此时将会报错，不能删除或更新父表记录，因为存在外键约束。</p></li><li><p>删除外键</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;</span><br></pre></td></tr></table></figure><p>案列：删除emp表的外键fk_emp_dept_id。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept_id;</span><br></pre></td></tr></table></figure></li><li><p>删除/更新行为</p><p>添加了外键之后，再删除父表数据时产生的约束行为，我们就称为删除/更新行为。具体的删除/更新行为有以下几种:</p><p>|     行为     |                             说明                             |<br>| :—————: | :—————————————————————————————: |<br>|  NO  ACTION  | 当在父表中删除/更新对应记录时，首先检查该记录是否有对应外键，<BR/>如果有则不允许删除/更新。 (与 RESTRICT 一致) 默认行为 |<br>|   RESTRICT   | 当在父表中删除/更新对应记录时，首先检查该记录是否有对应外键，<BR/>如果有则不允许删除/更新。 (与 NO ACTION 一致) 默认行为 |<br>|   CASCADE    | 当在父表中删除/更新对应记录时，首先检查该记录是否有对应外键，<BR/>如果有，则也删除/更新外键在子表中的记录 |<br>|   SET NULL   | 当在父表中删除对应记录时，首先检查该记录是否有对应外键，<BR/>如果有则设置子表中该外键值为null（这就要求该外键允许取null） |<br>| SET  DEFAULT | 父表有变更时，子表将外键列设置成一个默认的值 (Innodb不支持)  |</p><p>具体语法为：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名 (主表字段名) ON UPDATE CASCADE ON DELETE CASCADE;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY  (dept_id) REFERENCES dept (id) ON UPDATE CASCADE ON DELETE CASCADE ; -- CASCADE级联更新</span><br><span class="line"></span><br><span class="line">ALTER TABLE emp ADD CONSTRAINT fk_emp_dept_id FOREIGN KEY  (dept_id) REFERENCES dept (id) ON UPDATE SET NULL ON DELETE SET NULL ; -- SET NULL级联更新为null</span><br></pre></td></tr></table></figure></li></ul></li></ol><h2 id="6-多表查询"><a href="#6-多表查询" class="headerlink" title="6  多表查询"></a>6  多表查询</h2><h3 id="多表关系"><a href="#多表关系" class="headerlink" title="多表关系"></a>多表关系</h3><p>项目开发中，在进行数据库表结构设计时，会根据业务需求及业务模块之间的关系，分析并设计表结构，由于业务之间相互关联，所以各个表结构之间也存在着各种联系，基本上分为三种：一对多(多对一)、多对多、一对一</p><ol><li><p>一对多</p><ul><li><p>案例: 部门 与 员工的关系</p></li><li><p>关系: 一个部门对应多个员工，一个员工对应一个部门</p></li><li><p>实现: 在多的一方建立外键，指向一的一方的主键</p></li></ul></li></ol><ol><li><p>多对多</p><ul><li>案例: 学生 与 课程的关系</li></ul></li></ol><ul><li>关系: 一个学生可以选修多门课程，一门课程也可以供多个学生选择</li></ul><ul><li><p>实现: 建立第三张中间表，中间表至少包含两个外键，分别关联两方主键</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">create table student(</span><br><span class="line">        id int auto_increment primary key comment &#x27;主键ID&#x27;,</span><br><span class="line">        name varchar(10) comment &#x27;姓名&#x27;,</span><br><span class="line">        no varchar(10) comment &#x27;学号&#x27;</span><br><span class="line">) comment &#x27;学生表&#x27;;</span><br><span class="line"></span><br><span class="line">insert into student values (null, &#x27;黛绮丝&#x27;, &#x27;2000100101&#x27;),(null, &#x27;谢逊&#x27;,&#x27;2000100102&#x27;),(null, &#x27;殷天正&#x27;, &#x27;2000100103&#x27;),(null, &#x27;韦一笑&#x27;, &#x27;2000100104&#x27;);</span><br><span class="line"></span><br><span class="line">create table course(</span><br><span class="line">        id int auto_increment primary key comment &#x27;主键ID&#x27;,</span><br><span class="line">        name varchar(10) comment &#x27;课程名称&#x27;</span><br><span class="line">) comment &#x27;课程表&#x27;;</span><br><span class="line"></span><br><span class="line">insert into course values (null, &#x27;Java&#x27;), (null, &#x27;PHP&#x27;), (null , &#x27;MySQL&#x27;) ,(null, &#x27;Hadoop&#x27;);</span><br><span class="line"></span><br><span class="line">create table student_course(</span><br><span class="line">        id int auto_increment comment &#x27;主键&#x27; primary key,</span><br><span class="line">        studentid int not null comment &#x27;学生ID&#x27;,</span><br><span class="line">        courseid int not null comment &#x27;课程ID&#x27;,</span><br><span class="line">        constraint fk_courseid foreign key (courseid) references course (id),</span><br><span class="line">        constraint fk_studentid foreign key (studentid) references student (id)</span><br><span class="line">)comment &#x27;学生课程中间表&#x27;;</span><br><span class="line"></span><br><span class="line">insert into student_course values (null,1,1),(null,1,2),(null,1,3),(null,2,2),(null,2,3),(null,3,4);</span><br></pre></td></tr></table></figure></li></ul><ol><li><p>一对一</p><ul><li><p>案例: 用户 与 用户详情的关系</p></li><li><p>关系: 一对一关系，多用于单表拆分，将一张表的基础字段放在一张表中，其他详情字段放在另一张表中，以提升操作效率、</p></li><li><p>实现: 在任意一方加入外键，关联另外一方的主键，并且设置外键为唯一的(UNIQUE)</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">create table tb_user(</span><br><span class="line">       id int auto_increment primary key comment &#x27;主键ID&#x27;,</span><br><span class="line">       name varchar(10) comment &#x27;姓名&#x27;,</span><br><span class="line">       age int comment &#x27;年龄&#x27;,</span><br><span class="line">       gender char(1) comment &#x27;1: 男 , 2: 女&#x27;,</span><br><span class="line">       phone char(11) comment &#x27;手机号&#x27;</span><br><span class="line">) comment &#x27;用户基本信息表&#x27;;</span><br><span class="line"></span><br><span class="line">create table tb_user_edu(</span><br><span class="line">         id int auto_increment primary key comment &#x27;主键ID&#x27;,</span><br><span class="line">         degree varchar(20) comment &#x27;学历&#x27;,</span><br><span class="line">         major varchar(50) comment &#x27;专业&#x27;,</span><br><span class="line">         primaryschool varchar(50) comment &#x27;小学&#x27;,</span><br><span class="line">         middleschool varchar(50) comment &#x27;中学&#x27;,</span><br><span class="line">         university varchar(50) comment &#x27;大学&#x27;,</span><br><span class="line">         userid int unique comment &#x27;用户ID&#x27;,</span><br><span class="line">         constraint fk_userid foreign key (userid) references tb_user(id)</span><br><span class="line">) comment &#x27;用户教育信息表&#x27;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">insert into</span><br><span class="line">    tb_user(id, name, age, gender, phone)</span><br><span class="line">values</span><br><span class="line">      (null,&#x27;黄渤&#x27;,45,&#x27;1&#x27;,&#x27;18800001111&#x27;),</span><br><span class="line">      (null,&#x27;冰冰&#x27;,35,&#x27;2&#x27;,&#x27;18800002222&#x27;),</span><br><span class="line">      (null,&#x27;码云&#x27;,55,&#x27;1&#x27;,&#x27;18800008888&#x27;),</span><br><span class="line">      (null,&#x27;李彦宏&#x27;,50,&#x27;1&#x27;,&#x27;18800009999&#x27;);</span><br><span class="line"></span><br><span class="line">insert into</span><br><span class="line">    tb_user_edu (id, degree, major, primaryschool, middleschool,university, userid)</span><br><span class="line">values</span><br><span class="line">      (null,&#x27;本科&#x27;,&#x27;舞蹈&#x27;,&#x27;静安区第一小学&#x27;,&#x27;静安区第一中学&#x27;,&#x27;北京舞蹈学院&#x27;,1),</span><br><span class="line">      (null,&#x27;硕士&#x27;,&#x27;表演&#x27;,&#x27;朝阳区第一小学&#x27;,&#x27;朝阳区第一中学&#x27;,&#x27;北京电影学院&#x27;,2),</span><br><span class="line">      (null,&#x27;本科&#x27;,&#x27;英语&#x27;,&#x27;杭州市第一小学&#x27;,&#x27;杭州市第一中学&#x27;,&#x27;杭州师范大学&#x27;,3),</span><br><span class="line">      (null,&#x27;本科&#x27;,&#x27;应用数学&#x27;,&#x27;阳泉第一小学&#x27;,&#x27;阳泉区第一中学&#x27;,&#x27;清华大学&#x27;,4);</span><br></pre></td></tr></table></figure></li></ul></li></ol><h3 id="多表查询概述"><a href="#多表查询概述" class="headerlink" title="多表查询概述"></a>多表查询概述</h3><ol><li><p>数据准备</p><ul><li><p>删除之前 emp, dept表的测试数据</p></li><li><p>执行如下脚本，创建emp表与dept表并插入测试数据</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 创建dept表，并插入数据</span><br><span class="line">create table dept(</span><br><span class="line">     id int auto_increment comment &#x27;ID&#x27; primary key,</span><br><span class="line">     name varchar(50) not null comment &#x27;部门名称&#x27;</span><br><span class="line">)comment &#x27;部门表&#x27;;</span><br><span class="line"></span><br><span class="line">INSERT INTO dept (id, name) VALUES (1, &#x27;研发部&#x27;), (2, &#x27;市场部&#x27;),(3, &#x27;财务部&#x27;), (4,&#x27;销售部&#x27;), (5, &#x27;总经办&#x27;), (6, &#x27;人事部&#x27;);</span><br><span class="line"></span><br><span class="line">-- 创建emp表，并插入数据</span><br><span class="line">create table emp(</span><br><span class="line">        id int auto_increment comment &#x27;ID&#x27; primary key,</span><br><span class="line">        name varchar(50) not null comment &#x27;姓名&#x27;,</span><br><span class="line">        age int comment &#x27;年龄&#x27;,</span><br><span class="line">        job varchar(20) comment &#x27;职位&#x27;,</span><br><span class="line">        salary int comment &#x27;薪资&#x27;,</span><br><span class="line">        entrydate date comment &#x27;入职时间&#x27;,</span><br><span class="line">        managerid int comment &#x27;直属领导ID&#x27;,</span><br><span class="line">        dept_id int comment &#x27;部门ID&#x27;</span><br><span class="line">)comment &#x27;员工表&#x27;;</span><br><span class="line"></span><br><span class="line">-- 添加外键</span><br><span class="line">alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);</span><br><span class="line">INSERT INTO</span><br><span class="line">    emp (id, name, age, job,salary, entrydate, managerid, dept_id)</span><br><span class="line">VALUES</span><br><span class="line">       (1, &#x27;金庸&#x27;, 66, &#x27;总裁&#x27;,20000, &#x27;2000-01-01&#x27;, null,5),</span><br><span class="line">       (2, &#x27;张无忌&#x27;, 20, &#x27;项目经理&#x27;,12500, &#x27;2005-12-05&#x27;, 1,1),</span><br><span class="line">       (3, &#x27;杨逍&#x27;, 33, &#x27;开发&#x27;, 8400,&#x27;2000-11-03&#x27;, 2,1),</span><br><span class="line">       (4, &#x27;韦一笑&#x27;, 48, &#x27;开发&#x27;,11000, &#x27;2002-02-05&#x27;, 2,1),</span><br><span class="line">       (5, &#x27;常遇春&#x27;, 43, &#x27;开发&#x27;,10500, &#x27;2004-09-07&#x27;, 3,1),</span><br><span class="line">       (6, &#x27;小昭&#x27;, 19, &#x27;程序员鼓励师&#x27;,6600, &#x27;2004-10-12&#x27;, 2,1),</span><br><span class="line">       (7, &#x27;灭绝&#x27;, 60, &#x27;财务总监&#x27;,8500, &#x27;2002-09-12&#x27;, 1,3),</span><br><span class="line">       (8, &#x27;周芷若&#x27;, 19, &#x27;会计&#x27;,48000, &#x27;2006-06-02&#x27;, 7,3),</span><br><span class="line">       (9, &#x27;丁敏君&#x27;, 23, &#x27;出纳&#x27;,5250, &#x27;2009-05-13&#x27;, 7,3),</span><br><span class="line">       (10, &#x27;赵敏&#x27;, 20, &#x27;市场部总监&#x27;,12500, &#x27;2004-10-12&#x27;, 1,2),</span><br><span class="line">       (11, &#x27;鹿杖客&#x27;, 56, &#x27;职员&#x27;,3750, &#x27;2006-10-03&#x27;, 10,2),</span><br><span class="line">       (12, &#x27;鹤笔翁&#x27;, 19, &#x27;职员&#x27;,3750, &#x27;2007-05-09&#x27;, 10,2),</span><br><span class="line">       (13, &#x27;方东白&#x27;, 19, &#x27;职员&#x27;,5500, &#x27;2009-02-12&#x27;, 10,2),</span><br><span class="line">       (14, &#x27;张三丰&#x27;, 88, &#x27;销售总监&#x27;,14000, &#x27;2004-10-12&#x27;, 1,4),</span><br><span class="line">       (15, &#x27;俞莲舟&#x27;, 38, &#x27;销售&#x27;,4600, &#x27;2004-10-12&#x27;, 14,4),</span><br><span class="line">       (16, &#x27;宋远桥&#x27;, 40, &#x27;销售&#x27;,4600, &#x27;2004-10-12&#x27;, 14,4),</span><br><span class="line">       (17, &#x27;陈友谅&#x27;, 42, null,2000, &#x27;2011-10-12&#x27;, 1,null);</span><br></pre></td></tr></table></figure><p>多表查询就是指从多张表中查询数据。要执行多表查询，就只需要使用逗号分隔多张表即可，如： select * from emp , dept; 此时，我们看到查询结果中包含了大量的结果集，总共102条记录，而这其实就是员工表emp所有的记录(17) 与 部门表dept所有记录(6) 的所有组合情况，这种现象称之为笛卡尔积。接下来，就来简单介绍下笛卡尔积。</p><p>笛卡尔积: 笛卡尔乘积是指在数学中，两个集合A集合 和 B集合的所有组合情况。</p><p>而在多表查询中，我们是需要消除无效的笛卡尔积的，只保留两张表关联部分的数据。我们可以给多表查询加上连接查询的条件即可去除无效的笛卡尔积：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT * FROM emp,dept WHERE dept_id = dept.id;</span><br></pre></td></tr></table></figure></li></ul></li><li><p>分类</p><ul><li><p>连接查询</p><ul><li>内连接：相当于查询A、B交集部分数据</li><li>外连接：<br>左外连接：查询左表所有数据，以及两张表交集部分数据<br>右外连接：查询右表所有数据，以及两张表交集部分数据</li><li>自连接：当前表与自身的连接查询，自连接必须使用表别名</li></ul></li><li><p>子查询</p></li></ul></li></ol><h3 id="内连接"><a href="#内连接" class="headerlink" title="内连接"></a>内连接</h3><p>内连接查询的是两张表交集部分的数据。内连接的语法分为两种: 隐式内连接、显式内连接。</p><ol><li><p>隐式内连接</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表1 , 表2 WHERE 条件 ... ;</span><br></pre></td></tr></table></figure></li><li><p>显式内连接</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件 ... ;</span><br></pre></td></tr></table></figure><p>案例：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- A.查询每一个员工的姓名 , 及关联的部门的名称 (隐式内连接实现)</span><br><span class="line">-- 表结构: emp , dept</span><br><span class="line">-- 连接条件: emp.dept_id = dept.id</span><br><span class="line">SELECT emp.name,dept.name FROM emp ,dept WHERE emp.dept_id = dept.id;</span><br><span class="line">SELECT e.name,d.name FROM emp e,dept d WHERE e.dept_id = d.id;</span><br><span class="line"></span><br><span class="line">-- B. 查询每一个员工的姓名 , 及关联的部门的名称 (显式内连接实现) --- INNER JOIN ...ON ..</span><br><span class="line">-- 表结构: emp , dept</span><br><span class="line">-- 连接条件: emp.dept_id = dept.id</span><br><span class="line">SELECT emp.name,dept.name FROM emp INNER JOIN dept ON emp.dept_id = dept.id;</span><br><span class="line">SELECT e.name,d.name FROM emp e JOIN dept d ON e.dept_id = d.id;</span><br></pre></td></tr></table></figure><p>注：表的别名: <code>tablea as 别名1 , tableb as 别名2 ;</code> 或 <code>tablea 别名1 , tableb 别名2 ;</code>，一旦为表起了别名，就不能再使用表名来指定对应的字段了，此时只能够使用别名来指定字段。</p></li></ol><h3 id="外连接"><a href="#外连接" class="headerlink" title="外连接"></a>外连接</h3><p>外连接分为两种，分别是：左外连接 和 右外连接。具体的语法结构为：</p><ol><li><p>左外连接</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ... ;</span><br></pre></td></tr></table></figure><p>左外连接相当于查询表1(左表)的所有数据，当然也包含表1和表2交集部分的数据。</p></li><li><p>右外连接</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ... ;</span><br></pre></td></tr></table></figure><p>右外连接相当于查询表2(右表)的所有数据，当然也包含表1和表2交集部分的数据。</p><p>案例：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- A.查询每一个员工的姓名 , 及关联的部门的名称 (隐式内连接实现)</span><br><span class="line">-- 表结构: emp , dept</span><br><span class="line">-- 连接条件: emp.dept_id = dept.id</span><br><span class="line">SELECT emp.name,dept.name FROM emp ,dept WHERE emp.dept_id = dept.id;</span><br><span class="line">SELECT e.name,d.name FROM emp e,dept d WHERE e.dept_id = d.id;</span><br><span class="line"></span><br><span class="line">-- B. 查询每一个员工的姓名 , 及关联的部门的名称 (显式内连接实现) --- INNER JOIN ...ON ..</span><br><span class="line">-- 表结构: emp , dept</span><br><span class="line">-- 连接条件: emp.dept_id = dept.id</span><br><span class="line">SELECT emp.name,dept.name FROM emp INNER JOIN dept ON emp.dept_id = dept.id;</span><br><span class="line">SELECT e.name,d.name FROM emp e JOIN dept d ON e.dept_id = d.id;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">-- 查询emp表的所有数据, 和对应的部门信息</span><br><span class="line">-- 由于需求中提到，要查询emp的所有数据，所以是不能内连接查询的，需要考虑使用外连接查询。</span><br><span class="line">-- 表结构: emp, dept</span><br><span class="line">-- 连接条件: emp.dept_id = dept.id</span><br><span class="line">SELECT emp.* ,dept.name FROM emp LEFT OUTER JOIN dept ON emp.dept_id = dept.id;</span><br><span class="line">SELECT e.* ,d.name FROM emp e LEFT OUTER JOIN dept d ON e.dept_id = d.id;</span><br><span class="line"></span><br><span class="line">-- 查询dept表的所有数据, 和对应的员工信息(右外连接)</span><br><span class="line">-- 由于需求中提到，要查询dept表的所有数据，所以是不能内连接查询的，需要考虑使用外连接查询。</span><br><span class="line">-- 表结构: emp, dept</span><br><span class="line">-- 连接条件: emp.dept_id = dept.id</span><br><span class="line">SELECT d.*,e.* FROM emp e RIGHT OUTER JOIN dept d on e.dept_id = d.id;</span><br><span class="line">SELECT d.*,e.* FROM dept d LEFT OUTER JOIN emp e on e.dept_id = d.id;-- 左外连接取代右外连接</span><br></pre></td></tr></table></figure><p>注意事项：左外连接和右外连接是可以相互替换的，只需要调整在连接查询时SQL中，表结构的先后顺序就可以了。而我们在日常开发使用时，更偏向于左外连接。</p></li></ol><h3 id="自连接"><a href="#自连接" class="headerlink" title="自连接"></a>自连接</h3><ol><li><p>自连接查询</p><p>自连接查询，顾名思义，就是自己连接自己，也就是把一张表连接查询多次。查询语法：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ... ;</span><br></pre></td></tr></table></figure><p>而对于自连接查询，可以是内连接查询，也可以是外连接查询。</p><p>案例：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 查询员工 及其 所属领导的名字</span><br><span class="line">SELECT e1.name ,e2.name FROM emp e1 INNER JOIN emp e2 ON e1.managerid = e2.id;</span><br><span class="line"></span><br><span class="line">-- 查询所有员工 emp 及其领导的名字 emp , 如果员工没有领导, 也需要查询出来表结构: emp a , emp b</span><br><span class="line">SELECT a.name &#x27;员工&#x27;, b.name &#x27;领导&#x27; FROM emp a LEFT JOIN emp b ON a.managerid = b.id;</span><br></pre></td></tr></table></figure><p>注意事项：在自连接查询中，必须要为表起别名，要不然我们不清楚所指定的条件、返回的字段，到底是哪一张表的字段。</p></li><li><p>联合查询</p><p>对于union查询，就是把多次查询的结果合并起来，形成一个新的查询结果集。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT 字段列表 FROM 表A ...</span><br><span class="line">UNION [ ALL ]</span><br><span class="line">SELECT 字段列表 FROM 表B ....;</span><br></pre></td></tr></table></figure><p>对于联合查询的多张表的列数必须保持一致，字段类型也需要保持一致。union all 会将全部的数据直接合并在一起，union 会对合并之后的数据去重。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 将薪资低于 5000 的员工 , 和 年龄大于 50 岁的员工全部查询出来</span><br><span class="line">-- 当前对于这个需求，我们可以直接使用多条件查询，使用逻辑运算符 or 连接即可。 那这里呢，我们也可以通过union/union all来联合查询</span><br><span class="line">SELECT * FROM emp WHERE salary &lt; 5000 OR age &gt; 50; -- 去重</span><br><span class="line">-- 有重复</span><br><span class="line">SELECT * FROM emp WHERE salary &lt; 5000</span><br><span class="line">UNION ALL</span><br><span class="line">SELECT * FROM emp WHERE age &gt; 50;</span><br><span class="line">-- 去重(去掉ALL)</span><br><span class="line">SELECT * FROM emp WHERE salary &lt; 5000</span><br><span class="line">UNION</span><br><span class="line">SELECT * FROM emp WHERE age &gt; 50;</span><br></pre></td></tr></table></figure><p>注意：如果多条查询语句查询出来的结果，字段数量不一致，在进行union/union all联合查询时，将会报错。</p></li></ol><h3 id="子查询"><a href="#子查询" class="headerlink" title="子查询"></a>子查询</h3><ol><li><p>概念</p><p>SQL语句中嵌套SELECT语句，称为嵌套查询，又称子查询。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 );</span><br></pre></td></tr></table></figure><p>子查询外部的语句可以是INSERT / UPDATE / DELETE / SELECT 的任何一个。</p></li><li><p>分类</p><p>根据子查询结果不同，分为：</p><ul><li>标量子查询（子查询结果为单个值）</li><li>列子查询(子查询结果为一列)</li><li>行子查询(子查询结果为一行)</li><li>表子查询(子查询结果为多行多列)</li></ul><p>根据子查询位置，分为：</p><ul><li>WHERE之后</li></ul><ul><li><p>FROM之后</p></li><li><p>SELECT之后</p></li></ul></li><li><p>标量子查询</p><p>子查询返回的结果是单个值（数字、字符串、日期等），最简单的形式，这种子查询称为标量子查询。<br>常用的操作符：=  &lt;&gt;  &gt;  &gt;=  &lt;  &lt;=。</p><p>案例:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 查询 &quot;销售部&quot; 的所有员工信息</span><br><span class="line">-- 完成这个需求时，我们可以将需求分解为两步：</span><br><span class="line">-- 1)查询 &quot;销售部&quot; 部门ID</span><br><span class="line">SELECT id FROM dept WHERE name = &#x27;销售部&#x27;;</span><br><span class="line"></span><br><span class="line">-- 2)根据 &quot;销售部&quot; 部门ID, 查询员工信息</span><br><span class="line">SELECT  id, name, age, job, salary, entrydate, managerid, dept_id  FROM emp WHERE dept_id = (SELECT id FROM dept WHERE name = &#x27;销售部&#x27;);</span><br><span class="line"></span><br><span class="line">-- 查询在 &quot;方东白&quot; 入职之后的员工信息</span><br><span class="line">-- 完成这个需求时，我们可以将需求分解为两步：</span><br><span class="line">-- 1)查询方东白的入职日期</span><br><span class="line">SELECT entrydate FROM emp WHERE name = &#x27;方东白&#x27;;</span><br><span class="line"></span><br><span class="line">-- 2)查询指定入职日期之后入职的员工信息</span><br><span class="line">SELECT</span><br><span class="line">    id, name, age, job, salary, entrydate, managerid, dept_id</span><br><span class="line">FROM</span><br><span class="line">    emp</span><br><span class="line">WHERE</span><br><span class="line">    entrydate &gt; ( SELECT entrydate FROM emp WHERE name = &#x27;方东白&#x27; );</span><br></pre></td></tr></table></figure></li><li><p>列子查询</p><p>子查询返回的结果是一列（可以是多行），这种子查询称为列子查询。常用的操作符：IN 、NOT IN 、 ANY 、SOME 、 ALL</p><p>| 操作符 |                  描述                  |<br>| :——: | :——————————————————: |<br>|   IN   |      在指定的集合范围之内，多选一      |<br>| NOT IN |         不在指定的集合范围之内         |<br>|  ANY   |  子查询返回列表中，有任意一个满足即可  |<br>|  SOME  | 与ANY等同，使用SOME的地方都可以使用ANY |<br>|  ALL   |    子查询返回列表的所有值都必须满足    |</p><p>案例：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 查询 &quot;销售部&quot; 和 &quot;市场部&quot; 的所有员工信息</span><br><span class="line">-- 1)查询 &quot;销售部&quot; 和 &quot;市场部&quot; 的部门ID</span><br><span class="line">SELECT id FROM dept WHERE name = &#x27;销售部&#x27; OR name = &#x27;市场部&#x27;;</span><br><span class="line"></span><br><span class="line">-- 2)根据部门ID, 查询员工信息</span><br><span class="line">SELECT * FROM emp WHERE dept_id in (SELECT id FROM dept WHERE name = &#x27;销售部&#x27; OR name = &#x27;市场部&#x27;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">-- 查询比 财务部 所有人工资都高的员工信息</span><br><span class="line">-- 1)查询所有 财务部 人员工资</span><br><span class="line">SELECT salary FROM emp WHERE dept_id = ( SELECT id FROM dept WHERE name = &#x27;财务部&#x27; );</span><br><span class="line"></span><br><span class="line">-- 2)比 财务部 所有人工资都高的员工信息</span><br><span class="line">SELECT * FROM emp WHERE salary &gt; ALL(SELECT salary FROM emp WHERE dept_id = ( SELECT id FROM dept WHERE name = &#x27;财务部&#x27; ));</span><br><span class="line"></span><br><span class="line">-- 查询比研发部其中任意一人工资高的员工信息</span><br><span class="line">-- 1)查询研发部所有人工资</span><br><span class="line">SELECT salary FROM emp WHERE dept_id = ( SELECT id FROM dept WHERE name = &#x27;研发部&#x27; );</span><br><span class="line"></span><br><span class="line">-- 2)比研发部其中任意一人工资高的员工信息(SOME/ANY)</span><br><span class="line">SELECT * FROM emp WHERE salary &gt; ANY ( SELECT salary FROM emp WHERE dept_id = ( SELECT id FROM dept WHERE name = &#x27;研发部&#x27; ) );</span><br></pre></td></tr></table></figure></li><li><p>行子查询</p><p>子查询返回的结果是一行（可以是多列），这种子查询称为行子查询。常用的操作符：= 、&lt;&gt; 、IN 、NOT IN</p><p>案例：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 查询与 &quot;张无忌&quot; 的薪资及直属领导相同的员工信息</span><br><span class="line">-- 1)查询 &quot;张无忌&quot; 的薪资及直属领导</span><br><span class="line">SELECT salary,managerid FROM emp WHERE name = &#x27;张无忌&#x27;;</span><br><span class="line"></span><br><span class="line">-- 2)查询与 &quot;张无忌&quot; 的薪资及直属领导相同的员工信息</span><br><span class="line">SELECT * FROM emp WHERE ( salary,managerid ) = ( SELECT salary,managerid FROM emp WHERE name = &#x27;张无忌&#x27; );</span><br></pre></td></tr></table></figure></li><li><p>表子查询</p><p>子查询返回的结果是多行多列，这种子查询称为表子查询。常用的操作符：IN</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">-- 查询与 &quot;鹿杖客&quot; , &quot;宋远桥&quot; 的职位和薪资相同的员工信息</span><br><span class="line">-- 1)查询 &quot;鹿杖客&quot; , &quot;宋远桥&quot; 的职位和薪资</span><br><span class="line">SELECT job,salary FROM emp WHERE name = &#x27;鹿杖客&#x27; OR name = &#x27;宋远桥&#x27;;</span><br><span class="line"></span><br><span class="line">-- 2)查询与 &quot;鹿杖客&quot; , &quot;宋远桥&quot; 的职位和薪资相同的员工信息</span><br><span class="line">SELECT * FROM emp WHERE ( job,salary ) IN ( SELECT job,salary FROM emp WHERE name = &#x27;鹿杖客&#x27; OR name = &#x27;宋远桥&#x27; );</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">-- 查询入职日期是 &quot;2006-01-01&quot; 之后的员工信息 , 及其部门信息</span><br><span class="line">-- 1)入职日期是 &quot;2006-01-01&quot; 之后的员工信息</span><br><span class="line">SELECT * FROM emp WHERE entrydate &gt; &#x27;2006-01-01&#x27;;</span><br><span class="line"></span><br><span class="line">-- 2)查询这部分员工, 对应的部门信息;</span><br><span class="line">SELECT e.*,d.* FROM ( SELECT * FROM emp WHERE entrydate &gt; &#x27;2006-01-01&#x27; ) e LEFT JOIN dept d ON e.dept_id = d.id;</span><br></pre></td></tr></table></figure></li></ol><h3 id="多表查询案例"><a href="#多表查询案例" class="headerlink" title="多表查询案例"></a>多表查询案例</h3><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="comment">-- 多表查询案例</span></span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> salgrade(</span><br><span class="line">      grade <span class="type">int</span>,</span><br><span class="line">      losal <span class="type">int</span>,</span><br><span class="line">      hisal <span class="type">int</span></span><br><span class="line">) comment <span class="string">&#x27;薪资等级表&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> salgrade <span class="keyword">values</span> (<span class="number">1</span>,<span class="number">0</span>,<span class="number">3000</span>);</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> salgrade <span class="keyword">values</span> (<span class="number">2</span>,<span class="number">3001</span>,<span class="number">5000</span>);</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> salgrade <span class="keyword">values</span> (<span class="number">3</span>,<span class="number">5001</span>,<span class="number">8000</span>);</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> salgrade <span class="keyword">values</span> (<span class="number">4</span>,<span class="number">8001</span>,<span class="number">10000</span>);</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> salgrade <span class="keyword">values</span> (<span class="number">5</span>,<span class="number">10001</span>,<span class="number">15000</span>);</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> salgrade <span class="keyword">values</span> (<span class="number">6</span>,<span class="number">15001</span>,<span class="number">20000</span>);</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> salgrade <span class="keyword">values</span> (<span class="number">7</span>,<span class="number">20001</span>,<span class="number">25000</span>);</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> salgrade <span class="keyword">values</span> (<span class="number">8</span>,<span class="number">25001</span>,<span class="number">30000</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 案例练习</span></span><br><span class="line"><span class="comment">-- 查询员工的姓名、年龄、职位、部门信息 （隐式内连接）</span></span><br><span class="line"><span class="keyword">SELECT</span> e.name,e.age,e.job,d.name <span class="keyword">FROM</span> emp e,dept d <span class="keyword">WHERE</span> e.dept_id <span class="operator">=</span> d.id;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询年龄小于30岁的员工的姓名、年龄、职位、部门信息（显式内连接）</span></span><br><span class="line"><span class="keyword">SELECT</span> e.name,e.age,e.job,d.name <span class="keyword">FROM</span> emp e <span class="keyword">INNER</span> <span class="keyword">JOIN</span> dept d <span class="keyword">ON</span> e.dept_id <span class="operator">=</span> d.id <span class="keyword">WHERE</span> e.age <span class="operator">&lt;</span> <span class="number">30</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询拥有员工的部门ID、部门名称</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="keyword">DISTINCT</span> d.id ,d.name <span class="keyword">FROM</span> emp e,dept d <span class="keyword">WHERE</span> e.dept_id <span class="operator">=</span> d.id;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询所有年龄大于40岁的员工, 及其归属的部门名称; 如果员工没有分配部门, 也需要展示出来(外连接)</span></span><br><span class="line"><span class="keyword">SELECT</span>  e.<span class="operator">*</span> ,d.name <span class="keyword">FROM</span> emp e <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> dept d <span class="keyword">on</span> e.dept_id <span class="operator">=</span> d.id <span class="keyword">WHERE</span> age <span class="operator">&gt;</span> <span class="number">40</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询所有员工的工资等级</span></span><br><span class="line"><span class="keyword">SELECT</span> e.<span class="operator">*</span>, s.grade,s.losal,s.hisal <span class="keyword">FROM</span> emp e, salgrade s <span class="keyword">WHERE</span>  e.salary <span class="keyword">BETWEEN</span> s.losal <span class="keyword">AND</span> s.hisal;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询 &quot;研发部&quot; 所有员工的信息及 工资等级</span></span><br><span class="line"><span class="keyword">SELECT</span> e.<span class="operator">*</span>,s.grade <span class="keyword">FROM</span> emp e,dept d,salgrade s <span class="keyword">WHERE</span> e.dept_id <span class="operator">=</span> d.id <span class="keyword">AND</span> d.name <span class="operator">=</span> <span class="string">&#x27;研发部&#x27;</span> <span class="keyword">AND</span> ( e.salary <span class="keyword">BETWEEN</span> s.losal <span class="keyword">AND</span> s.hisal );</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询 &quot;研发部&quot; 员工的平均工资</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">AVG</span>(e.salary) <span class="keyword">FROM</span> emp e,dept d <span class="keyword">WHERE</span> e.dept_id <span class="operator">=</span> d.id <span class="keyword">AND</span> d.name <span class="operator">=</span> <span class="string">&#x27;研发部&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询工资比 &quot;灭绝&quot; 高的员工信息。</span></span><br><span class="line"><span class="comment">-- 1)查询 &quot;灭绝&quot; 的薪资</span></span><br><span class="line"><span class="keyword">SELECT</span> salary <span class="keyword">FROM</span> emp e <span class="keyword">WHERE</span> name <span class="operator">=</span> <span class="string">&#x27;灭绝&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 2)查询比她工资高的员工数据</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> salary <span class="operator">&gt;</span> ( <span class="keyword">SELECT</span> salary <span class="keyword">FROM</span> emp e <span class="keyword">WHERE</span> name <span class="operator">=</span> <span class="string">&#x27;灭绝&#x27;</span> );</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询比平均薪资高的员工信息</span></span><br><span class="line"><span class="comment">-- 1)查询员工的平均薪资</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">AVG</span>(salary) <span class="keyword">FROM</span> emp;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 2)查询比平均薪资高的员工信息</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> salary <span class="operator">&gt;</span> ( <span class="keyword">SELECT</span> <span class="built_in">AVG</span>(salary) <span class="keyword">FROM</span> emp );</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询低于本部门平均工资的员工信息</span></span><br><span class="line"><span class="comment">-- 1)查询指定部门平均薪资</span></span><br><span class="line"><span class="keyword">SELECT</span>  <span class="built_in">AVG</span>(salary) <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> dept_id <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line"><span class="keyword">SELECT</span>  <span class="built_in">AVG</span>(salary) <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> dept_id <span class="operator">=</span> <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 2)查询低于本部门平均工资的员工信息</span></span><br><span class="line"><span class="keyword">SELECT</span> e2.<span class="operator">*</span>, ( <span class="keyword">SELECT</span>  <span class="built_in">AVG</span>(e1.salary) <span class="keyword">FROM</span> emp e1 <span class="keyword">WHERE</span> e1.dept_id <span class="operator">=</span> e2.dept_id ) <span class="string">&#x27;平均薪资&#x27;</span></span><br><span class="line"><span class="keyword">FROM</span> emp e2 <span class="keyword">WHERE</span> e2.salary <span class="operator">&lt;</span> ( <span class="keyword">SELECT</span>  <span class="built_in">AVG</span>(e1.salary) <span class="keyword">FROM</span> emp e1 <span class="keyword">WHERE</span> e1.dept_id <span class="operator">=</span> e2.dept_id );</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询所有的部门信息, 并统计部门的员工人数</span></span><br><span class="line"><span class="keyword">SELECT</span> d.id, d.name, ( <span class="keyword">SELECT</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">FROM</span> emp e <span class="keyword">WHERE</span> e.dept_id <span class="operator">=</span> d.id ) <span class="string">&#x27;人数&#x27;</span> <span class="keyword">FROM</span> dept d;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查询所有学生的选课情况, 展示出学生名称, 学号, 课程名称</span></span><br><span class="line"><span class="keyword">SELECT</span> s.name,s.no,c.name <span class="keyword">FROM</span> student s,student_course sc,course c <span class="keyword">WHERE</span> s.id <span class="operator">=</span> sc.studentid <span class="keyword">AND</span> c.id <span class="operator">=</span> sc.courseid;</span><br></pre></td></tr></table></figure><h2 id="7-事务"><a href="#7-事务" class="headerlink" title="7  事务"></a>7  事务</h2><h3 id="事务简介"><a href="#事务简介" class="headerlink" title="事务简介"></a>事务简介</h3><p>事务是一组操作的集合，它是一个不可分割的工作单位，事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求，即这些操作要么同时成功，要么同时失败。就比如: 张三给李四转账1000块钱，张三银行账户的钱减少1000，而李四银行账户的钱要增加1000。这一组操作就必须在一个事务的范围内，要么都成功，要么都失败。</p><p>注意： 默认MySQL的事务是自动提交的，也就是说，当执行完一条DML语句时，MySQL会立即隐式的提交事务。</p><h3 id="事务操作"><a href="#事务操作" class="headerlink" title="事务操作"></a>事务操作</h3><p>数据准备：</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">drop</span> <span class="keyword">table</span> if <span class="keyword">exists</span> account;</span><br><span class="line"></span><br><span class="line">       <span class="keyword">create</span> <span class="keyword">table</span> account(</span><br><span class="line">       id <span class="type">int</span> <span class="keyword">primary</span> key AUTO_INCREMENT comment <span class="string">&#x27;ID&#x27;</span>,</span><br><span class="line">       name <span class="type">varchar</span>(<span class="number">10</span>) comment <span class="string">&#x27;姓名&#x27;</span>,</span><br><span class="line">       money <span class="keyword">double</span>(<span class="number">10</span>,<span class="number">2</span>) comment <span class="string">&#x27;余额&#x27;</span></span><br><span class="line">) comment <span class="string">&#x27;账户表&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> account(name, money) <span class="keyword">VALUES</span> (<span class="string">&#x27;张三&#x27;</span>,<span class="number">2000</span>), (<span class="string">&#x27;李四&#x27;</span>,<span class="number">2000</span>);</span><br></pre></td></tr></table></figure><ol><li><p>控制事务一</p><ul><li><p>查看/设置事务提交方式</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT @@AUTOCOMMIT;</span><br><span class="line"></span><br><span class="line">SET @@AUTOCOMMIT = 0;-- 设置手动提交</span><br></pre></td></tr></table></figure></li><li><p>提交事务</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">COMMIT ;</span><br></pre></td></tr></table></figure></li><li><p>回滚事务</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ROLLBACK ;</span><br></pre></td></tr></table></figure><p>注意：上述的这种方式，我们是修改了事务的自动提交行为, 把默认的自动提交修改为了手动提交, 此时我们执行的DML语句都不会提交, 需要手动的执行commit进行提交。</p></li></ul></li><li><p>控制事务二</p><ul><li><p>开启事务</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">START TRANSACTION ;</span><br><span class="line">BEGIN ;-- 与上面相同</span><br></pre></td></tr></table></figure></li><li><p>提交事务</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">COMMIT ;</span><br></pre></td></tr></table></figure></li><li><p>回滚事务</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ROLLBACK ;</span><br></pre></td></tr></table></figure></li></ul></li></ol><h3 id="事务四大特性"><a href="#事务四大特性" class="headerlink" title="事务四大特性"></a>事务四大特性</h3><ul><li>原子性（Atomicity）：事务是不可分割的最小操作单元，要么全部成功，要么全部失败。</li></ul><ul><li>一致性（Consistency）：事务完成时，必须使所有的数据都保持一致状态。</li><li>隔离性（Isolation）：数据库系统提供的隔离机制，保证事务在不受外部并发操作影响的独立环境下运行。</li><li>持久性（Durability）：事务一旦提交或回滚，它对数据库中的数据的改变就是永久的。<br>上述就是事务的四大特性，简称ACID</li></ul><h3 id="事务并发问题"><a href="#事务并发问题" class="headerlink" title="事务并发问题"></a>事务并发问题</h3><ul><li><p>脏读：一个事务读到另外一个事务还没有提交的数据（读到了另一个事务没有commit的数据）。</p></li><li><p>可重复读：一个事务先后读取同一条记录，但两次读取的数据不同，称之为不可重复读（先后查询到另一个事务commit前后的数据不一致）。</p></li><li><p>幻读：一个事务按照条件查询数据时，没有对应的数据行，但是在插入数据时，又发现这行数据已经存在，好像出现了 “幻影”。（另一事务插入数据commit了，而这个事务没有查询到数据，但是插入数据发现又在，commit后才能查到）</p></li></ul><h3 id="事务隔离级别"><a href="#事务隔离级别" class="headerlink" title="事务隔离级别"></a>事务隔离级别</h3><p>为了解决并发事务所引发的问题，在数据库中引入了事务隔离级别。主要有以下几种：</p><div class="table-container"><table><thead><tr><th style="text-align:center">隔离级别</th><th style="text-align:center">脏读</th><th style="text-align:center">不可重复读</th><th style="text-align:center">幻读</th></tr></thead><tbody><tr><td style="text-align:center">Read uncommitted</td><td style="text-align:center">√</td><td style="text-align:center">√</td><td style="text-align:center">√</td></tr><tr><td style="text-align:center">Read committed(Oracle默认)</td><td style="text-align:center">×</td><td style="text-align:center">√</td><td style="text-align:center">√</td></tr><tr><td style="text-align:center">Repeatable Read(MySQL默认)</td><td style="text-align:center">×</td><td style="text-align:center">×</td><td style="text-align:center">√</td></tr><tr><td style="text-align:center">Serializable</td><td style="text-align:center">×</td><td style="text-align:center">×</td><td style="text-align:center">×</td></tr></tbody></table></div><ol><li><p>查看事务隔离级别</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SELECT @@TRANSACTION_ISOLATION;</span><br></pre></td></tr></table></figure></li><li><p>设置事务隔离级别</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL &#123; READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE &#125;</span><br></pre></td></tr></table></figure><p>注意：事务隔离级别越高，数据越安全，但是性能越低。</p></li></ol><h2 id="8-存储引擎"><a href="#8-存储引擎" class="headerlink" title="8  存储引擎"></a>8  存储引擎</h2><h3 id="MySQL体系架构"><a href="#MySQL体系架构" class="headerlink" title="MySQL体系架构"></a>MySQL体系架构</h3><p>1）连接层</p><p>最上层是一些客户端和链接服务，包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念，为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。</p><p>2）服务层</p><p>第二层架构主要完成大多数的核心服务功能，如SQL接口，并完成缓存的查询，SQL的分析和优化，部分内置函数的执行。所有跨存储引擎的功能也在这一层实现，如 过程、函数等。在该层，服务器会解析查询并创建相应的内部解析树，并对其完成相应的优化如确定表的查询的顺序，是否利用索引等，最后生成相应的执行操作。如果是select语句，服务器还会查询内部的缓存，如果缓存空间足够大，这样在解决大量读操作的环境中能够很好的提升系统的性能。</p><p>3）引擎层</p><p>存储引擎层， 存储引擎真正的负责了MySQL中数据的存储和提取，服务器通过API和存储引擎进行通信。不同的存储引擎具有不同的功能，这样我们可以根据自己的需要，来选取合适的存储引擎。数据库中的索引是在存储引擎层实现的。</p><p>4）存储层</p><p>数据存储层， 主要是将数据(如: redolog、undolog、数据、索引、二进制日志、错误日志、查询日志、慢查询日志等)存储在文件系统之上，并完成与存储引擎的交互。</p><p>和其他数据库相比，MySQL有点与众不同，它的架构可以在多种不同场景中应用并发挥良好作用。主要体现在存储引擎上，插件式的存储引擎架构，将查询处理和其他的系统任务以及数据的存储提取分离。这种架构可以根据业务的需求和实际需要选择合适的存储引擎。</p><h3 id="存储引擎介绍"><a href="#存储引擎介绍" class="headerlink" title="存储引擎介绍"></a>存储引擎介绍</h3><p>存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式 。存储引擎是基于表的，而不是基于库的，所以存储引擎也可被称为表类型。我们可以在创建表的时候，来指定选择的存储引擎，如果没有指定将自动选择默认的存储引擎。</p><ol><li><p>建表时指定存储引擎</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">CREATE TABLE 表名(</span><br><span class="line">字段1 字段1类型 [ COMMENT 字段1注释 ] ,</span><br><span class="line">......</span><br><span class="line">字段n 字段n类型 [COMMENT 字段n注释 ]</span><br><span class="line">) ENGINE = INNODB [ COMMENT 表注释 ] ;</span><br></pre></td></tr></table></figure></li><li><p>查询当前数据库支持的存储引擎</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">SHOW ENGINES;</span><br></pre></td></tr></table></figure></li></ol><h3 id="存储引擎特点"><a href="#存储引擎特点" class="headerlink" title="存储引擎特点"></a>存储引擎特点</h3><ol><li><p>InnoDB</p><p>InnoDB是一种兼顾高可靠性和高性能的通用存储引擎，在 MySQL 5.5 之后，InnoDB是默认的MySQL 存储引擎。</p><p>特点：</p><ul><li><p>DML操作遵循ACID模型，支持<strong>事务</strong>；</p></li><li><p><strong>行级锁</strong>，提高并发访问性能；</p></li><li><p>支持<strong>外键</strong>FOREIGN KEY约束，保证数据的完整性和正确性；</p></li></ul><p>文件：</p><p>xxx.ibd：xxx代表的是表名，innoDB引擎的每张表都会对应这样一个表空间文件，存储该表的表结构（frm-早期的 、sdi-新版的）、数据和索引。</p><p>参数：innodb_file_per_table</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">show variables like &#x27;innodb_file_per_table&#x27;;</span><br></pre></td></tr></table></figure><p>如果该参数开启，代表对于InnoDB引擎的表，每一张表都对应一个ibd文件。 我们直接打开MySQL的数据存放目录：<code>D:\ProgramData\MySQL\MySQL Server 8.0\Data</code> ， 这个目录下有很多文件夹，不同的文件夹代表不同的数据库，我们直接打开itxie01文件夹。可以看到里面有很多的ibd文件，每一个ibd文件就对应一张表，比如：我们有一张表 account，就有这样的一个account.ibd文件，而在这个ibd文件中不仅存放表结构、数据，还会存放该表对应的索引信息。 而该文件是基于二进制存储的，不能直接基于记事本打开，我们可以使用mysql提供的一个指令 ibd2sdi ，通过该指令就可以从ibd文件中提取sdi信息，而sdi数据字典信息中就包含该表的表结构。（使用命令行打开）</p><p>逻辑存储结构：</p><ul><li><p>表空间 : InnoDB存储引擎逻辑结构的最高层，ibd文件其实就是表空间文件，在表空间中可以包含多个Segment段。</p></li><li><p>段 : 表空间是由各个段组成的， 常见的段有数据段、索引段、回滚段等。InnoDB中对于段的管理，都是引擎自身完成，不需要人为对其控制，一个段中包含多个区。</p></li><li><p>区 : 区是表空间的单元结构，每个区的大小为1M。 默认情况下， InnoDB存储引擎页大小为16K， 即一个区中一共有64个连续的页。</p></li><li><p>页 : 页是组成区的最小单元，页也是InnoDB 存储引擎磁盘管理的最小单元，每个页的大小默认为 16KB。为了保证页的连续性，InnoDB 存储引擎每次从磁盘申请 4-5 个区。</p></li><li><p>行 : InnoDB 存储引擎是面向行的，也就是说数据是按行进行存放的，在每一行中除了定义表时所指定的字段以外，还包含两个隐藏字段。</p></li></ul></li></ol><ol><li><p>MyISAM</p><p>MyISAM是MySQL早期的默认存储引擎。</p><p>特点：</p><ul><li><p>不支持事务，不支持外键</p></li><li><p>支持表锁，不支持行锁</p></li><li><p>访问速度快</p></li></ul><p>文件：</p><ul><li><p>xx.sdi：存储表结构信息</p></li><li><p>xxx.MYD: 存储数据</p></li><li><p>xxx.MYI: 存储索引</p></li></ul></li></ol><ol><li><p>Memory</p><p>Memory引擎的表数据时存储在内存中的，由于受到硬件问题、或断电问题的影响，只能将这些表作为临时表或缓存使用。</p><p>特点：</p><ul><li><p>内存存放</p></li><li><p>hash索引（默认）</p></li></ul><p>文件：xxx.sdi：存储表结构信息</p></li><li><p>区别及特点</p><p>| 特点         | InnoDB            | MyISAM | Memory |<br>| —————— | ————————- | ——— | ——— |<br>| 存储限制     | 64TB              | 有     | 有     |<br>| 事务安全     | 支持              | -      | -      |<br>| 锁机制       | 行锁              | 表锁   | 表锁   |<br>| B+Tree索引   | 支持              | 支持   | 支持   |<br>| hash索引     | -                 | -      | 支持   |<br>| 全文索引     | 支持(5.6版本之后) | 支持   | -      |<br>| 空间使用     | 高                | 低     | N/A    |<br>| 内存使用     | 高                | 低     | 中等   |<br>| 批量插入速度 | 低                | 高     | 高     |<br>| 支持外键     | 支持              | -      | -      |</p><p>面试题：<br> InnoDB引擎与MyISAM引擎的区别 ?<br>①. InnoDB引擎, 支持事务, 而MyISAM不支持。<br>②. InnoDB引擎, 支持行锁和表锁, 而MyISAM仅支持表锁, 不支持行锁。<br>③. InnoDB引擎, 支持外键, 而MyISAM是不支持的。</p><p>主要是上述三点区别，当然也可以从索引结构、存储限制等方面，更加深入的回答，具体参考如下官方文档：</p><p><a href="https://dev.mysql.com/doc/refman/8.0/en/innodb-introduction.html">https://dev.mysql.com/doc/refman/8.0/en/innodb-introduction.html</a></p><p><a href="https://dev.mysql.com/doc/refman/8.0/en/myisam-storage-engine.html">https://dev.mysql.com/doc/refman/8.0/en/myisam-storage-engine.html</a></p></li></ol><h3 id="存储引擎选择"><a href="#存储引擎选择" class="headerlink" title="存储引擎选择"></a>存储引擎选择</h3><p>在选择存储引擎时，应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统，还可以根据<br>实际情况选择多种存储引擎进行组合。</p><ul><li>InnoDB: 是Mysql的默认存储引擎，支持事务、外键。如果应用对事务的完整性有比较高的要求，在并发条件下要求数据的一致性，数据操作除了插入和查询之外，还包含很多的更新、删除操作，那么InnoDB存储引擎是比较合适的选择。</li><li>MyISAM ： 如果应用是以读操作和插入操作为主，只有很少的更新和删除操作，并且对事务的完整性、并发性要求不是很高，那么选择这个存储引擎是非常合适的。</li><li>MEMORY：将所有数据保存在内存中，访问速度快，通常用于临时表及缓存。MEMORY的缺陷就是对表的大小有限制，太大的表无法缓存在内存中，而且无法保障数据的安全性。</li></ul><h2 id="9-索引"><a href="#9-索引" class="headerlink" title="9  索引"></a>9  索引</h2><p>索引（index）是帮助MySQL高效获取数据的数据结构(有序)。在数据之外，数据库系统还维护着满足特定查找算法的数据结构，这些数据结构以某种方式引用（指向）数据， 这样就可以在这些数据结构上实现高级查找算法，这种数据结构就是索引。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;MySQL数据库&quot;&gt;&lt;a href=&quot;#MySQL数据库&quot; class=&quot;headerlink&quot; title=&quot;MySQL数据库&quot;&gt;&lt;/a&gt;MySQL数据库&lt;/h1&gt;&lt;h2 id=&quot;1-数据库相关概念&quot;&gt;&lt;a href=&quot;#1-数据库相关概念&quot; class=&quot;he</summary>
      
    
    
    
    <category term="数据库" scheme="https://www.miraclerice.top/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    
    <category term="MySQL" scheme="https://www.miraclerice.top/tags/MySQL/"/>
    
  </entry>
  
  <entry>
    <title>python基础</title>
    <link href="https://www.miraclerice.top/posts/81b2f4bf/"/>
    <id>https://www.miraclerice.top/posts/81b2f4bf/</id>
    <published>2023-11-16T02:40:22.000Z</published>
    <updated>2023-11-18T12:52:30.748Z</updated>
    
    <content type="html"><![CDATA[<h1 id="python"><a href="#python" class="headerlink" title="python"></a>python</h1><ul><li>在ubantu下使用./xxx.py运行py</li><li><a href="https://docs.python.org/zh-cn/3.9/library/index.html">python官方中文文档</a></li></ul><h2 id="一、py基础知识点"><a href="#一、py基础知识点" class="headerlink" title="一、py基础知识点"></a>一、py基础知识点</h2><h3 id="1-在py文件前面加上"><a href="#1-在py文件前面加上" class="headerlink" title="1.在py文件前面加上"></a>1.在py文件前面加上</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment">#!/user/bin/env python</span></span><br></pre></td></tr></table></figure><h3 id="2-python2执行py出现ASCII码问题"><a href="#2-python2执行py出现ASCII码问题" class="headerlink" title="2.python2执行py出现ASCII码问题"></a>2.python2执行py出现ASCII码问题</h3><p>在文件开头加</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># encoding=utf-8</span></span><br></pre></td></tr></table></figure><p>或者</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># coding=utf-8</span></span><br></pre></td></tr></table></figure><p>或者(官方推荐)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># _*_coding:utf-8_*_</span></span><br></pre></td></tr></table></figure><h3 id="3-py关键字"><a href="#3-py关键字" class="headerlink" title="3.py关键字"></a>3.py关键字</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> keyword</span><br><span class="line"><span class="built_in">print</span>(keyword.kwlist)</span><br></pre></td></tr></table></figure><h3 id="4-常用数据类型"><a href="#4-常用数据类型" class="headerlink" title="4.常用数据类型"></a>4.常用数据类型</h3><ul><li>查看类型</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 输出&lt;class &#x27;bool&#x27;&gt;</span></span><br><span class="line"><span class="built_in">type</span>(<span class="string">&#x27;需要查看的类型变量或字符串或数字等等&#x27;</span>)</span><br></pre></td></tr></table></figure><h4 id="4-1-Numbers-数值类型"><a href="#4-1-Numbers-数值类型" class="headerlink" title="4.1 Numbers(数值类型)"></a>4.1 Numbers(数值类型)</h4><ul><li><p>int</p><p>1）二进制：0b+二进制数（注意是数字0不是字母o）</p><p>2）八进制：0/0o+八进制数</p><p>3）十进制：十进制数</p><p>4）十六进制：0x+十六进制数</p></li><li><p>long(python2的类型，python3可以通过int自动调整)</p></li><li><p>float</p><p>1）由整数和小数组成，如155.66</p><p>2）也可以使用科学计数法1.5566e2</p></li><li><p>complex(复数)</p><p>1）a+bj</p><p>2）a,b均为浮点数，complex(a, b)</p></li></ul><h4 id="4-2-bool-布尔类型"><a href="#4-2-bool-布尔类型" class="headerlink" title="4.2 bool(布尔类型)"></a>4.2 bool(布尔类型)</h4><ul><li>True</li><li>False</li><li>可以当做int类型参加数学运算，使用issubclass(bool, int)判断bool是否是int子类</li></ul><h4 id="4-3-string-字符串str"><a href="#4-3-string-字符串str" class="headerlink" title="4.3 string(字符串str)"></a>4.3 string(字符串str)</h4><p>1）非原始字符串（\加上\或者字母表示转义，仅仅\表示续行符）</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">‘string’</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">“string”</span><br></pre></td></tr></table></figure> <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&quot;&quot;&quot;string&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure> <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;string&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>  2）原始字符串（转义字符不生效）</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">r‘string’</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">r“string”</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">r&quot;&quot;&quot;string&quot;&quot;&quot;</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">r&#x27;&#x27;&#x27;string&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>  3）字符串打印与多行关系</p>  <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 多行打印(也可以作为多行注释)</span></span><br><span class="line">str1 = <span class="string">&#x27;&#x27;&#x27;string1</span></span><br><span class="line"><span class="string">string2</span></span><br><span class="line"><span class="string">string3</span></span><br><span class="line"><span class="string">.</span></span><br><span class="line"><span class="string">.</span></span><br><span class="line"><span class="string">.</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="comment"># 把换行的连接起来一</span></span><br><span class="line">str2 = <span class="string">&#x27;string1&#x27;</span>\</span><br><span class="line"><span class="string">&#x27;string2&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 把换行的连接起来二</span></span><br><span class="line">str2 = (<span class="string">&#x27;string1&#x27;</span></span><br><span class="line"><span class="string">&#x27;string2&#x27;</span>)</span><br></pre></td></tr></table></figure><p>  4）字符串拼接</p>  <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 方式一：直接+拼接</span></span><br><span class="line">result = <span class="string">&quot;aaa&quot;</span> + <span class="string">&quot;bbb&quot;</span></span><br><span class="line"><span class="comment"># 方式二： 直接放在一起</span></span><br><span class="line">result = <span class="string">&quot;aaa&quot;</span><span class="string">&quot;bbb&quot;</span></span><br><span class="line"><span class="comment"># 方式三： ”xxx%sxxx&quot; % (a, b)，利用格式化符</span></span><br><span class="line">result = <span class="string">&quot;%s%s&quot;</span> % (<span class="string">&quot;aaa&quot;</span>, <span class="string">&quot;bbb&quot;</span>)</span><br><span class="line"><span class="comment"># 方式四： 字符串乘法 string * int</span></span><br><span class="line">result = string * <span class="number">100</span></span><br><span class="line"><span class="built_in">print</span>(result)</span><br></pre></td></tr></table></figure><p>  5）字符串切片</p><p>概念：获取一个字符串的某个片段</p>  <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 获取一个字符 下标法获取 注意不能越界,i是字符串下标</span></span><br><span class="line"><span class="comment"># i可以为负，反向遍历获取值</span></span><br><span class="line">string[i]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取一片字符串，包头不包尾[x1, x2)</span></span><br><span class="line">string[x1:x2]</span><br><span class="line"></span><br><span class="line">string[起始值:结束值:步长]</span><br><span class="line"><span class="comment"># 获取所有(取默认值起始值0:结束值len(string):步长1)</span></span><br><span class="line">string[::]</span><br><span class="line"><span class="comment"># 相当于</span></span><br><span class="line">string[<span class="number">0</span>:<span class="built_in">len</span>(string):<span class="number">1</span>]</span><br><span class="line"><span class="comment"># 反向获取整个字符串</span></span><br><span class="line">string[::-<span class="number">1</span>]</span><br><span class="line"><span class="comment"># 相当于</span></span><br><span class="line">string[-<span class="number">1</span>:-(<span class="built_in">len</span>(string)+<span class="number">1</span>):-<span class="number">1</span>]</span><br></pre></td></tr></table></figure><p>  注：步长大于0，从左到右，小于0，从右到左，不能从头部跳到尾部，从尾部跳到头部，即起始值与结束值要与方向保持一致</p><p>  6）字符串方法</p>  <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 字符串查找的方法</span></span><br><span class="line"><span class="comment"># 获取字符串长度</span></span><br><span class="line"><span class="built_in">len</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找方法</span></span><br><span class="line"><span class="comment"># 对象.find(目标片段, 起始值, 结束值) 找到返回指定索引并立即停止遍历，找不到返回-1</span></span><br><span class="line"><span class="built_in">print</span>(string.find(<span class="string">&#x27;string1&#x27;</span>, <span class="number">0</span>, <span class="built_in">len</span>(string)))</span><br><span class="line"><span class="comment"># rfind()与find()只是方向相反，但是起始值与结束值还是同向</span></span><br><span class="line"><span class="built_in">print</span>(string.rfind(<span class="string">&#x27;string1&#x27;</span>, <span class="number">0</span>, <span class="built_in">len</span>(string))))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用对象.index(string1),找不到不会返回-1，而是直接抛异常</span></span><br><span class="line">sring.index(string1)</span><br><span class="line">sring.rindex(string1)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用对象.count(string1)统计出现次数</span></span><br><span class="line">string.count(string1)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 字符串转换的方法</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">替换字符串</span></span><br><span class="line"><span class="string">replace(old, new[, count])</span></span><br><span class="line"><span class="string">old 需要替换的原字符串</span></span><br><span class="line"><span class="string">new 新字符串</span></span><br><span class="line"><span class="string">count 替换个数，不写默认全部</span></span><br><span class="line"><span class="string">返回值: 返回替换后的新字符串</span></span><br><span class="line"><span class="string">注意:原来的字符串不会改变</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.replace(str1, str2, count))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">字符串第一个词首字母的大写</span></span><br><span class="line"><span class="string">capitalize()</span></span><br><span class="line"><span class="string">返回值: 返回修改后的新字符串</span></span><br><span class="line"><span class="string">注意:原来的字符串不会改变</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.capitalize())</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">字符串每个单词首字母大写(只要不是字母，其他字符隔开都认为是一个单词)</span></span><br><span class="line"><span class="string">title()</span></span><br><span class="line"><span class="string">返回值: 返回修改后的新字符串</span></span><br><span class="line"><span class="string">注意:原来的字符串不会改变</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.title())</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">字符串每个字符小写</span></span><br><span class="line"><span class="string">lower()</span></span><br><span class="line"><span class="string">返回值: 返回修改后的新字符串</span></span><br><span class="line"><span class="string">注意:原来的字符串不会改变</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.lower())</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">字符串每个字符大写</span></span><br><span class="line"><span class="string">upper()</span></span><br><span class="line"><span class="string">返回值: 返回修改后的新字符串</span></span><br><span class="line"><span class="string">注意:原来的字符串不会改变</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.upper())</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 字符串填充压缩</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">根据指定的一个字符fillchar，将原有字符串填充到指定长度width</span></span><br><span class="line"><span class="string">ljust(width, fillchar)</span></span><br><span class="line"><span class="string">返回值: 返回填充后的字符串</span></span><br><span class="line"><span class="string">注意: 原有字符串不会改变，只有原字符串长度 &lt; 指定结果长度时才会填充</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.ljust(<span class="number">10</span>, <span class="string">&#x27;l&#x27;</span>))</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">根据指定的一个字符fillchar，将原有字符串向左填充到指定长度width（字符串前面）</span></span><br><span class="line"><span class="string">rjust(width, fillchar)</span></span><br><span class="line"><span class="string">返回值: 返回填充后的字符串</span></span><br><span class="line"><span class="string">注意: 原有字符串不会改变，只有原字符串长度 &lt; 指定结果长度时才会填充</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.rjust(<span class="number">10</span>, <span class="string">&#x27;l&#x27;</span>))</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">根据指定的一个字符fillchar，将原有字符串两边填充到指定长度width（字符串在中间）</span></span><br><span class="line"><span class="string">center(width, fillchar)</span></span><br><span class="line"><span class="string">返回值: 返回填充后的字符串</span></span><br><span class="line"><span class="string">注意: 原有字符串不会改变，只有原字符串长度 &lt; 指定结果长度时才会填充</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.center(<span class="number">10</span>, <span class="string">&#x27;l&#x27;</span>))</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">移除原有字符串指定字符(默认为空白字符)</span></span><br><span class="line"><span class="string">仅仅移除左侧</span></span><br><span class="line"><span class="string">lstrip(chars)</span></span><br><span class="line"><span class="string">参数：需要移除的字符集，移除&#x27;a&#x27;|&#x27;b&#x27;|&#x27;c&#x27;...</span></span><br><span class="line"><span class="string">返回值: 返回移除后的字符串</span></span><br><span class="line"><span class="string">注意: 原有字符串不会改变</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;|&quot;</span> + string.lstrip() + <span class="string">&quot;|&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;|&quot;</span> + string.lstrip(<span class="string">&quot;wo&quot;</span>) + <span class="string">&quot;|&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;|&quot;</span> + string + <span class="string">&quot;|&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">移除原有字符串指定字符(默认为空白字符)</span></span><br><span class="line"><span class="string">仅仅移除左侧</span></span><br><span class="line"><span class="string">rstrip(chars)</span></span><br><span class="line"><span class="string">参数：需要移除的字符集,移除&#x27;a&#x27;|&#x27;b&#x27;|&#x27;c&#x27;...</span></span><br><span class="line"><span class="string">返回值: 返回移除后的字符串</span></span><br><span class="line"><span class="string">注意: 原有字符串不会改变，向左没有检测到字符集的字符，直接终止</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;|&quot;</span> + string.rstrip() + <span class="string">&quot;|&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;|&quot;</span> + string.rstrip(<span class="string">&quot;wo&quot;</span>) + <span class="string">&quot;|&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;|&quot;</span> + string + <span class="string">&quot;|&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 字符串的分隔拼接</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">将一个大的字符串分隔成几个子字符串</span></span><br><span class="line"><span class="string">split(sep, maxsplit)</span></span><br><span class="line"><span class="string">参数一：sep 分隔符</span></span><br><span class="line"><span class="string">参数二： maxsplit 分隔次数，可以省略，有多少分隔多少</span></span><br><span class="line"><span class="string">返回值：返回分隔后的字符串，组成为列表(list)</span></span><br><span class="line"><span class="string">注意：不会改变原字符串</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">result = string.split(<span class="string">&quot;-&quot;</span>, <span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">根据指定的分隔符，返回(分隔符左侧内容, 分隔符, 分隔符右侧内容)</span></span><br><span class="line"><span class="string">partition(sep)</span></span><br><span class="line"><span class="string">参数一：sep 分隔符</span></span><br><span class="line"><span class="string">返回值：</span></span><br><span class="line"><span class="string">    如果找到分隔符，返回(分隔符左侧内容, 分隔符, 分隔符右侧内容) tuple类型</span></span><br><span class="line"><span class="string">    如果没有找到分隔符，返回(原字符串, &quot;&quot;, &quot;&quot;) tuple类型</span></span><br><span class="line"><span class="string">注意：不会改变原字符串,从左侧开始找分隔符</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">result = string.partition(<span class="string">&quot;-&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">根据指定的分隔符，返回(分隔符左侧内容, 分隔符, 分隔符右侧内容)</span></span><br><span class="line"><span class="string">rpartition(sep)</span></span><br><span class="line"><span class="string">参数一：sep 分隔符</span></span><br><span class="line"><span class="string">返回值：</span></span><br><span class="line"><span class="string">    如果找到分隔符，返回(分隔符左侧内容, 分隔符, 分隔符右侧内容) tuple类型</span></span><br><span class="line"><span class="string">    如果没有找到分隔符，返回(&quot;&quot;, &quot;&quot;, 原字符串) tuple类型</span></span><br><span class="line"><span class="string">注意：不会改变原字符串,从右侧开始找分隔符</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">result = string.rpartition(<span class="string">&quot;-&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">按照换行符(\r,\n),将字符串拆成多个元素，保存到列表中</span></span><br><span class="line"><span class="string">splitlines(keepends)</span></span><br><span class="line"><span class="string">参数一：keepends 是否保留换行符 bool类型</span></span><br><span class="line"><span class="string">返回值：</span></span><br><span class="line"><span class="string">    被换行符分隔的多个字符串，作为元素组成的列表</span></span><br><span class="line"><span class="string">    list类型</span></span><br><span class="line"><span class="string">注意：不会改变原字符串</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">result = string.splitlines(<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"><span class="built_in">print</span>(string)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">根据指定字符串，将给定的可迭代对象，进行拼接，得到拼接后的拼接字符串</span></span><br><span class="line"><span class="string">join(iterable)</span></span><br><span class="line"><span class="string">参数一：iterable</span></span><br><span class="line"><span class="string">        可迭代对象</span></span><br><span class="line"><span class="string">        字符串</span></span><br><span class="line"><span class="string">        元祖</span></span><br><span class="line"><span class="string">        列表</span></span><br><span class="line"><span class="string">        ...</span></span><br><span class="line"><span class="string">        </span></span><br><span class="line"><span class="string">返回值：拼接好的新字符串</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">items = [<span class="string">&quot;sz&quot;</span>, <span class="string">&quot;18&quot;</span>, <span class="string">&quot;gg&quot;</span>]</span><br><span class="line">result = <span class="string">&quot;-&quot;</span>.join(items)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 字符串函数判定操作</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">字符串中是否所有的字符都是字母</span></span><br><span class="line"><span class="string">    不包含该数字，特殊符号，标点符号等等</span></span><br><span class="line"><span class="string">    至少有一个字符</span></span><br><span class="line"><span class="string">语法：isalpha()</span></span><br><span class="line"><span class="string">返回值：是否全部是字母，bool类型</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(name.isalpha())</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">字符串中是否所有的字符都是数字</span></span><br><span class="line"><span class="string">    不包含该字母，特殊符号，标点符号等等</span></span><br><span class="line"><span class="string">    至少有一个字符</span></span><br><span class="line"><span class="string">语法：isdigit()</span></span><br><span class="line"><span class="string">返回值：是否全部是数字，bool类型</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.isdigit())</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">字符串中是否所有的字符都是数字或字母</span></span><br><span class="line"><span class="string">    不包含该特殊符号，标点符号等等</span></span><br><span class="line"><span class="string">    至少有一个字符</span></span><br><span class="line"><span class="string">语法：isalnum()</span></span><br><span class="line"><span class="string">返回值：是否全部是字母或数字，bool类型</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.isalnum())</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">字符串中是否所有的字符都是空白符</span></span><br><span class="line"><span class="string">    包含空格，缩进，换行等不可见转义符</span></span><br><span class="line"><span class="string">    至少有一个字符</span></span><br><span class="line"><span class="string">语法：isspace()</span></span><br><span class="line"><span class="string">返回值：是否全部是空白符，bool类型</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.isspace())</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">判断一个字符串是否以某个前缀开头</span></span><br><span class="line"><span class="string">语法：startswith(prefix, start=0, end=len(str))</span></span><br><span class="line"><span class="string">参数一：prefix  需要判断的前缀字符串</span></span><br><span class="line"><span class="string">参数二：start  判定的起始位置</span></span><br><span class="line"><span class="string">参数三：end  判定的终止位置</span></span><br><span class="line"><span class="string">返回值：是否以指定前缀开头</span></span><br><span class="line"><span class="string">      bool  类型</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.startswith(<span class="string">&quot;21&quot;</span>, <span class="number">2</span>, <span class="number">4</span>))</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">判断一个字符串是否以某个后缀结尾</span></span><br><span class="line"><span class="string">语法：endswith(suffix, start=0, end=len(str))</span></span><br><span class="line"><span class="string">参数一：suffix  需要判断的后缀字符串</span></span><br><span class="line"><span class="string">参数二：start  判定的起始位置</span></span><br><span class="line"><span class="string">参数三：end  判定的终止位置</span></span><br><span class="line"><span class="string">返回值：是否以指定前缀开头</span></span><br><span class="line"><span class="string">      bool  类型</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(string.endswith(<span class="string">&quot;.doc&quot;</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># in 判断一个字符串，是否被另一个字符串包含</span></span><br><span class="line"><span class="comment"># not in 判断一个字符串，是否不被另一个字符串包含</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;wo&quot;</span> <span class="keyword">in</span> <span class="string">&quot;who am wo&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;wo&quot;</span> <span class="keyword">not</span> <span class="keyword">in</span> <span class="string">&quot;who am wo&quot;</span>)</span><br></pre></td></tr></table></figure><h4 id="4-4-List-列表"><a href="#4-4-List-列表" class="headerlink" title="4.4 List(列表)"></a>4.4 List(列表)</h4><p>1）概念：有序可变的集合</p><p>2）定义：</p><ul><li><p>列表变量名 = [元素1, 元素2, …]，列表的嵌套，即列表的元素可以为列表，但注意不能相互嵌套</p></li><li><p>列表生成式：</p><p>range(stop) : [0, 1, 2, …, stop-1];</p><p>range(start, stop[, step]) : [start, start+2*step, …],step步长默认为1</p><p>注：由于防止生成的列表没有被使用，python3做了一些改变，不会立即生成列表</p></li><li><p>列表推导式：从一个list推导出另一个list；映射解析：一对一变更；过滤：从多到少</p><p>语法：[表达式 for 变量 in 列表]  或  [表达式 for 变量 in 列表 if条件]，其中for遍历可以有多个，表示多层循环遍历</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 列表推导式</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line"><span class="comment"># resList = [num ** 2 for num in nums if num % 2 != 0]</span></span><br><span class="line"><span class="comment"># resList = [num ** 2 for num in nums for num2 in nums]</span></span><br><span class="line">resList = <span class="built_in">list</span>(num ** <span class="number">2</span> <span class="keyword">for</span> num <span class="keyword">in</span> nums <span class="keyword">for</span> num2 <span class="keyword">in</span> nums)</span><br><span class="line"><span class="built_in">print</span>(resList)</span><br></pre></td></tr></table></figure></li><li><p>列表常规方法操作</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 列表添加操作</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">append</span></span><br><span class="line"><span class="string">作用：往列表最后追加一个元素</span></span><br><span class="line"><span class="string">语法：list.append(object)</span></span><br><span class="line"><span class="string">参数：object为添加的元素</span></span><br><span class="line"><span class="string">返回值：None</span></span><br><span class="line"><span class="string">注意：会修改原列表</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line"><span class="built_in">print</span>(nums.append(<span class="number">5</span>))</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">insert</span></span><br><span class="line"><span class="string">作用：往列表指定索引处追加一个元素</span></span><br><span class="line"><span class="string">语法：list.insert(index, object)</span></span><br><span class="line"><span class="string">参数：index为索引（下标），object为添加的元素</span></span><br><span class="line"><span class="string">返回值：None</span></span><br><span class="line"><span class="string">注意：会修改原列表</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line"><span class="built_in">print</span>(nums.insert(<span class="number">1</span>, <span class="number">5</span>))</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">extend</span></span><br><span class="line"><span class="string">作用：往列表拓展另一个可迭代序列</span></span><br><span class="line"><span class="string">语法：list.extend(iterable)</span></span><br><span class="line"><span class="string">参数：iterable为可迭代集合</span></span><br><span class="line"><span class="string">        字符串、列表、元组、等等 </span></span><br><span class="line"><span class="string">返回值：None</span></span><br><span class="line"><span class="string">注意：会修改原列表，和append区别是两个集合的拼接</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line">nums2 = [<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>]</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line"><span class="built_in">print</span>(nums.extend(nums2))</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 乘法运算</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line"><span class="built_in">print</span>(nums * <span class="number">3</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 加法运算</span></span><br><span class="line">nums1 = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line">nums2 = [<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>]</span><br><span class="line"><span class="comment"># nums3 = &quot;abf&quot; 不能拼接字符串</span></span><br><span class="line"><span class="built_in">print</span>(nums1 + nums2)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 列表删除操作</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">del</span></span><br><span class="line"><span class="string">作用：可以删除一个指定元素或对象</span></span><br><span class="line"><span class="string">语法：del 指定元素</span></span><br><span class="line"><span class="string">参数：无 </span></span><br><span class="line"><span class="string">返回值：无</span></span><br><span class="line"><span class="string">注意：可以删除整个列表、某个元素、一个变量</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line"><span class="comment"># 删除某个元素</span></span><br><span class="line"><span class="keyword">del</span> nums[<span class="number">0</span>]</span><br><span class="line"><span class="comment"># 删除整个列表</span></span><br><span class="line"><span class="keyword">del</span> nums</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line"><span class="comment"># 删除一个变量</span></span><br><span class="line">num = <span class="number">666</span></span><br><span class="line"><span class="keyword">del</span> num</span><br><span class="line"><span class="built_in">print</span>(num)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">pop</span></span><br><span class="line"><span class="string">作用：移除并返回列表中指定索引对应元素</span></span><br><span class="line"><span class="string">语法：list.pop(index = -1)</span></span><br><span class="line"><span class="string">参数：index默认是-1，即最后一个元素</span></span><br><span class="line"><span class="string">返回值：被删除元素</span></span><br><span class="line"><span class="string">注意：会直接修改原数组，注意越界</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line"><span class="built_in">print</span>(nums.pop(<span class="number">2</span>))</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">remove</span></span><br><span class="line"><span class="string">作用：移除列表中指定元素</span></span><br><span class="line"><span class="string">语法：list.remove(object)</span></span><br><span class="line"><span class="string">参数：object是待移除的元素 </span></span><br><span class="line"><span class="string">返回值：None</span></span><br><span class="line"><span class="string">注意：会直接修改原数组，如果不存在，报错，存在多个，删除最左边一个，注意循环内删除列表元素的坑</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line"><span class="built_in">print</span>(nums.remove(<span class="number">2</span>))</span><br><span class="line"><span class="built_in">print</span>(nums)</span><br><span class="line">nums2 = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">2</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> num <span class="keyword">in</span> nums2:</span><br><span class="line">    <span class="built_in">print</span>(num)</span><br><span class="line">    <span class="keyword">if</span> num == <span class="number">2</span>:</span><br><span class="line">        nums2.remove(<span class="number">2</span>)</span><br><span class="line"><span class="built_in">print</span>(nums2)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改列表</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">通过下标修改指定列表的指定索引处的值</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line">nums[<span class="number">2</span>] = <span class="number">6</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 列表查询</span></span><br><span class="line"><span class="comment"># 获取单个，元素通过下标（索引）查询</span></span><br><span class="line">nums = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">5</span>, <span class="number">2</span>, <span class="number">6</span>, <span class="number">6</span>]</span><br><span class="line"><span class="built_in">print</span>(nums[<span class="number">2</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取元素索引 list.index(value,start,stop)</span></span><br><span class="line"><span class="built_in">print</span>(nums.index(<span class="number">5</span>, <span class="number">5</span>, <span class="number">6</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取指定元素个数 count()</span></span><br><span class="line"><span class="built_in">print</span>(nums.count(<span class="number">5</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 切片与字符串一样</span></span><br><span class="line"><span class="built_in">print</span>(nums[<span class="number">1</span>:<span class="number">4</span>:<span class="number">1</span>])</span><br><span class="line"><span class="built_in">print</span>(nums[-<span class="number">1</span>:-<span class="number">4</span>:-<span class="number">2</span>])</span><br></pre></td></tr></table></figure></li><li><p>列表查询遍历操作:</p><p>1) 根据元素进行遍历</p>   <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># for item in list:</span></span><br><span class="line">values = [<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>, <span class="string">&#x27;d&#x27;</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> v <span class="keyword">in</span> values:</span><br><span class="line">    currentIndex = <span class="number">0</span></span><br><span class="line">    <span class="built_in">print</span>(v)</span><br><span class="line">    <span class="built_in">print</span>(values.index(v, currentIndex))</span><br><span class="line">    currentIndex += <span class="number">1</span></span><br></pre></td></tr></table></figure><p>2) 根据索引进行遍历</p>   <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># for index in range(len(list)):</span></span><br><span class="line">values = [<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>, <span class="string">&#x27;d&#x27;</span>, <span class="string">&#x27;e&#x27;</span>]</span><br><span class="line"><span class="keyword">for</span> index <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(values)):</span><br><span class="line">    <span class="built_in">print</span>(index, values[index])</span><br></pre></td></tr></table></figure><p>3) 根据枚举对象进行遍历(了解)</p>   <figure class="highlight python"><table><tr><td class="code"><pre><span class="line">values = [<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>, <span class="string">&#x27;d&#x27;</span>, <span class="string">&#x27;e&#x27;</span>]</span><br><span class="line"><span class="comment"># 1.根据列表创建枚举对象</span></span><br><span class="line"><span class="comment"># 语法：enumerate(list, [start=0])</span></span><br><span class="line"><span class="comment"># print(list(enumerate(values)))</span></span><br><span class="line"><span class="comment"># 2.遍历枚举对象，可以直接遍历</span></span><br><span class="line"><span class="keyword">for</span> index, value <span class="keyword">in</span> <span class="built_in">enumerate</span>(values):</span><br><span class="line"><span class="comment"># for tupleValue in enumerate(values):</span></span><br><span class="line">    <span class="comment"># print(tupleValue)</span></span><br><span class="line">    <span class="comment"># print(tupleValue[0])</span></span><br><span class="line">    <span class="comment"># print(tupleValue[1])</span></span><br><span class="line">    <span class="comment"># index, value = tupleValue</span></span><br><span class="line">    <span class="built_in">print</span>(index)</span><br><span class="line">    <span class="built_in">print</span>(value)</span><br></pre></td></tr></table></figure><p>4) 根据迭代器进行遍历(了解)</p>   <figure class="highlight python"><table><tr><td class="code"><pre><span class="line">l = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="comment"># 创建迭代器对象</span></span><br><span class="line">it = <span class="built_in">iter</span>(l)</span><br><span class="line"><span class="comment"># 内部自动调整指针，指向下一个索引</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(it))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(it))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(it))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(it))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(it))</span><br><span class="line"><span class="comment"># 迭代完成，继续迭代会报错StopIteration</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(it))</span><br><span class="line"><span class="keyword">for</span> v <span class="keyword">in</span> it:</span><br><span class="line">    <span class="built_in">print</span>(v)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;===========&quot;</span>)</span><br><span class="line"><span class="comment"># 不能多次迭代，只能重新创建迭代器对象</span></span><br><span class="line"><span class="keyword">for</span> v <span class="keyword">in</span> it:</span><br><span class="line">    <span class="built_in">print</span>(v)</span><br></pre></td></tr></table></figure><p>5) 迭代器</p><ul><li><p>可迭代对象：能够被迭代的对象</p><p>判断方法：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> collections.abc <span class="keyword">import</span> Iterable</span><br><span class="line"><span class="built_in">isinstance</span>(obj, Iterable)</span><br></pre></td></tr></table></figure><p>判断依据：能否作用于for in</p></li><li><p>迭代器是可以记录遍历位置的对象，从第一个元素开始，往后只能通过next()函数进行遍历，只能往前，不能往后</p><p>判断方法：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> collections.abc <span class="keyword">import</span> Iterator</span><br><span class="line"><span class="built_in">isinstance</span>(obj, Iterator)</span><br></pre></td></tr></table></figure><p>判断依据：能否作用于next()函数</p><p>注意：迭代器也是可迭代对象，也可以使用for in</p></li><li><p>迭代器产生原因：</p><p><strong>仅仅迭代到某个元素时才会处理该元素：</strong> 在此之前，元素可以不存在，在此之后，元素可以销毁，适用于无限大集合，例如斐波那契数列<br><strong>提供了一个统一的访问集合的接口：</strong> 可以将所有可迭代对象转换成迭代器使用</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">iter(Iterable)</span><br><span class="line">iter(str)</span><br><span class="line">iter(list)</span><br><span class="line">iter(tuple)</span><br><span class="line">iter(dict)</span><br><span class="line">...</span><br></pre></td></tr></table></figure><p><strong>注：迭代完成，继续迭代会报错StopIteration，使用for in，不能多次迭代，只能重新创建迭代器对象</strong></p></li></ul><p>6) 列表其他操作</p>   <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 判断元素是否在集合</span></span><br><span class="line"><span class="comment"># in 判断元素是否在列表中（对其他集合和字符串通用）</span></span><br><span class="line"><span class="comment"># not in 判断元素是否在列表中（对其他集合和字符串通用）</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 比较</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">cmp(val1,val2)</span></span><br><span class="line"><span class="string">内建函数</span></span><br><span class="line"><span class="string">如果比较字符串，列表等集合,从左往右逐个比较</span></span><br><span class="line"><span class="string">val1 &gt; val2  1</span></span><br><span class="line"><span class="string">val1 = val2  0</span></span><br><span class="line"><span class="string">val1 &lt; val2  -1</span></span><br><span class="line"><span class="string">python3.x不支持</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">python3使用比较运算符比较</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="comment"># python3</span></span><br><span class="line"><span class="built_in">print</span>([<span class="number">1</span>, <span class="number">2</span>] &gt; [<span class="number">1</span>, <span class="number">3</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment"># 排序方式一：内建函数，返回一个列表，原来列表不变</span></span><br><span class="line"><span class="comment"># s = &quot;happynewYear&quot;</span></span><br><span class="line">s = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">9</span>]</span><br><span class="line"><span class="comment"># 升序，返回一个列表</span></span><br><span class="line">res = <span class="built_in">sorted</span>(s)</span><br><span class="line"><span class="built_in">print</span>(res)</span><br><span class="line"><span class="comment"># print(s)</span></span><br><span class="line"><span class="comment"># 降序</span></span><br><span class="line">res1 = <span class="built_in">sorted</span>(s, reverse=<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">print</span>(res1)</span><br><span class="line">s1 = [(<span class="string">&quot;dd1&quot;</span>, <span class="number">18</span>), (<span class="string">&quot;dd5&quot;</span>, <span class="number">16</span>), (<span class="string">&quot;dd2&quot;</span>, <span class="number">28</span>), (<span class="string">&quot;dd1&quot;</span>, <span class="number">15</span>)]</span><br><span class="line"><span class="comment"># 第一个值的比较排序</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sorted</span>(s1))</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">getKey</span>(<span class="params">x</span>):</span><br><span class="line">    <span class="keyword">return</span> x[<span class="number">1</span>]</span><br><span class="line"><span class="comment"># 第二个值来排序</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">sorted</span>(s1,key=getKey, reverse=<span class="literal">True</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 排序方式二:更改对象本身，返回值为None</span></span><br><span class="line">val = [<span class="number">11</span>, <span class="number">2</span>, <span class="number">45</span>, <span class="number">56</span>]</span><br><span class="line"><span class="built_in">print</span>(val.sort(), val)</span><br><span class="line">s = [(<span class="string">&quot;dd1&quot;</span>, <span class="number">18</span>), (<span class="string">&quot;dd5&quot;</span>, <span class="number">16</span>), (<span class="string">&quot;dd2&quot;</span>, <span class="number">28</span>), (<span class="string">&quot;dd1&quot;</span>, <span class="number">15</span>)]</span><br><span class="line"><span class="built_in">print</span>(s.sort())</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">getKey</span>(<span class="params">x</span>):</span><br><span class="line">    <span class="keyword">return</span> x[<span class="number">1</span>]</span><br><span class="line"><span class="comment"># 第二个元素降序排序</span></span><br><span class="line"><span class="built_in">print</span>(s.sort(key=getKey, reverse=<span class="literal">True</span>), s)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">乱序</span></span><br><span class="line"><span class="string">import random</span></span><br><span class="line"><span class="string">random.shuffle(list) </span></span><br><span class="line"><span class="string">返回值 ：None</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line">l = [<span class="number">1</span>, <span class="number">5</span>, <span class="number">98</span>, <span class="number">6</span>, <span class="number">2</span>]</span><br><span class="line">res = random.shuffle(l)</span><br><span class="line"><span class="built_in">print</span>(res, l)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">反转</span></span><br><span class="line"><span class="string">list.reverse() </span></span><br><span class="line"><span class="string">返回值 ：None</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">l = [<span class="number">1</span>, <span class="number">5</span>, <span class="number">98</span>, <span class="number">6</span>, <span class="number">2</span>]</span><br><span class="line">res = l.reverse()</span><br><span class="line"><span class="built_in">print</span>(res, l)</span><br><span class="line"><span class="comment"># 切片反转,返回值反转，不会改变本身</span></span><br><span class="line">res1 = l[::-<span class="number">1</span>]</span><br><span class="line"><span class="built_in">print</span>(res1, l)</span><br></pre></td></tr></table></figure></li></ul><h4 id="4-5-set-集合"><a href="#4-5-set-集合" class="headerlink" title="4.5 set(集合)"></a>4.5 set(集合)</h4><p>1）概念：无序的，不可随机访问的，不可重复的元素集合</p><ul><li>可变集合set：可以增删改</li><li>不可变集合frozenset：不能增删改</li></ul><p>2）可变集合定义：</p><ul><li><p>集合变量名 = {元素1, 元素2, …}；</p></li><li><p>集合变量名 = set(iterable), 即可以转换字符串、列表、元组、字典为set集合，字典时，只生成key的集合；</p></li><li><p>集合的推导式：集合变量名={推导式}或者set(推导式)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 集合推导式</span></span><br><span class="line"><span class="comment"># set5 = set(x for x in range(10) if x % 2 == 0)</span></span><br><span class="line">set5 = &#123;x <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>) <span class="keyword">if</span> x % <span class="number">2</span> == <span class="number">0</span>&#125;</span><br><span class="line"><span class="built_in">print</span>(set5, <span class="built_in">type</span>(set5))</span><br></pre></td></tr></table></figure></li><li><p>集合的嵌套，即元组的元素可以为元组，但注意不能相互嵌套</p></li></ul><p>3） 不可变集合定义：</p><ul><li><p>集合变量名 = frozenset(iterable), 即可以转换字符串、列表、元组、字典为set集合，字典时，只生成key的集合；</p></li><li><p>集合的推导式：集合变量名=frozenset(推导式)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">fs = <span class="built_in">frozenset</span>(x <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>) <span class="keyword">if</span> x % <span class="number">2</span> == <span class="number">0</span>)</span><br><span class="line"><span class="built_in">print</span>(fs, <span class="built_in">type</span>(fs))</span><br></pre></td></tr></table></figure></li></ul><p>4） 注意：</p><ul><li><p>创建一个空集合时需要使用set()或者frozenset()，不能使用是s={},会被识别为dict字典</p></li><li><p>集合中的元素必须是可哈希的值：</p><p>如果一对象在自己的生命周期中有一哈希值(hash value)，是不可变的，那么它是可哈希的(hashable)到，暂时认为是不可变类型</p><p>比如字典、列表是可变类型，元组、字符串是不可变类型</p></li><li><p>如果集合中的元素出现重复，则会被合并为一个 </p></li></ul><p>5） 集合常规操作方法：</p><p>​    a）可变集合：(元素为不可变类型，不能修改)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 集合常用操作方法</span></span><br><span class="line"><span class="comment"># 增 返回值None</span></span><br><span class="line">add = s.add(<span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(s, <span class="built_in">type</span>(s), add)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 删</span></span><br><span class="line"><span class="comment"># s.remove(element) 返回值None 没有该元素，报错KeyError</span></span><br><span class="line">remove = s.remove(<span class="number">4</span>)</span><br><span class="line"><span class="comment"># remove = s.remove(5)</span></span><br><span class="line"><span class="built_in">print</span>(s, <span class="built_in">type</span>(s), remove)</span><br><span class="line"></span><br><span class="line"><span class="comment"># s.discard(element) 返回值None 没有该元素，什么都不会发生</span></span><br><span class="line">discard = s.discard(<span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(s, <span class="built_in">type</span>(s), discard)</span><br><span class="line"></span><br><span class="line"><span class="comment"># s.pop(element) 随机删除并返回集合中的某个元素，集合为空，报错</span></span><br><span class="line"><span class="comment"># p1 = s.pop()</span></span><br><span class="line"><span class="comment"># print(p1)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># s.clear() 返回值None，清空集合，集合仍存在</span></span><br><span class="line">clear = s.clear()</span><br><span class="line"><span class="built_in">print</span>(s, clear)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 查</span></span><br><span class="line"><span class="comment"># 无法通过索引或key进行查询</span></span><br><span class="line">s = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;</span><br><span class="line"><span class="comment"># for v in s:</span></span><br><span class="line"><span class="comment">#     print(v)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 1.生成一个迭代器</span></span><br><span class="line">its = <span class="built_in">iter</span>(s)</span><br><span class="line"><span class="comment"># 2.使用迭代器取访问(next()  或 for in)</span></span><br><span class="line"><span class="comment"># print(next(its))</span></span><br><span class="line"><span class="comment"># print(next(its))</span></span><br><span class="line"><span class="comment"># print(next(its))</span></span><br><span class="line"><span class="comment"># 指针为null</span></span><br><span class="line"><span class="comment"># print(next(its))</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> it <span class="keyword">in</span> its:</span><br><span class="line">    <span class="built_in">print</span>(it)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;==========&quot;</span>)</span><br><span class="line"><span class="comment"># 迭代一次后，迭代器对象需要重新创建才可以遍历</span></span><br><span class="line"><span class="keyword">for</span> it <span class="keyword">in</span> its:</span><br><span class="line">    <span class="built_in">print</span>(it)</span><br></pre></td></tr></table></figure><p>b) 不可变集合常用方法：(不能增删改)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 不可变集合查询</span></span><br><span class="line">fs = <span class="built_in">frozenset</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="keyword">for</span> f <span class="keyword">in</span> fs:</span><br><span class="line">    <span class="built_in">print</span>(f)</span><br><span class="line">ifs = <span class="built_in">iter</span>(fs)</span><br><span class="line"></span><br><span class="line"><span class="comment"># print(next(ifs))</span></span><br><span class="line"><span class="comment"># print(next(ifs))</span></span><br><span class="line"><span class="comment"># print(next(ifs))</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> ifs:</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br></pre></td></tr></table></figure><p>c) 集合之间交并差集判定操作：(可变集合与不可变集合做混合运算，返回值类型以运算符左侧类型为主)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">s1 = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">9</span>&#125;</span><br><span class="line">s2 = &#123;<span class="number">2</span>, <span class="number">4</span>, <span class="number">3</span>, <span class="number">9</span>, <span class="number">8</span>&#125;</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">交集</span></span><br><span class="line"><span class="string">intersection(iterable) </span></span><br><span class="line"><span class="string">    字符串(只判断非数字）</span></span><br><span class="line"><span class="string">    元组</span></span><br><span class="line"><span class="string">    集合</span></span><br><span class="line"><span class="string">    列表</span></span><br><span class="line"><span class="string">    字典(只判断key)</span></span><br><span class="line"><span class="string">    ...</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">逻辑与&#x27;&amp;&#x27; 集合本身不会改变</span></span><br><span class="line"><span class="string">intersection_update(iterable)</span></span><br><span class="line"><span class="string">    交集计算完后会赋值给原集合，所以只适用于可变集合</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">res = s1.intersection(s2)</span><br><span class="line"><span class="comment"># set</span></span><br><span class="line"><span class="built_in">print</span>(res, <span class="built_in">type</span>(res))</span><br><span class="line">s3 = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">9</span>&#125;</span><br><span class="line">s4 = <span class="built_in">frozenset</span>([<span class="number">2</span>, <span class="number">4</span>, <span class="number">3</span>, <span class="number">9</span>, <span class="number">8</span>])</span><br><span class="line"><span class="comment"># frozenset</span></span><br><span class="line">res1 = s4.intersection(s3)</span><br><span class="line"><span class="built_in">print</span>(res1, <span class="built_in">type</span>(res1))</span><br><span class="line"></span><br><span class="line">res2 = s1.intersection_update(s2)</span><br><span class="line"><span class="comment"># res2:None s1:&#123;9, 2, 3&#125; s2:&#123;2, 3, 4, 8, 9&#125;</span></span><br><span class="line"><span class="built_in">print</span>(res2, <span class="built_in">type</span>(res2), s1, s2)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 集合本身不会改变</span></span><br><span class="line"><span class="comment"># res3 = s1 &amp; s2</span></span><br><span class="line"><span class="comment"># print(res3, type(res3), s1, s2)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># set() 因为不会判断数字</span></span><br><span class="line"><span class="built_in">print</span>(s1.intersection(<span class="string">&quot;123&quot;</span>))</span><br><span class="line">s5 = &#123;<span class="string">&quot;1&quot;</span>, <span class="string">&quot;2&quot;</span>, <span class="string">&quot;5&quot;</span>&#125;</span><br><span class="line"><span class="comment"># 只能判定字符串</span></span><br><span class="line"><span class="built_in">print</span>(s5.intersection(<span class="string">&quot;123&quot;</span>))</span><br><span class="line"><span class="built_in">print</span>(s5.intersection([<span class="string">&quot;1&quot;</span>, <span class="string">&quot;2&quot;</span>, <span class="string">&quot;6&quot;</span>]))</span><br><span class="line"><span class="comment"># 不能存在不可哈希的值[&quot;1&quot;, &quot;5&quot;]</span></span><br><span class="line"><span class="built_in">print</span>(s5.intersection([<span class="string">&quot;1&quot;</span>, <span class="string">&quot;2&quot;</span>, [<span class="string">&quot;1&quot;</span>, <span class="string">&quot;5&quot;</span>]]))</span><br><span class="line"><span class="built_in">print</span>(s5.intersection(&#123;<span class="string">&quot;1&quot;</span>: <span class="string">&quot;vv&quot;</span>, <span class="string">&quot;2&quot;</span>: <span class="string">&quot;jj&quot;</span>, <span class="string">&quot;6&quot;</span>: <span class="string">&quot;55&quot;</span>&#125;))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">并集</span></span><br><span class="line"><span class="string">union()</span></span><br><span class="line"><span class="string">    返回并集</span></span><br><span class="line"><span class="string">逻辑或&#x27;|&#x27;</span></span><br><span class="line"><span class="string">    返回并集</span></span><br><span class="line"><span class="string">update()</span></span><br><span class="line"><span class="string">    更新并集,原左侧集合更新为并集</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">s3 = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;</span><br><span class="line"><span class="comment"># s3 = frozenset([1, 2, 3])</span></span><br><span class="line">s4 = &#123;<span class="number">4</span>, <span class="number">2</span>, <span class="number">5</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment"># res1 = s3.union(s4)</span></span><br><span class="line"><span class="comment"># res1 = s3 | s4</span></span><br><span class="line"><span class="comment"># None, s3:&#123;1, 2, 3, 4, 5&#125;</span></span><br><span class="line">res1 = s3.update(s4)</span><br><span class="line"><span class="built_in">print</span>(res1, <span class="built_in">type</span>(res1), s3, s4)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">差集</span></span><br><span class="line"><span class="string">difference()</span></span><br><span class="line"><span class="string">    返回差集</span></span><br><span class="line"><span class="string">算术运算符&#x27;-&#x27; </span></span><br><span class="line"><span class="string">    返回并集</span></span><br><span class="line"><span class="string">update()</span></span><br><span class="line"><span class="string">    更新并集,原左侧集合更新为并集</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="comment"># s3 = &#123;1, 2, 3&#125;</span></span><br><span class="line">s3 = <span class="built_in">frozenset</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line">s4 = &#123;<span class="number">4</span>, <span class="number">2</span>, <span class="number">5</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment"># res1 = s3.difference(s4)</span></span><br><span class="line">res1 = s3 - s4</span><br><span class="line"><span class="comment"># None, s3:&#123;1, 3&#125;</span></span><br><span class="line"><span class="comment"># res1 = s3.difference_update(s4)</span></span><br><span class="line"><span class="built_in">print</span>(res1, <span class="built_in">type</span>(res1), s3, s4)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">判定</span></span><br><span class="line"><span class="string">两个集合不相交：isdisjoint()</span></span><br><span class="line"><span class="string">一个集合包含另一个集合：issuperset()</span></span><br><span class="line"><span class="string">一个集合包含于另一个集合：issubset()</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">set1 = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;</span><br><span class="line">set2 = &#123;<span class="number">1</span>, <span class="number">2</span>&#125;</span><br><span class="line"><span class="comment"># False</span></span><br><span class="line"><span class="built_in">print</span>(set1.isdisjoint(set2))</span><br><span class="line"><span class="comment"># True</span></span><br><span class="line"><span class="built_in">print</span>(set1.issuperset(set2))</span><br><span class="line"><span class="comment"># False</span></span><br><span class="line"><span class="built_in">print</span>(set1.issubset(set2))</span><br><span class="line"><span class="built_in">print</span>(set1.issubset(set1))</span><br></pre></td></tr></table></figure><h4 id="4-6-Tuple-元组"><a href="#4-6-Tuple-元组" class="headerlink" title="4.6 Tuple(元组)"></a>4.6 Tuple(元组)</h4><p>1）概念：有序不可变的集合</p><p>2）定义：</p><ul><li>元组变量名 = (元素1, 元素2, …)；</li><li>元组变量名 = (元素1, )只有一个元素时，需要写逗号；</li><li>元组变量名 = 元素1, 元素2, …；</li><li>元组变量名 = tuple(list)；</li><li>元组的嵌套，即元组的元素可以为元组，但注意不能相互嵌套</li></ul><p>3） 元组常规操作方法：</p><p><strong>元组不能增加、删除、修改元素。</strong></p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">元祖查询</span></span><br><span class="line"><span class="string">获取单个元素，下标法 tuple[index]</span></span><br><span class="line"><span class="string">获取多个元素</span></span><br><span class="line"><span class="string">tuple[start:stop:step] 与字符串和列表同理</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">元组获取</span></span><br><span class="line"><span class="string">tuple.count(item), 统计元组中指定元素的个数，没有返回0</span></span><br><span class="line"><span class="string">tuple.index(item), 获取元组中指定元素的索引，没有报错</span></span><br><span class="line"><span class="string">内建函数</span></span><br><span class="line"><span class="string">len(tuple), 返回元组的元素个数</span></span><br><span class="line"><span class="string">max(tuple), 返回元组的元素最大值</span></span><br><span class="line"><span class="string">min(tuple), 返回元组的元素最小值</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">in 判定元素是否在元组里面</span></span><br><span class="line"><span class="string">not in判定元素是否不在元组里面</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 比较</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">cmp(val1,val2)</span></span><br><span class="line"><span class="string">内建函数</span></span><br><span class="line"><span class="string">如果比较字符串，列表等集合,从左往右逐个比较</span></span><br><span class="line"><span class="string">val1 &gt; val2  1</span></span><br><span class="line"><span class="string">val1 = val2  0</span></span><br><span class="line"><span class="string">val1 &lt; val2  -1</span></span><br><span class="line"><span class="string">python3.x不支持</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">python3使用比较运算符比较</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">t = (<span class="string">&#x27;aa&#x27;</span>, <span class="string">&#x27;bb&#x27;</span>, <span class="string">&#x27;cc&#x27;</span>, <span class="string">&quot;dd&quot;</span>, <span class="string">&quot;ee&quot;</span>)</span><br><span class="line">t1 = (<span class="string">&#x27;aa&#x27;</span>, <span class="string">&#x27;bb&#x27;</span>, <span class="string">&#x27;cc&#x27;</span>, <span class="string">&quot;dd&quot;</span>, <span class="string">&quot;ee&quot;</span>, <span class="string">&quot;ff&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(t &gt; t1)</span><br><span class="line"><span class="built_in">print</span>(t == t)</span><br><span class="line"><span class="built_in">print</span>(t &lt; t1)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 元组拼接</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">乘法拼接：tuple * int类型</span></span><br><span class="line"><span class="string">加法拼接：tuple1 + tuple2</span></span><br><span class="line"><span class="string">注意不同数据类型不能使用+拼接，保错</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">拆包</span></span><br><span class="line"><span class="string">变量名1,变量名2... = (元素1,元素2,...)</span></span><br><span class="line"><span class="string">括号可以省略</span></span><br><span class="line"><span class="string">变量名1,变量名2... = 元素1,元素2,...</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">交换变量的值,也可以加括号</span></span><br><span class="line"><span class="string">变量名1,变量名2 = =变量名2, 变量名1</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="4-7-Dictory-字典"><a href="#4-7-Dictory-字典" class="headerlink" title="4.7 Dictory(字典)"></a>4.7 Dictory(字典)</h4><p>1）概念：无序的可变的键值对集合</p><p>2）定义：</p><ul><li>字典变量名 = {key1: value1, key2: value2, …}；</li><li>类调用fromkeys，字典变量名 = dict.fromkeys(S, V=None),值不写默认为None，S可以是字符串，列表元组</li><li>字典对象调用fromkeys，字典变量名 = dictory.fromkeys(S, V=None),值不写默认为None，S可以是字符串，列表元组,dictory为字典实例化对象</li><li>字典的嵌套，即字典的元素可以为字典，但注意不能相互嵌套</li><li>字典的key不能重复，如果重复，后值覆盖前值；key必须是任意不可变类型，value可以是任意可变与不可变类型</li></ul><p>3）字典常规操作方法：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 字典常规操作</span></span><br><span class="line"><span class="comment"># 添加一个键值对 dictory[key] = value</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除操作</span></span><br><span class="line"><span class="comment"># 删除一个键值对 del dic[key],当删除的key不存在时，报错</span></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">dic.pop(key[, default])</span></span><br><span class="line"><span class="string">删除指定的键值对，并返回对应的值</span></span><br><span class="line"><span class="string">如果key不存在，返回给的的default值，如果没有指定default值，会报错</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">d = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;admin&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>&#125;</span><br><span class="line"><span class="comment"># v = d.pop(&quot;age&quot;)</span></span><br><span class="line">v = d.pop(<span class="string">&quot;age1&quot;</span>, <span class="number">666</span>)</span><br><span class="line"><span class="built_in">print</span>(d, v)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">dic.popitem()</span></span><br><span class="line"><span class="string">删除按升序排序后的第一个键值对，并以元组的形式返回键值对</span></span><br><span class="line"><span class="string">如果字典为空，则报错</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">d = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;admin&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>&#125;</span><br><span class="line"><span class="comment"># 返回元组</span></span><br><span class="line">dp = d.popitem()</span><br><span class="line"><span class="built_in">print</span>(d, dp)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">dic.clear()</span></span><br><span class="line"><span class="string">删除字典内所有键值对</span></span><br><span class="line"><span class="string">返回值：None</span></span><br><span class="line"><span class="string">注意：字典对象本身还存在，只是清空了内容</span></span><br><span class="line"><span class="string">del是删除一个键值对或整个字典</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">clear = d.clear()</span><br><span class="line"><span class="built_in">print</span>(d, clear)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改字典：只能修改值，不能修改键</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">修改单个键值对</span></span><br><span class="line"><span class="string">dic[key] = value</span></span><br><span class="line"><span class="string">key不存在就是新增操作，存在就是修改操作</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">dic = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;admin&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>&#125;</span><br><span class="line">dic[<span class="string">&quot;age&quot;</span>] = <span class="number">20</span></span><br><span class="line"><span class="built_in">print</span>(dic)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">批量修改键值对</span></span><br><span class="line"><span class="string">oldDic.update(newDic) 返回值：None</span></span><br><span class="line"><span class="string">根据新的字典，批量修改旧字典的键值对值</span></span><br><span class="line"><span class="string">如果旧字典没有key，就新增该key</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">oldDic = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;admin&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>&#125;</span><br><span class="line">newDic = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;root&quot;</span>, <span class="string">&quot;height&quot;</span>: <span class="number">180</span>&#125;</span><br><span class="line">update = oldDic.update(newDic)</span><br><span class="line"><span class="built_in">print</span>(oldDic, newDic, update)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 字典查询操作</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">查询单个键值对 </span></span><br><span class="line"><span class="string">方式一： dic[key],key不存在报错</span></span><br><span class="line"><span class="string">方式二： dic.get(key[, default]), key不存在会返回default值，如果没有给定default值，会返回None，但是原字典不会新增该键值对</span></span><br><span class="line"><span class="string">方式二： dic.setdefault(key[, default]), key不存在会返回default值，如果没有给定default值，会返回None，原字典会新增该键值对</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">dic = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;admin&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>&#125;</span><br><span class="line"><span class="built_in">print</span>(dic[<span class="string">&quot;age&quot;</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment"># dic_get = dic.get(&quot;name1&quot;)</span></span><br><span class="line">dic_get = dic.get(<span class="string">&quot;name1&quot;</span>, <span class="string">&quot;root&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(dic_get, dic)</span><br><span class="line"></span><br><span class="line"><span class="comment"># dic_setdefault = dic.setdefault(&quot;name1&quot;, &quot;root&quot;)</span></span><br><span class="line">dic_setdefault = dic.setdefault(<span class="string">&quot;name1&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(dic_setdefault, dic) </span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">获取字典所有的值： dic.values()</span></span><br><span class="line"><span class="string">获取字典所有的键： dic.keys()</span></span><br><span class="line"><span class="string">获取字典所有的键值对： dic.items()</span></span><br><span class="line"><span class="string">python2.x与python3.x之间获取键、值、键值对之间区别</span></span><br><span class="line"><span class="string">1.python2.x获取到的直接是一个列表，可以通过下标进行获取指定元素</span></span><br><span class="line"><span class="string">2.python3.x获取到的是Dictionary view objects改变键值对，获取到也跟着发生变化</span></span><br><span class="line"><span class="string">3.python2.x提供如下方法:</span></span><br><span class="line"><span class="string">viewkeys()</span></span><br><span class="line"><span class="string">viewvalues()</span></span><br><span class="line"><span class="string">viewitems()</span></span><br><span class="line"><span class="string">作用如同.python3.x的Dictionary view objects</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line">dic = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;admin&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>, <span class="string">&quot;height&quot;</span>: <span class="number">666</span>&#125;</span><br><span class="line">vs = dic.values()</span><br><span class="line"></span><br><span class="line">ks = dic.keys()</span><br><span class="line"></span><br><span class="line">its = dic.items()</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(ks, vs, its)</span><br><span class="line"></span><br><span class="line">dic[<span class="string">&quot;address&quot;</span>] = <span class="string">&quot;shanghai&quot;</span></span><br><span class="line"><span class="built_in">print</span>(dic)</span><br><span class="line"><span class="built_in">print</span>(ks, vs, its)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 遍历方式一：遍历所有的key，根据key获取所有的值</span></span><br><span class="line">dic = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;admin&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>, <span class="string">&quot;height&quot;</span>: <span class="number">666</span>&#125;</span><br><span class="line">keys = dic.keys()</span><br><span class="line"><span class="keyword">for</span> key <span class="keyword">in</span> keys:</span><br><span class="line">    <span class="built_in">print</span>(key)</span><br><span class="line">    <span class="built_in">print</span>(dic[key])</span><br><span class="line">dic[<span class="string">&quot;address&quot;</span>] = <span class="string">&quot;shanghai&quot;</span></span><br><span class="line"><span class="comment"># 遍历方式二：直接遍历所有的键值对</span></span><br><span class="line">items = dic.items()</span><br><span class="line"><span class="built_in">print</span>(items)</span><br><span class="line"><span class="keyword">for</span> k, v <span class="keyword">in</span> items:</span><br><span class="line">    <span class="built_in">print</span>(k, v)</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line"><span class="comment"># 计算键值对个数</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">len</span>(dic))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 判定</span></span><br><span class="line"><span class="comment"># x in dic判定dic中的key是否存在x</span></span><br><span class="line"><span class="comment"># x not in dic判定dic中的key是否不存在x</span></span><br><span class="line"><span class="comment"># dic.has_key(key) 判定dic是否存在key，python2.x可以使用，但是过期了，使用in代替</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;name1&quot;</span> <span class="keyword">in</span> dic)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;name1&quot;</span> <span class="keyword">not</span> <span class="keyword">in</span> dic)</span><br></pre></td></tr></table></figure><h4 id="4-8-NoneType-空类型"><a href="#4-8-NoneType-空类型" class="headerlink" title="4.8 NoneType(空类型)"></a>4.8 NoneType(空类型)</h4><h3 id="5-数据类型转换-强类型语言"><a href="#5-数据类型转换-强类型语言" class="headerlink" title="5.数据类型转换(强类型语言)"></a>5.数据类型转换(强类型语言)</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment">#转换为整数</span></span><br><span class="line"><span class="built_in">int</span>(x) </span><br><span class="line"><span class="comment">#转换为浮点数</span></span><br><span class="line"><span class="built_in">float</span>(x) </span><br><span class="line"><span class="comment">#转换为表达式字符串</span></span><br><span class="line"><span class="built_in">repr</span>(x) </span><br><span class="line"><span class="comment">#转换为字符</span></span><br><span class="line"><span class="built_in">chr</span>(x) </span><br><span class="line"><span class="comment">#转换为Unicode字符</span></span><br><span class="line">unichr(x) </span><br><span class="line"></span><br><span class="line"><span class="comment"># 进制转换</span></span><br><span class="line"><span class="comment">#转换为对应整数值十进制</span></span><br><span class="line"><span class="built_in">ord</span>(x) </span><br><span class="line"><span class="comment">#转换为十六进制字符串</span></span><br><span class="line"><span class="built_in">hex</span>(x) </span><br><span class="line"><span class="comment">#转换为八进制字符串</span></span><br><span class="line"><span class="built_in">oct</span>(x) </span><br><span class="line"><span class="comment">#转换为二进制字符串</span></span><br><span class="line"><span class="built_in">bin</span>(x) </span><br><span class="line"></span><br><span class="line"><span class="comment">#计算字符串的有效表达式，返回对象</span></span><br><span class="line"><span class="built_in">eval</span>(x) </span><br><span class="line"><span class="comment">#转换为字符串</span></span><br><span class="line"><span class="built_in">str</span>(x)</span><br><span class="line"><span class="comment">#将序列转换为元祖</span></span><br><span class="line"><span class="built_in">tuple</span>(S)</span><br><span class="line"><span class="comment">#将序列转换为集合</span></span><br><span class="line"><span class="built_in">list</span>(S)</span><br></pre></td></tr></table></figure><h3 id="6-py运算符"><a href="#6-py运算符" class="headerlink" title="6.py运算符"></a>6.py运算符</h3><ul><li>算术运算符（不同类型运算，自动精度提升，即类型上转换）</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">+  -  *  /(不像c++、java，除数为非整数，有小数部分)</span><br><span class="line">**(幂运算符)  //(整除，只取整数部分)</span><br><span class="line">%(求模) =(赋值)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 上面运算符加上=为复合运算符</span></span><br><span class="line">a, b, c = <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span> <span class="comment">#批量赋值</span></span><br></pre></td></tr></table></figure><ul><li>比较运算符</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">&gt;  &lt;  !=  &lt;&gt;(python2不等于)  &gt;=  &lt;= == <span class="keyword">is</span>(比对唯一标识) x1 &lt;= x &lt;= x3(链式运算符)</span><br></pre></td></tr></table></figure><ul><li>逻辑运算符</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">not</span> <span class="keyword">and</span> <span class="keyword">or</span> <span class="comment"># 非零非空为真，返回结果不一定是bool</span></span><br></pre></td></tr></table></figure><h3 id="7-py输入输出"><a href="#7-py输入输出" class="headerlink" title="7.py输入输出"></a>7.py输入输出</h3><h4 id="7-1-输入"><a href="#7-1-输入" class="headerlink" title="7.1 输入"></a>7.1 输入</h4><ul><li>python2</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">res = raw_input(<span class="string">&#x27;请输入：&#x27;</span>) <span class="comment"># 将内容当做字符串</span></span><br><span class="line">res = <span class="built_in">input</span>(<span class="string">&#x27;提示信息&#x27;</span>) <span class="comment"># 将内容作为代码执行 input = raw_input() + eval()</span></span><br><span class="line">content = raw_input(<span class="string">&quot;qingshuru&quot;</span>)</span><br><span class="line">res = <span class="built_in">eval</span>(content)</span><br></pre></td></tr></table></figure><ul><li>python3</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">res = <span class="built_in">input</span>(<span class="string">&#x27;提示信息&#x27;</span>) <span class="comment"># 等同于python2的raw_input(&#x27;请输入：&#x27;)</span></span><br><span class="line"><span class="comment"># 与python2的input同理</span></span><br><span class="line">content = <span class="built_in">input</span>(<span class="string">&#x27;hh:&#x27;</span>)</span><br><span class="line">res = <span class="built_in">eval</span>(content)</span><br></pre></td></tr></table></figure><h4 id="7-2-输出"><a href="#7-2-输出" class="headerlink" title="7.2 输出"></a>7.2 输出</h4><ul><li>python2</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="built_in">print</span> value1</span><br><span class="line"><span class="built_in">print</span> value1, value2...</span><br><span class="line"><span class="comment"># 格式化输出</span></span><br><span class="line"><span class="built_in">print</span> <span class="string">&#x27;字符串 格式化输出时的数据类型和格式占位符&#x27;</span>%(与前面占位符对应类型)</span><br><span class="line"><span class="comment"># 也可以使用索引</span></span><br><span class="line"><span class="built_in">print</span> <span class="string">&#x27;&#123;0&#125; &#123;1&#125; ...&#x27;</span>.<span class="built_in">format</span>(value1, value2...)</span><br><span class="line"><span class="comment"># 输出到文件</span></span><br><span class="line">f = <span class="built_in">open</span>(<span class="string">&#x27;text.txt&#x27;</span>, <span class="string">&#x27;w&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> &gt;&gt; f, <span class="string">&#x27;hhhh&#x27;</span></span><br><span class="line"><span class="comment"># 输出不换行</span></span><br><span class="line"><span class="built_in">print</span> value1,</span><br><span class="line"><span class="built_in">print</span> value2,</span><br><span class="line"><span class="built_in">print</span> value3,</span><br><span class="line"><span class="built_in">print</span> ...</span><br><span class="line"><span class="comment"># 输出带分割符</span></span><br><span class="line"><span class="built_in">print</span> <span class="string">&#x27;-&#x27;</span>.join([<span class="string">&quot;1&quot;</span>, <span class="string">&quot;2&quot;</span>, <span class="string">&quot;3&quot;</span>])</span><br></pre></td></tr></table></figure><ul><li>python3</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="built_in">print</span>(value1)</span><br><span class="line"><span class="built_in">print</span>(value1, value2...)</span><br><span class="line"><span class="comment"># 格式化输出</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;字符串 格式化输出时的数据类型和格式占位符&#x27;</span>%(与前面占位符对应类型))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;&#123;0&#125; &#123;1&#125; ...&#x27;</span>.<span class="built_in">format</span>(value1, value1...))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;value1&#125;</span> <span class="subst">&#123;value1&#125;</span> ...&#x27;</span>)</span><br><span class="line"><span class="comment"># 输出到文件</span></span><br><span class="line">f = <span class="built_in">open</span>(<span class="string">&#x27;text.txt&#x27;</span>, <span class="string">&#x27;w&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;hhh&#x27;</span>, file=f)</span><br><span class="line"><span class="comment"># 输出不自动换行</span></span><br><span class="line"><span class="built_in">print</span>(values, end=<span class="string">&quot;&quot;</span>)</span><br><span class="line"><span class="comment"># 输出带分隔符</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>, sep=<span class="string">&quot;-&quot;</span>)</span><br></pre></td></tr></table></figure><ul><li><p>格式控制符</p><figure class="highlight py"><table><tr><td class="code"><pre><span class="line">%[(name)][flags][width][.precision]typecode  <span class="comment"># []表示可选 </span></span><br></pre></td></tr></table></figure><p>1) (name) : 选择指定的名称对应的值</p>   <figure class="highlight python"><table><tr><td class="code"><pre><span class="line">englishSc = <span class="number">100</span></span><br><span class="line">mathSC = <span class="number">60</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;数学成绩 ：%(ms)d, 英语成绩：%(es)d&#x27;</span> % (&#123;<span class="string">&#x27;es&#x27;</span>: englishSc, <span class="string">&#x27;ms&#x27;</span>: mathSC&#125;))</span><br></pre></td></tr></table></figure><p>2) flags : </p><ul><li>空：表示右对齐</li><li>-：-表示左对齐</li><li>空格：‘ ’表示一个空格，在正数左侧填充一个空格，与负数对齐</li><li>0：表示用0填充</li></ul><p>3) width：表示显示宽度</p><p>4) <strong>.precision</strong>: 表示小数点后精度</p><p>5) typecode</p><ul><li><p>数值</p><p>| 格式符 |                             含义                             |<br>| :——: | :—————————————————————————————: |<br>|  i/d   |                  将整数、浮点数转化成十进制                  |<br>|   o    |                      将整数转化成八进制                      |<br>|   x    |                     将整数转化成十六进制                     |<br>|   e    |                将整数、浮点数转换成科学计数法                |<br>|   E    |                将整数、浮点数转换成科学计数法                |<br>|   f    |    将整数、浮点数转换成科学计数法（默认保留小数点后6位）     |<br>|   F    |    将整数、浮点数转换成科学计数法（默认保留小数点后6位）     |<br>|   g    | 自动调整将整数、浮点数转换成浮点型或科学计数法（超过6位数用科学计数法） |<br>|   G    | 自动调整将整数、浮点数转换成浮点型或科学计数法（超过6位数用科学计数法） |</p></li><li><p>字符串</p><p>| 格式符 |                             含义                             |<br>| :——: | :—————————————————————————————: |<br>|   s    |               获取传入对象的_str_方法的返回值                |<br>|   r    |               获取传入对象的_repr_方法的返回值               |<br>|   c    | 整数：将数字转换成unicode对应的值  字符：将字符添加到指定为位置 |</p></li></ul></li></ul><p>注：没有将整数转为二进制，即%b; %%表示打印%</p><h3 id="8-py分支"><a href="#8-py分支" class="headerlink" title="8.py分支"></a>8.py分支</h3><h4 id="8-1-if分支"><a href="#8-1-if分支" class="headerlink" title="8.1 if分支"></a>8.1 if分支</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 单分支</span></span><br><span class="line"><span class="keyword">if</span> 条件:</span><br><span class="line">    代码块</span><br><span class="line"><span class="comment"># 双分支</span></span><br><span class="line"><span class="keyword">if</span> 条件:</span><br><span class="line">    代码块</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    代码块</span><br><span class="line">    </span><br><span class="line"><span class="comment">#if-else可以嵌套</span></span><br><span class="line"><span class="keyword">if</span> 条件:</span><br><span class="line">    <span class="keyword">if</span> 条件:</span><br><span class="line">    代码块</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        代码块</span><br><span class="line">        .</span><br><span class="line">        .</span><br><span class="line">        .</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="keyword">if</span> 条件:</span><br><span class="line">    代码块</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        代码块</span><br><span class="line">        .</span><br><span class="line">        .</span><br><span class="line">        .</span><br><span class="line"><span class="comment"># 上面代码可阅读性差，可以使用多分支</span></span><br><span class="line"><span class="keyword">if</span> 条件:</span><br><span class="line">    代码块</span><br><span class="line"><span class="keyword">elif</span> 条件:</span><br><span class="line">    代码块</span><br><span class="line"><span class="keyword">elif</span> 条件:</span><br><span class="line">    代码块</span><br><span class="line">    ...</span><br></pre></td></tr></table></figure><p>注：python没有switch语句</p><h3 id="9-循环"><a href="#9-循环" class="headerlink" title="9.循环"></a>9.循环</h3><ul><li><p>while</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">while</span> 条件体:</span><br><span class="line">条件满足的代码块</span><br><span class="line"><span class="comment"># 没有dowhile，而且有break语句else就不会执行</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    条件不满足代码块</span><br></pre></td></tr></table></figure></li></ul><ul><li><p>for</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 与java增强for循环相同</span></span><br><span class="line"><span class="comment"># 变量不用先前声明</span></span><br><span class="line"><span class="keyword">for</span> 变量名 <span class="keyword">in</span> 列表、字符串等:</span><br><span class="line">    条件满足循环体</span><br><span class="line"><span class="comment"># 没有dowhile，而且有break语句else就不会执行</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">     条件不满足循环体</span><br></pre></td></tr></table></figure></li><li><p>break: 打断本次循环，退出循环</p></li><li>continue ： 结束本次循环，继续进入下一次循环</li><li>pass: 占位语句，空语句，保持程序结构完整性</li></ul><p>注：rang(a, b)函数 —》[1,b-1]</p><h3 id="10-时间日历"><a href="#10-时间日历" class="headerlink" title="10.时间日历"></a>10.时间日历</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取时间戳</span></span><br><span class="line">res = time.time()</span><br><span class="line">years = res / (<span class="number">365</span> * <span class="number">24</span> * <span class="number">60</span> * <span class="number">60</span>) + <span class="number">1970</span></span><br><span class="line"><span class="built_in">print</span>(res)</span><br><span class="line"><span class="built_in">print</span>(years)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取时间元组，可以不传人参数，默认当前时间元组</span></span><br><span class="line">res = time.localtime(<span class="number">1564727544.8498905</span>)</span><br><span class="line"><span class="built_in">print</span>(res)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 时间戳获取格式化时间</span></span><br><span class="line">t = time.time()</span><br><span class="line"><span class="comment"># 格式化时间</span></span><br><span class="line">res = time.ctime(t)</span><br><span class="line"><span class="built_in">print</span>(res)</span><br><span class="line"><span class="comment"># 默认当前时间戳</span></span><br><span class="line">res3 = time.ctime()</span><br><span class="line"><span class="built_in">print</span>(res3)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 时间元组获取格式化时间</span></span><br><span class="line">time_tuple = time.localtime()</span><br><span class="line"><span class="comment"># 格式化时间</span></span><br><span class="line">res1 = time.asctime(time_tuple)</span><br><span class="line"><span class="built_in">print</span>(res1)</span><br><span class="line"><span class="comment"># 默认当前时间元组</span></span><br><span class="line">res2 = time.asctime()</span><br><span class="line"><span class="built_in">print</span>(res2)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 时间元组--》格式化日期 </span></span><br><span class="line"><span class="comment"># 2022-10-03 09:48:37</span></span><br><span class="line"><span class="comment"># format_time = time.strftime(&quot;%Y-%m-%d %H:%M:%S&quot;, time.localtime())</span></span><br><span class="line"><span class="comment"># 22-10-03 09:49:13</span></span><br><span class="line">format_time = time.strftime(<span class="string">&quot;%y-%m-%d %H:%M:%S&quot;</span>, time.localtime())</span><br><span class="line"><span class="built_in">print</span>(format_time)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 格式化时间--》时间元组  time.strptime(日期字符串, 格式符字符串)</span></span><br><span class="line"><span class="comment"># time.struct_time(tm_year=2022, tm_mon=10, tm_mday=3, tm_hour=10, tm_min=3, tm_sec=41, tm_wday=0, tm_yday=276, tm_isdst=-1)</span></span><br><span class="line">pt = time.strptime(<span class="string">&quot;2022-10-03 10:03:41&quot;</span>, <span class="string">&quot;%Y-%m-%d %H:%M:%S&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(pt)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过时间元组时间戳</span></span><br><span class="line">time_mktime = time.mktime(pt)</span><br><span class="line"><span class="built_in">print</span>(time_mktime)  </span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取当前cpu时间</span></span><br><span class="line"><span class="comment"># python3.8后不支持time.clock(),使用time.perf_counter()代替</span></span><br><span class="line"><span class="comment"># startClock = time.clock()</span></span><br><span class="line">startClock = time.perf_counter()</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">1000</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"><span class="comment"># endClock = time.clock()</span></span><br><span class="line">endClock = time.perf_counter()</span><br><span class="line"><span class="built_in">print</span>(endClock-startClock)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 休眠时间，让线程暂停secs秒  time.sleep(secs)</span></span><br><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">    format_time = time.strftime(<span class="string">&quot; %Y-%m-%d  %H:%M:%S &quot;</span>, time.localtime())</span><br><span class="line">    <span class="built_in">print</span>(format_time)</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line"><span class="keyword">import</span> calendar</span><br><span class="line"><span class="comment"># 时间日历</span></span><br><span class="line"><span class="built_in">print</span>(calendar.month(<span class="number">2022</span>, <span class="number">10</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> datetime</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取当天日期</span></span><br><span class="line">datetime_now = datetime.datetime.now()</span><br><span class="line"><span class="built_in">print</span>(datetime_now, <span class="built_in">type</span>(datetime_now))</span><br><span class="line"><span class="built_in">print</span>(datetime.datetime.today())</span><br><span class="line"><span class="comment"># 单独获取年月日时分秒</span></span><br><span class="line"><span class="built_in">print</span>(datetime_now.year)</span><br><span class="line"><span class="built_in">print</span>(datetime_now.month)</span><br><span class="line"><span class="built_in">print</span>(datetime_now.day)</span><br><span class="line"><span class="built_in">print</span>(datetime_now.hour)</span><br><span class="line"><span class="built_in">print</span>(datetime_now.minute)</span><br><span class="line"><span class="built_in">print</span>(datetime_now.second)</span><br><span class="line"></span><br><span class="line">t = datetime.datetime.today()</span><br><span class="line"><span class="comment"># 计算n天后的日期</span></span><br><span class="line"><span class="comment"># res = t + datetime.timedelta(days=7)</span></span><br><span class="line">res = t + datetime.timedelta(days=-<span class="number">7</span>)</span><br><span class="line"><span class="built_in">print</span>(t, res)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 时间间隔</span></span><br><span class="line">first = datetime.datetime(<span class="number">2020</span>, <span class="number">12</span>, <span class="number">26</span>, <span class="number">10</span>, <span class="number">30</span>, <span class="number">10</span>)</span><br><span class="line">second = datetime.datetime(<span class="number">2020</span>, <span class="number">12</span>, <span class="number">27</span>, <span class="number">10</span>, <span class="number">30</span>, <span class="number">10</span>)</span><br><span class="line">delta = second - first</span><br><span class="line"><span class="comment"># datetime.timedelta 时间间隔类型</span></span><br><span class="line"><span class="built_in">print</span>(delta, <span class="built_in">type</span>(delta))</span><br><span class="line"><span class="comment"># 对应的秒数</span></span><br><span class="line"><span class="built_in">print</span>(delta.total_seconds())</span><br></pre></td></tr></table></figure><ul><li>日期时间格式符</li></ul><div class="table-container"><table><thead><tr><th style="text-align:center">符号</th><th style="text-align:left">说明</th></tr></thead><tbody><tr><td style="text-align:center">%a</td><td style="text-align:left">当前区域设置下星期简写，如星期二Tue。</td></tr><tr><td style="text-align:center">%A</td><td style="text-align:left">当前区域设置下星期全名，如星期二Tuesday。</td></tr><tr><td style="text-align:center">%b</td><td style="text-align:left">当前区域设置下月份简写，如九月Sep。</td></tr><tr><td style="text-align:center">%B</td><td style="text-align:left">当前区域设置下月份全名，如九月September。</td></tr><tr><td style="text-align:center">%c</td><td style="text-align:left">当前区域设置下的日期和时间表示。</td></tr><tr><td style="text-align:center">%C</td><td style="text-align:left">世纪，如2019年，21世纪，则返回20。</td></tr><tr><td style="text-align:center">%d</td><td style="text-align:left">十进制数字表示的月份的某一天，范围[01,31]。</td></tr><tr><td style="text-align:center">%D</td><td style="text-align:left">日期，等效于“%m/%d/%y”（美国格式），如“09/03/19”</td></tr><tr><td style="text-align:center">%e</td><td style="text-align:left">十进制数字表示的月份的某一天，范围[1,31]。如果小时10，则数字前用一个填充一个空格。</td></tr><tr><td style="text-align:center">%F</td><td style="text-align:left">ISO 8601格式的完整日期，等效于“%Y-%m-%d”，如“2019-09-03”。</td></tr><tr><td style="text-align:center">%g</td><td style="text-align:left">ISO周数对应的不包含世纪的年份，等效于“%y”，除非ISO周数属于前一年或后一年，则使用前一年或后一年，范围[00,99]。</td></tr><tr><td style="text-align:center">%G</td><td style="text-align:left">ISO周数对应的年份，等效于“%Y”，除非ISO周数属于前一年或后一年，则使用前一年或后一年，范围[0000,9999]。</td></tr><tr><td style="text-align:center">%h</td><td style="text-align:left">等效于“%b”。</td></tr><tr><td style="text-align:center">%j</td><td style="text-align:left">十进制表示的在一天中的天数，范围[001,366]。</td></tr><tr><td style="text-align:center">%m</td><td style="text-align:left">十进制表示的月份，范围[01,12]。</td></tr><tr><td style="text-align:center">%u</td><td style="text-align:left">十进制表示的星期，范围[1-7]。周一为一周的第一天。周一为1，依次递增。</td></tr><tr><td style="text-align:center">%U</td><td style="text-align:left">十进制表示的一年中的周数，[00,53]。星期日为一周的第一天，新年第一个星期日之前的所有日子都视为第0周。</td></tr><tr><td style="text-align:center">%V</td><td style="text-align:left">十进制表示的一年中的ISO周数，[01,53]。星期一为一周的第一天，如果包含1月1日的一周在新的一年里有四天或四天以上，则认为这周是第一周，否则就是前一年的第53周，下一周是新年的第一周。</td></tr><tr><td style="text-align:center">%w</td><td style="text-align:left">十进制表示的星期，范围[0-6]。周日为一周的第一天。周日为0，依次递增。</td></tr><tr><td style="text-align:center">%W</td><td style="text-align:left">十进制表示的一年中的周数，[00,53]。星期一为一周的第一天，新年第一个星期一之前的所有日子都视为第0周。</td></tr><tr><td style="text-align:center">%x</td><td style="text-align:left">按当前区域设置下的日期格式，如“09/03/19”。</td></tr><tr><td style="text-align:center">%y</td><td style="text-align:left">年份的后两位，范围[00,99]。</td></tr><tr><td style="text-align:center">%Y</td><td style="text-align:left">年份，范围[0000,9999]。</td></tr><tr><td style="text-align:center">%H</td><td style="text-align:left">十进制数字表示的小时（24小时制），范围[00,23]。</td></tr><tr><td style="text-align:center">%I（大写i）</td><td style="text-align:left">十进制数字表示的小时（12小时制），范围[01,12]。</td></tr><tr><td style="text-align:center">%M</td><td style="text-align:left">分钟，范围[00,59]。</td></tr><tr><td style="text-align:center">%p</td><td style="text-align:left">本地区域设置下等价于“AM”或“PM”，在许多地区是空字符串。中午视为“PM”，午夜视为“AM”。</td></tr><tr><td style="text-align:center">%r</td><td style="text-align:left">本地区域设置下12小时制时间，如02:15:11 PM。</td></tr><tr><td style="text-align:center">%R</td><td style="text-align:left">24小时制的时和分，等效于“%H%M”，如“14:16”。</td></tr><tr><td style="text-align:center">%S</td><td style="text-align:left">十进制数字表示的秒，范围[00,61]。60在表示闰秒的时间戳中有效，61是出于历史原因而支持的。</td></tr><tr><td style="text-align:center">%T</td><td style="text-align:left">24小时制的时分秒，等效于“%H:%M:%S”。</td></tr><tr><td style="text-align:center">%X</td><td style="text-align:left">按当前区域设置下的日期格式，如“02:20:24 PM”。</td></tr><tr><td style="text-align:center">%z</td><td style="text-align:left">表示与UTC/GMT的正或负时差的时区偏移量，格式为+HHMM或-HHMM，其中H表示小时数，M表示分钟数，范围是[-23:59,+23:59]。</td></tr><tr><td style="text-align:center">%Z</td><td style="text-align:left">时区名。没有时区则返回空字符。</td></tr></tbody></table></div><h3 id="11-函数"><a href="#11-函数" class="headerlink" title="11.函数"></a>11.函数</h3><ul><li><p>调用：先定义后调用，类似c语言，不同于java（调用的代码可以在方法前）</p></li><li><p>作用：方便代码重用；分解任务，简化程序逻辑；使代码更加模块化</p></li><li><p>定义：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">函数定义方式一:</span></span><br><span class="line"><span class="string">def 函数名(形式参数名列表):</span></span><br><span class="line"><span class="string">    代码块</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">注意，参数列表不是数据类型的列表</span></span><br><span class="line"><span class="string">函数调用:</span></span><br><span class="line"><span class="string">方式一:</span></span><br><span class="line"><span class="string">函数名(实际参数列表)</span></span><br><span class="line"><span class="string">实际参数列表的参数与形式参数的列表一一对应</span></span><br><span class="line"><span class="string">此时的参数列表可以写一个类似元组去掉括号，例如 函数名(参数1, 参数2, 参数3, 参数4, 参数5,...)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">方式二:</span></span><br><span class="line"><span class="string">函数名(实际参数名=参数的值,...)   也可叫关键字参数：键值对</span></span><br><span class="line"><span class="string">实际参数列表的参数与形式参数的列表不需要位置上一一对应，只需要参数名对应即可，例如mysum(num2=5, num1=2)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></span><br><span class="line"><span class="string">函数定义方式二: *args代表的接收一个元组</span></span><br><span class="line"><span class="string">def 函数名(*形式参数名)</span></span><br><span class="line"><span class="string">    代码块</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">函数调用:</span></span><br><span class="line"><span class="string">函数名(实际参数列表)</span></span><br><span class="line"><span class="string">实际参数列表的参数与形式参数的列表一一对应</span></span><br><span class="line"><span class="string">此时的参数列表可以写一个元组，此时元组括号必须省略 ，例如 函数名(参数1, 参数2, 参数3, 参数4, 参数5)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</span></span><br><span class="line"><span class="string">函数定义方式三: **args代表的接收一个字典</span></span><br><span class="line"><span class="string">def 函数名(**形式参数名)</span></span><br><span class="line"><span class="string">    代码块</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">函数调用:</span></span><br><span class="line"><span class="string">方式一:</span></span><br><span class="line"><span class="string">函数名(实际参数列表)</span></span><br><span class="line"><span class="string">实际参数列表的参数与形式参数的列表一一对应</span></span><br><span class="line"><span class="string">此时的参数列表是类似字典，此时字典&#123;&#125;必须省略，冒号用等号代替，参数名称没有引号，例如 函数名(参数名称1=参数1, 参数名称2=参数2, 参数名称3=参数3, ...)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li><li><p>参数拆包：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">mySum</span>(<span class="params">a, b, c, d</span>):</span><br><span class="line">    <span class="built_in">print</span>(a + b + c + d)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">myFun</span>(<span class="params">*args</span>):</span><br><span class="line">    <span class="built_in">print</span>(args)</span><br><span class="line">    <span class="comment"># 拆包</span></span><br><span class="line">    <span class="built_in">print</span>(*args)</span><br><span class="line">    mySum(*args)</span><br><span class="line">    mySum(args[<span class="number">0</span>], args[<span class="number">1</span>], args[<span class="number">2</span>], args[<span class="number">3</span>])</span><br><span class="line">    <span class="comment"># 此时只有a能接收值，且为元组，报错</span></span><br><span class="line">    mySum(args)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">myFun(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mySum</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="built_in">print</span>(a + b)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test</span>(<span class="params">**kwargs</span>):</span><br><span class="line">    <span class="built_in">print</span>(kwargs, <span class="built_in">type</span>(kwargs))</span><br><span class="line">    <span class="comment"># 拆包操作</span></span><br><span class="line">    <span class="comment"># 无法打印，报错</span></span><br><span class="line">    <span class="comment"># print(**kwargs)</span></span><br><span class="line">    <span class="comment"># 同理一个字典传参，b没有接收值报错</span></span><br><span class="line">    <span class="comment"># mySum(kwargs)</span></span><br><span class="line">    mySum(**kwargs)</span><br><span class="line">    </span><br><span class="line"><span class="comment">#必须传a，b不然不错，即传递对应的名称才能正确的拆包传参</span></span><br><span class="line">test(a=<span class="number">15</span>, b=<span class="number">12</span>)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">参数装包：把传递进来的参数包装成一个集合</span></span><br><span class="line"><span class="string">参数拆包：把集合参数再次分解成单独的个体</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li><li><p>缺省参数：</p><p>1） 场景：使用一个函数，使用某个数据的一个固定值或者主功能之外的小功能实现</p><p>2） 定义：def 函数名(变量名1=默认值1, 变量名2=默认值2, …):</p><p>​                  函数体中即使没有传参，也可以使用，但是使用的是默认值</p><p>3） 使用：函数名(变量1, 变量2, …)    缺省参数可以不写，为默认值</p></li><li><p>参数传递：</p><p>1）值传递：只传递值的副本，不传递地址(引用)，修改值的副本对原参数值没有影响</p><p>2）引用传递(地址传递)：通过传递过来的地址可以操作原参数</p><p><strong>注意：python只有引用传递，如果数据类型是可变类型，可以改变原件，如果数据类型是不可变类型，不能改变原件！</strong></p></li><li><p>函数返回值：</p><p>1） 场景：使用一个函数处理数据，需要获取数据的处理结果</p><p>2） 定义：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">函数名</span>(<span class="params">参数列表</span>):</span><br><span class="line">函数体</span><br><span class="line">    <span class="keyword">return</span> 返回值</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">只能返回一次，因为<span class="keyword">return</span>后函数执行完毕，不会向下执行</span><br><span class="line">如果返回多个数据，包装成一个集合返回，可以返回列表、字典、元祖等等</span><br></pre></td></tr></table></figure></li><li><p>函数的使用描述：</p><p>1） 场景：编写三方函数，方便别人使用，添加函数的功能和使用方式等描述在函数体最上面</p><p>2） 定义：使用双引号引起来注释</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">函数名</span>(<span class="params">参数列表</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">    帮助信息</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line">函数体</span><br></pre></td></tr></table></figure><p>3）一般函数的使用描述</p><ul><li>函数的功能</li><li>参数的含义、类型、是否可以省略、默认值</li><li>返回值含义、类型</li></ul><p>4） 查看函数帮助文档</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="built_in">help</span>(函数名)</span><br><span class="line"><span class="comment"># 注意函数名后面没有括号</span></span><br></pre></td></tr></table></figure></li></ul><h4 id="11-1-偏函数-有点想java的重载"><a href="#11-1-偏函数-有点想java的重载" class="headerlink" title="11.1 偏函数(有点想java的重载)"></a>11.1 偏函数(有点想java的重载)</h4><p>1） 场景：编写较多参数的函数时，如果某些参数是一个固定值，为了简化使用，可以创建一个新函数，指定使用的函数的某个参数为某个固定值，这个新函数就是<strong>偏函数</strong>。</p><p>2） 语法：</p><ul><li><p>方式一：自己写一个新的</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">mySum</span>(<span class="params">a, b, c, d=<span class="number">1</span></span>):</span><br><span class="line">    <span class="built_in">print</span>(a + b + c + d)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 偏函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mySum1</span>(<span class="params">a, b, c=<span class="number">1</span>, d=<span class="number">2</span></span>):</span><br><span class="line">    mySum(a, b, c, d)</span><br><span class="line"></span><br><span class="line">mySum1(<span class="number">1</span>, <span class="number">2</span>)</span><br></pre></td></tr></table></figure></li><li><p>方式二：借助functools模块的partial函数</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> functools</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mySum</span>(<span class="params">a, b, c, d=<span class="number">1</span></span>):</span><br><span class="line">    <span class="built_in">print</span>(a + b + c + d)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 偏函数</span></span><br><span class="line">newFunc = functools.partial(mySum, c=<span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(newFunc, <span class="built_in">type</span>(newFunc))</span><br><span class="line"><span class="comment"># 利用functools.partial(mySum, c=5)生成的偏函数不能多写参数，会报错</span></span><br><span class="line"><span class="comment"># newFunc(1, 2, 3, 4)</span></span><br><span class="line">newFunc(<span class="number">1</span>, <span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 场景</span></span><br><span class="line">numStr = <span class="string">&quot;1000010&quot;</span></span><br><span class="line"><span class="comment"># 二进制转换成十进制</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">int</span>(numStr, base=<span class="number">2</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用偏函数，不用重复写base参数</span></span><br><span class="line">int2 = functools.partial(<span class="built_in">int</span>, base=<span class="number">2</span>)</span><br><span class="line"><span class="built_in">print</span>(int2(numStr))</span><br></pre></td></tr></table></figure></li></ul><h4 id="11-2-高阶函数"><a href="#11-2-高阶函数" class="headerlink" title="11.2 高阶函数"></a>11.2 高阶函数</h4><p>1） 概念：当一个函数A的参数，接收的又是另一个函数时，则把这个函数A称为是<strong>高阶函数</strong>。例如sorted函数</p><p>2） 语法：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 高阶函数</span></span><br><span class="line">l = [&#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd1&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">15</span>&#125;, &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd4&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">125</span>&#125;, &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd2&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">25</span>&#125;,</span><br><span class="line">     &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd3&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>&#125;, &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd5&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">14</span>&#125;]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># def getKey(dic):</span></span><br><span class="line"><span class="comment">#      return dic[&quot;name&quot;]</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># l1 = sorted(l, key=getKey)</span></span><br><span class="line"><span class="comment"># print(l1)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义高阶函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">calculate</span>(<span class="params">num1, num2, calculateFunc</span>):</span><br><span class="line">    <span class="keyword">return</span> calculateFunc(num1, num2)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">addFunc</span>(<span class="params">num1, num2</span>):</span><br><span class="line">    <span class="keyword">return</span> num1 + num2</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">subFunc</span>(<span class="params">num1, num2</span>):</span><br><span class="line">    <span class="keyword">return</span> num1 - num2</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(calculate(<span class="number">3</span>, <span class="number">2</span>, addFunc))</span><br><span class="line"><span class="built_in">print</span>(calculate(<span class="number">3</span>, <span class="number">2</span>, subFunc))</span><br></pre></td></tr></table></figure><h4 id="11-3-返回函数"><a href="#11-3-返回函数" class="headerlink" title="11.3 返回函数"></a>11.3 返回函数</h4><p>1） 概念：一个函数的内部，它的返回值数据是另一个函数，把这样的操作称为<strong>返回函数</strong>。</p><p>2） 语法：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 返回函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">getFunc</span>(<span class="params">flag</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">getAdd</span>(<span class="params">num1, num2, num3</span>):</span><br><span class="line">        <span class="keyword">return</span> num1 + num2 + num3</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">getSub</span>(<span class="params">num1, num2, num3</span>):</span><br><span class="line">        <span class="keyword">return</span> num1 - num2 - num3</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 根据flag值判断返回哪一个函数</span></span><br><span class="line">    <span class="keyword">if</span> flag == <span class="string">&quot;+&quot;</span>:</span><br><span class="line">        <span class="keyword">return</span> getAdd</span><br><span class="line">    <span class="keyword">elif</span> flag == <span class="string">&quot;-&quot;</span>:</span><br><span class="line">        <span class="keyword">return</span> getSub</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">func = getFunc(<span class="string">&quot;+&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(func, <span class="built_in">type</span>(func))</span><br><span class="line"><span class="built_in">print</span>(func(<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>))</span><br></pre></td></tr></table></figure><h4 id="11-4-匿名函数-lambda函数"><a href="#11-4-匿名函数-lambda函数" class="headerlink" title="11.4 匿名函数(lambda函数)"></a>11.4 匿名函数(lambda函数)</h4><p>1） 概念：没有名字的函数。</p><p>2） 语法：<strong>lambda 参数1, 参数2, …: 表达式</strong></p><p>3） 限制：只能写一个表达式，<strong>不能直接return</strong>；表达式的结果就是返回值；只适用于简单的操作处理。</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 匿名函数</span></span><br><span class="line">res = (<span class="keyword">lambda</span> x, y: x + y)(<span class="number">1</span>, <span class="number">2</span>)</span><br><span class="line"><span class="built_in">print</span>(res)</span><br><span class="line"></span><br><span class="line">func = <span class="keyword">lambda</span> x, y: x + y</span><br><span class="line"><span class="built_in">print</span>(func(<span class="number">1</span>, <span class="number">2</span>))</span><br><span class="line"></span><br><span class="line">l = [&#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd1&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">15</span>&#125;, &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd4&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">125</span>&#125;, &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd2&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">25</span>&#125;,</span><br><span class="line">     &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd3&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">18</span>&#125;, &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;ssd5&quot;</span>, <span class="string">&quot;age&quot;</span>: <span class="number">14</span>&#125;]</span><br><span class="line"></span><br><span class="line"><span class="comment"># def getKey(dic):</span></span><br><span class="line"><span class="comment">#      return dic[&quot;name&quot;]</span></span><br><span class="line"></span><br><span class="line">l1 = <span class="built_in">sorted</span>(l, key=<span class="keyword">lambda</span> dic: dic[<span class="string">&quot;age&quot;</span>])</span><br><span class="line"><span class="built_in">print</span>(l1)</span><br></pre></td></tr></table></figure><h4 id="11-5-闭包-Closure"><a href="#11-5-闭包-Closure" class="headerlink" title="11.5 闭包(Closure)"></a>11.5 闭包(Closure)</h4><p>1） 概念：在函数嵌套的前提下，内层函数引用了外层函数的变量(包括参数)，外层函数又把内层函数当作返回值返回，这个内层函数+所引用的外层变量，称为<strong>闭包</strong>。</p><p>2） 语法：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 闭包函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">func1</span>():</span><br><span class="line">    a = <span class="number">100</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">func2</span>():</span><br><span class="line">        <span class="built_in">print</span>(a)</span><br><span class="line">    <span class="keyword">return</span> func2</span><br><span class="line"></span><br><span class="line"><span class="comment"># 得到func2</span></span><br><span class="line">newFunc = func1()</span><br><span class="line"><span class="comment"># 调用内部函数</span></span><br><span class="line">newFunc()</span><br></pre></td></tr></table></figure><p>3） 应用场景：外层函数，根据不同的参数生成不同功能的内层函数 </p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"># 案例：生成分割线</span><br><span class="line">def line_config(content, length):</span><br><span class="line">    def line():</span><br><span class="line">        print(&quot;-&quot; * (length // 2) + content + &quot;-&quot; * (length // 2))</span><br><span class="line"></span><br><span class="line">    return line</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">f = line_config(&quot;闭包函数&quot;, 100)</span><br><span class="line">f()</span><br></pre></td></tr></table></figure><p>4） 注意事项</p><ul><li><p>闭包中如果想要修改引用的外层变量，需要使用nonlocal关键字修饰变量，不能同时赋值，先修饰然后赋值，没有加关键字，就是闭包内新定义的变量</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># external and internal</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">external_func</span>():</span><br><span class="line">    num = <span class="number">10</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">internal_func</span>():</span><br><span class="line">        <span class="comment"># nonlocal关键字 非局部的</span></span><br><span class="line">        <span class="keyword">nonlocal</span> num</span><br><span class="line">        num = <span class="number">666</span></span><br><span class="line">        <span class="built_in">print</span>(num)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 没有加nonlocal 10</span></span><br><span class="line">    <span class="built_in">print</span>(num)</span><br><span class="line">    internal_func()</span><br><span class="line">    <span class="comment"># 没有加nonlocal 10</span></span><br><span class="line">    <span class="built_in">print</span>(num)</span><br><span class="line">    <span class="keyword">return</span> internal_func</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">func = external_func()</span><br><span class="line">func()</span><br></pre></td></tr></table></figure></li><li><p>闭包内引用了一个后期会发生变化的变量是需要注意</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 闭包注意事项二</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">external_func</span>():</span><br><span class="line">    num = <span class="number">10</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">internal_func</span>():</span><br><span class="line">        <span class="built_in">print</span>(num)</span><br><span class="line"></span><br><span class="line">    num = <span class="number">100</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> internal_func</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">func = external_func()</span><br><span class="line"><span class="comment"># 函数被调用时才确定内部变量标识对应的值</span></span><br><span class="line"><span class="comment"># 100</span></span><br><span class="line">func()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">external_func1</span>():</span><br><span class="line">    funcs = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">internal_func1</span>():</span><br><span class="line">            <span class="built_in">print</span>(i)</span><br><span class="line"></span><br><span class="line">        funcs.append(internal_func1)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> funcs</span><br><span class="line"> </span><br><span class="line"></span><br><span class="line">func_ = external_func1()</span><br><span class="line"><span class="built_in">print</span>(func_, <span class="built_in">type</span>(func_))</span><br><span class="line"><span class="comment"># 全是3</span></span><br><span class="line">func_[<span class="number">0</span>]()</span><br><span class="line">func_[<span class="number">1</span>]()</span><br><span class="line">func_[<span class="number">2</span>]()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">external_func2</span>():</span><br><span class="line">    funcs = []</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">4</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">internal_func2</span>(<span class="params">num</span>):</span><br><span class="line">            <span class="comment"># 增加内层函数，保持num = i = 1、2、3</span></span><br><span class="line">            <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">                <span class="built_in">print</span>(num)</span><br><span class="line"></span><br><span class="line">            <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line">        funcs.append(internal_func2(i))</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> funcs</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">func2 = external_func2()</span><br><span class="line"><span class="built_in">print</span>(func2, <span class="built_in">type</span>(func2))</span><br><span class="line"><span class="comment"># 1、2、3</span></span><br><span class="line">func2[<span class="number">0</span>]()</span><br><span class="line">func2[<span class="number">1</span>]()</span><br><span class="line">func2[<span class="number">2</span>]()</span><br></pre></td></tr></table></figure></li></ul><h4 id="11-6-装饰器-设计模式"><a href="#11-6-装饰器-设计模式" class="headerlink" title="11.6 装饰器(设计模式)"></a>11.6 装饰器(设计模式)</h4><p>1） 作用：在函数名以及函数体不改变的前提下，给一个函数附加一些额外代码</p><p>2） 案例：</p><ul><li><p>优化前</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 装饰器</span></span><br><span class="line"><span class="comment"># 开放封闭原则：已经写好的代码，尽可能不要修改，如果想新增功能，在原来代码基础上，单独进行扩展</span></span><br><span class="line"><span class="comment"># 单一职责原则：单一功能</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">publish_novels</span>():</span><br><span class="line">    <span class="comment"># print(&quot;login_check&quot;)</span></span><br><span class="line">    login_check()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;发说说&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">publish_pictures</span>():</span><br><span class="line">    <span class="comment"># print(&quot;login_check&quot;)</span></span><br><span class="line">    login_check()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;发图片&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">login_check</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;login_check&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 业务逻辑代码</span></span><br><span class="line">btn = <span class="number">2</span></span><br><span class="line"><span class="keyword">if</span> btn == <span class="number">1</span>:</span><br><span class="line">    <span class="comment"># print(&quot;login_check&quot;)</span></span><br><span class="line">    publish_novels()</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="comment"># print(&quot;login_check&quot;)</span></span><br><span class="line">    publish_pictures()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 方式一：在业务逻辑代码添加登录验证代码，代码冗余度大，维护性能差</span></span><br><span class="line"><span class="comment"># 方式二：在功能函数添加登录验证代码，减少代码重复度,复用性好</span></span><br></pre></td></tr></table></figure></li></ul><ul><li><p>使用装饰器优化后</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">login_check</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;login_check&quot;</span>)</span><br><span class="line">        func()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用@login_check立马执行login_check方法</span></span><br><span class="line"><span class="meta">@login_check</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">publish_novels</span>():</span><br><span class="line">    <span class="comment"># print(&quot;login_check&quot;)</span></span><br><span class="line">    <span class="comment"># login_check()</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;发说说&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># publish_novels = login_check(publish_novels)相当于</span></span><br><span class="line">    <span class="comment"># publish_novels = def inner():</span></span><br><span class="line">    <span class="comment">#                     print(&quot;login_check&quot;)</span></span><br><span class="line">    <span class="comment">#                     func()</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 利用python语法题@函数名代替下式</span></span><br><span class="line"><span class="comment"># publish_novels = login_check(publish_novels)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># print(publish_novels)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@login_check</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">publish_pictures</span>():</span><br><span class="line">    <span class="comment"># print(&quot;login_check&quot;)</span></span><br><span class="line">    <span class="comment"># login_check()</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;发图片&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 利用python语法题@函数名代替下式</span></span><br><span class="line"><span class="comment"># publish_pictures = login_check(publish_pictures)</span></span><br><span class="line"><span class="comment"># print(publish_pictures)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 业务逻辑代码</span></span><br><span class="line">btn = <span class="number">1</span></span><br><span class="line"><span class="keyword">if</span> btn == <span class="number">1</span>:</span><br><span class="line">    <span class="comment"># print(&quot;login_check&quot;)</span></span><br><span class="line">    publish_novels()</span><br><span class="line"><span class="comment"># login_check(publish_novels)</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="comment"># print(&quot;login_check&quot;)</span></span><br><span class="line">    publish_pictures()</span><br><span class="line"><span class="comment"># login_check(publish_pictures)</span></span><br></pre></td></tr></table></figure></li></ul><ul><li><p>装饰器的叠加使用(使用多个注解)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># decorator 装饰器叠加使用，加@decorator方法的注解，从上往下执行</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator_line</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;-&quot;</span> * <span class="number">100</span>)</span><br><span class="line">        func()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator_star</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">100</span>)</span><br><span class="line">        func()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator_line</span></span><br><span class="line"><span class="comment"># content = decorator_line(content)</span></span><br><span class="line"><span class="meta">@decorator_star</span></span><br><span class="line"><span class="comment"># content = decorator_star(content)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">content</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;社会我小谢，人狠话不多&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">content()</span><br></pre></td></tr></table></figure></li><li><p>对有参函数进行装饰</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 对有参函数进行装饰</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">50</span>)</span><br><span class="line">        <span class="built_in">print</span>(args, kwargs)</span><br><span class="line">        <span class="comment"># 拆包</span></span><br><span class="line">        func(*args, **kwargs)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">print_number</span>(<span class="params">num1, num2, num3</span>):</span><br><span class="line">    <span class="built_in">print</span>(num1, num2, num3)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">print_number2</span>(<span class="params">num1</span>):</span><br><span class="line">    <span class="built_in">print</span>(num1)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">print_number(<span class="number">123</span>, <span class="number">666</span>, num3=<span class="number">666</span>)</span><br><span class="line">print_number2(<span class="number">123</span>)</span><br></pre></td></tr></table></figure></li><li><p>对有返回值的函数进行装饰（无论什么场景下，保证函数返回值一致）</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 对有返回值的函数进行装饰</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decorator</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">50</span>)</span><br><span class="line">        <span class="built_in">print</span>(args, kwargs)</span><br><span class="line">        <span class="comment"># 拆包</span></span><br><span class="line">        res = func(*args, **kwargs)</span><br><span class="line">        <span class="keyword">return</span> res</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">print_number</span>(<span class="params">num1, num2, num3</span>):</span><br><span class="line">    <span class="built_in">print</span>(num1, num2, num3)</span><br><span class="line">    <span class="keyword">return</span> num1 + num2 + num3</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@decorator</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">print_number2</span>(<span class="params">num1</span>):</span><br><span class="line">    <span class="built_in">print</span>(num1)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># inner函数必须要有返回值，且与被装饰者返回值一致</span></span><br><span class="line">res1 = print_number(<span class="number">123</span>, <span class="number">666</span>, num3=<span class="number">666</span>)</span><br><span class="line">res2 = print_number2(<span class="number">123</span>)</span><br><span class="line"><span class="built_in">print</span>(res1, res2)</span><br></pre></td></tr></table></figure></li><li><p>通过装饰器的注解加参数获取不同的装饰器</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 获取装饰器，通过char控制获取不同装饰器</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">getDecorator</span>(<span class="params">char</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">decorator</span>(<span class="params">func</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">            <span class="built_in">print</span>(char * <span class="number">50</span>)</span><br><span class="line">            func()</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> decorator</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@getDecorator(<span class="params"><span class="string">&quot;*&quot;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fp</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;中华人民共和国万岁&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">fp()</span><br></pre></td></tr></table></figure></li></ul><h4 id="11-7-生成器"><a href="#11-7-生成器" class="headerlink" title="11.7 生成器"></a>11.7 生成器</h4><p>1） 概念：是一个特殊的迭代器（迭代器的抽象层次更高）</p><p>​        拥有迭代器特性：惰性计算数据，节省内存；能够记录状态，通过next()函数访问下一个状态；具备可迭代特性；</p><p>​        也可以自己实现迭代器</p><p>2） 创建方式一：生成器变量名 = (推导式),即列表推导式的[]改为()</p><p>3） 创建方式二：生成器函数，函数中包含yield语句，函数执行结果就是<strong>生成器</strong></p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># yield，可以阻断当前函数执行，当使用next(generator)或者generator.__next__()函数，让函数继续执行，当执行下一个yield时，又阻断</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;test函数执行&quot;</span>)</span><br><span class="line">    <span class="comment"># 遇到yield，阻断执行</span></span><br><span class="line">    <span class="keyword">yield</span> <span class="number">1</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;a&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">yield</span> <span class="number">2</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;b&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">yield</span> <span class="number">3</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;c&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">yield</span> <span class="number">4</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;d&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">yield</span> <span class="number">5</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;e&quot;</span>)</span><br><span class="line"></span><br><span class="line">    </span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test</span>():</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">9</span>):</span><br><span class="line">        <span class="keyword">yield</span> i</span><br><span class="line">        <span class="comment"># print(&quot;a&quot; + str(i))</span></span><br><span class="line"></span><br><span class="line">g = test()</span><br><span class="line"><span class="built_in">print</span>(g)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(g))</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="comment"># print(g.__next__())</span></span><br></pre></td></tr></table></figure><p>4） send()方法：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">send方法有一个参数，指定的是上一次被挂起的<span class="keyword">yield</span>语句的返回值</span><br><span class="line">相比于.__next__()，可以额外的给<span class="keyword">yield</span>语句传值</span><br><span class="line">注意第一次调用t.send(<span class="literal">None</span>)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;test函数执行&quot;</span>)</span><br><span class="line">    res1 = <span class="keyword">yield</span> <span class="number">1</span> <span class="comment"># &quot;000&quot;</span></span><br><span class="line">    <span class="built_in">print</span>(res1)</span><br><span class="line"></span><br><span class="line">    res2 = <span class="keyword">yield</span> <span class="number">2</span></span><br><span class="line">    <span class="built_in">print</span>(res2)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">g = test()</span><br><span class="line"><span class="comment"># 开启调用函数</span></span><br><span class="line"><span class="built_in">print</span>(g.__next__())</span><br><span class="line"><span class="comment"># print(g.__next__())</span></span><br><span class="line"><span class="comment"># g.__next__(),默认是None,使用g.send(&quot;000&quot;)可以给上一次挂起的yield传值</span></span><br><span class="line"><span class="built_in">print</span>(g.send(<span class="string">&quot;000&quot;</span>))</span><br><span class="line"><span class="built_in">print</span>(g.send(<span class="literal">None</span>))</span><br></pre></td></tr></table></figure><p>5） 关闭生成器</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">g.close()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 遇到return语句，直接终止函数 StopIteration</span></span><br><span class="line"><span class="keyword">return</span> 返回值</span><br><span class="line"></span><br><span class="line"><span class="comment"># 与迭代器一样，生成器只能迭代一次</span></span><br></pre></td></tr></table></figure><h4 id="11-8-递归函数"><a href="#11-8-递归函数" class="headerlink" title="11.8 递归函数"></a>11.8 递归函数</h4><p>1） 概念：函数A内部继续调用A</p><p>2）案例：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 递归求n!</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">recursion</span>(<span class="params">n</span>):</span><br><span class="line">    <span class="keyword">if</span> n == <span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> n * recursion(n - <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(recursion(<span class="number">9</span>))</span><br></pre></td></tr></table></figure><h4 id="11-9-按位置传参数函数"><a href="#11-9-按位置传参数函数" class="headerlink" title="11.9  按位置传参数函数"></a>11.9  按位置传参数函数</h4><p>概念：只能位置传参，不能键值对传参，最后一个是正斜杠/，该参数不用传</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 保证按位置传参且只能传一个</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">new_method</span>(<span class="params">self, /</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;我是新来的，给我一个实例&quot;</span>)</span><br><span class="line"></span><br><span class="line">new_method(<span class="string">&quot;kk&quot;</span>)</span><br></pre></td></tr></table></figure><h4 id="11-10-函数作用域"><a href="#11-10-函数作用域" class="headerlink" title="11.10 函数作用域"></a>11.10 函数作用域</h4><p>1) 变量作用域</p><ul><li>变量的作用范围(可操作范围)：python是静态作用域，变量的作用域源于它在代码中的位置，在不同的位置，可能有不同的命名空间。</li></ul><p>2) 命名空间</p><ul><li>是作用域的体现形式</li><li>不同的具体操作范围</li></ul><p>3) python-LEGB</p><ul><li>L-Local：函数内的命名空间；作用范围：当前整个函数体范围</li><li>E-Enclosing function locals：外部嵌套函数的命名空间；作用范围：闭包函数</li><li>G-Global：全局命名空间；作用范围：当前模块（文件）</li><li>B-Builtin内建模块命名空间；作用范围：所有模块（文件）</li><li>注意：<strong>python没有块级作用域</strong>，比如while、for、if后面的代码块只要执行了，代码块外面可以访问，与javascript类似</li><li>LEGB规则：按照L—&gt;E–-&gt;G–&gt;B 的顺序进行查找</li></ul><ol><li>基于命名空间的常见变量类型</li></ol><ul><li>局部变量：在一个函数内部定义的变量；作用域为函数内部；查看局部变量locals()</li><li>nonlocal关键字仅仅适用于闭包里面函数与外层函数的变量相同的变量操作，单个函数体内使用global关键字，即可修改全局变量的值</li><li>全局变量：在函数外部，文件最外层定义的变量，作用域为整个文件内部；查看全局变量globals()</li><li>注意点 ：<ul><li>结构规范：访问原则从内到外</li><li>全局变量与局部变量重名：获取，就近原则；修改，加global关键字修饰变量再修改</li><li>命名：全局变量一般g_变量名命名</li></ul></li></ul><h3 id="12-python文件I-O操作"><a href="#12-python文件I-O操作" class="headerlink" title="12.python文件I/O操作"></a>12.python文件I/O操作</h3><ol><li><p>文件概念：数据存放的容器</p></li><li><p>文件的作用：持久性的存储数据内容</p></li><li><p>文件组成：</p><ul><li>文件名：同级目录下，不允许同名文件存在</li><li>扩展名：.jpg、.avi、.doc、.java等等</li><li>注意：一般不同的扩展名，对应不同的文件格式；不同的文件格式，有着不同的存储约定，方便程序处理</li></ul></li><li><p>文本内容</p><ul><li>文本文件：.doc、.xls、.txt等等</li><li>二进制文件：图片、视频、音乐等等</li></ul></li><li><p>文件使用流程</p><ul><li><p>打开：open(“文件”, “模式”)，文件指定文件名称，模式控制操作模式，返回文件对象</p><p>模式：</p><p>| 模式  | 含义                                                         |<br>| :—-: | :—————————————————————————————- |<br>|   r   | 以只读方式打开文件(默认文件打开模式)，文件的指针放在文件的开头，注意：文件不存在报错 |<br>|   w   | 以只写方式打开文件，文件的指针放在文件的开头，所以写入新的内容会覆盖原文件的所有内容，注意：文件不存在会自动创建文件 |<br>|   a   | 以追加方式(只写)打开文件，文件的指针放在文件的结尾，所以写入新的内容会新增原文件的结尾，注意：文件不存在会自动创建文件 |<br>| 增加b | rb、wb、ab，如果是二进制文件，则选择此项；如图片、视频、音频等等（b为binary） |<br>| 增加+ | r+、w+、a+、wb+、rb+、ab+，都是以读写模式打开，其他特性基本和+前面的模式一致，但部分操作，有细节区别 |<br>|  r+   | 可读可写打开文件，没有文件 No such file or directory报错；可以读操作，指向文件头，读取全部内容；可以写入，指针指向文件头部，覆盖写入的内容长度，不会全部覆盖；读写同时进行，先读后写，指针先移到读完后的位置，再写入；读写同时进行，先写后读（会等读语句执行后写入），指针移到写完后的位置，若原文件空，读写不到数据，非空，则读到指针后面剩下内容 |<br>|  w+   | 可读可写打开文件，文件不存在，创建文件；打开文件就清空文件，指针指向头部，所以读操作，指向文件头，返回空；可以写入，指针指向文件头部，覆盖原文件全部内容；读写同时进行，先读后写（打开文件就清空了内容），不管先读后写，还是先写后读（执行完写语句不会写入内容，执行完读操作(缓冲区内容到磁盘)才会写入成功），不会读到内容，总结不可读，但是使用读操作不报错 |<br>|  a+   | 可读可写打开文件，文件不存在，创建文件；可以读操作，不管是否存在内容，读取不到内容，返回空；可以写入，指针指向文件尾，追加写入；读写同时进行，不管先读后读（写入到缓冲区，执行完close语句写入磁盘），还是先写后读（执行完读语句写入），不会读到内容，总结不可读，但是使用读操作不报错 |<br>|  rb+  | 可读可写打开文件，文件不存在，创建文件；以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |<br>|  wb+  | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。一般用于非文本文件如图片等。 |<br>|  ab+  | 以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。如果该文件不存在，创建新文件用于读写。 |</p></li><li><p>读写：</p><p>a)定位：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 偏移</span></span><br><span class="line">f.seek(偏移量[, <span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>])</span><br><span class="line"><span class="comment"># 查看文件指针</span></span><br><span class="line">f.tell()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过命令行查看seek帮助文档</span></span><br><span class="line">f = <span class="built_in">open</span>(<span class="string">&quot;py文件操作/a.txt&quot;</span>, <span class="string">&quot;r&quot;</span>)</span><br><span class="line"> <span class="built_in">help</span>(f.seek)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">seek的第二个参数</span></span><br><span class="line"><span class="string">0.文件指针在文件头，偏移量为正</span></span><br><span class="line"><span class="string">1.文件指针在文件中，表示当前位置，有可能偏移量可以为负</span></span><br><span class="line"><span class="string">2.文件指针在文件尾部，偏移量为负</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">注意：文本文件不带&quot;b&quot;seek第二参数只能写0，二进制文件(加b)操作模式下可以为1或2</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>b)读：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">f.read(字节数)</span></span><br><span class="line"><span class="string">    字节数默认是文本内容长度，下标自动移动</span></span><br><span class="line"><span class="string">* f.readline([limit])</span></span><br><span class="line"><span class="string">    读取一行数据，limit限制最大读取字节数</span></span><br><span class="line"><span class="string">f.readlines()</span></span><br><span class="line"><span class="string">    自动将文件按照换行符处理，将处理好的每一行数据组成列表返回</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">* for in (动态加载内存)</span></span><br><span class="line"><span class="string">    1.遍历行列表</span></span><br><span class="line"><span class="string">    2.遍历文件本身(文件对象就是迭代器）</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">判断文件是否可读(容错处理)</span></span><br><span class="line"><span class="string">    file对象.readable()</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">注意：</span></span><br><span class="line"><span class="string">    文件比较大时使用readline方法，按行加载，可节省内存，但相对于其他两个读取方法，性能较低</span></span><br><span class="line"><span class="string">    其他两个方法一次读取全部内容，虽然占用内存，但处理性能比较高</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>c)写：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">file对象.write()</span></span><br><span class="line"><span class="string">返回写入字节的长度</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">判断文件是否可写(容错处理)</span></span><br><span class="line"><span class="string">    file对象.writable()</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li></ul></li></ol><ul><li><p>关闭：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">file对象.close()</span></span><br><span class="line"><span class="string">关闭一个打开的文件</span></span><br><span class="line"><span class="string">可以释放系统资源，会立即清空缓冲区的数据内容到磁盘文件</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">file对象.flush()</span></span><br><span class="line"><span class="string">将缓冲区的数据内容刷新到磁盘文件中</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li></ul><ol><li><p>文件常用操作</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line"><span class="comment"># 重命名文件  os.rename(原, 新)， 没有文件或目录报错</span></span><br><span class="line"><span class="comment"># os.rename(&quot;b.txt&quot;, &quot;one.txt&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 重命名目录</span></span><br><span class="line"><span class="comment"># os.rename(&quot;first&quot;, &quot;one&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 同时修改目录名和文件名  renames()</span></span><br><span class="line"><span class="comment"># os.renames(&quot;one/one.txt&quot;, &quot;two/two.txt&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除文件,不存在报错  remove()</span></span><br><span class="line"><span class="comment"># os.remove(&quot;m52.jpg&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除目录，文件夹非空报错  rmdir()</span></span><br><span class="line"><span class="comment"># os.rmdir(&quot;one&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 只删除two目录</span></span><br><span class="line"><span class="comment"># os.rmdir(&quot;one/two&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 递归删除目录，文件夹非空报错  removedirs()</span></span><br><span class="line"><span class="comment"># os.removedirs(&quot;one/two&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建一级目录 mkdir()</span></span><br><span class="line"><span class="comment"># os.mkdir(&quot;one&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 无法递归创建多级目录，报错</span></span><br><span class="line"><span class="comment"># os.mkdir(&quot;a/b/c&quot;)</span></span><br><span class="line"></span><br><span class="line">os.mkdir(<span class="string">&quot;a&quot;</span>, <span class="number">0o777</span>)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">数字权限模式,windows忽略，可以参照linux的文件权限(读r:4、写w:2、可执行x:1)</span></span><br><span class="line"><span class="string">文件拥有者 八进制第一位数(读r:4、写w:2、可执行x:1)</span></span><br><span class="line"><span class="string">同组用户   八进制第二位数(读r:4、写w:2、可执行x:1)</span></span><br><span class="line"><span class="string">其他用户   八进制第三位数(读r:4、写w:2、可执行x:1)</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 切换默认目录,os.chdir(target目录)，目标目录不存在会报错</span></span><br><span class="line"><span class="comment"># os.chdir(&quot;one&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># open(&quot;ddd.txt&quot;, &quot;w&quot;)</span></span><br><span class="line"><span class="comment"># 获取当前目录 os.getcwd()</span></span><br><span class="line"><span class="comment"># print(os.getcwd())</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取目录内容列表  os.listdir(path) 目录默认是当前目录下(&quot;./&quot;) 返回一个列表</span></span><br><span class="line"><span class="built_in">print</span>(os.listdir(<span class="string">&quot;../&quot;</span>))</span><br></pre></td></tr></table></figure></li><li><p>案例：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 文件复制案例</span></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line">os.chdir(<span class="string">&quot;../file/&quot;</span>)</span><br><span class="line"><span class="comment"># 1.以只读模式打开要复制的文件</span></span><br><span class="line"><span class="comment"># 以追加模式打开副本文件</span></span><br><span class="line"><span class="comment"># 两个文件编码一致，不会乱码</span></span><br><span class="line">source_file = <span class="built_in">open</span>(<span class="string">&quot;poem.txt&quot;</span>, <span class="string">&quot;r&quot;</span>, encoding=<span class="string">&quot;utf-8&quot;</span>)</span><br><span class="line">target_file = <span class="built_in">open</span>(<span class="string">&quot;poem_copy.txt&quot;</span>, <span class="string">&quot;a&quot;</span>, encoding=<span class="string">&quot;utf-8&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2.从原文件中读取内容</span></span><br><span class="line"><span class="comment"># 目标文件写内容</span></span><br><span class="line"><span class="comment"># if source_file.readable():</span></span><br><span class="line"><span class="comment"># content = source_file.read()</span></span><br><span class="line"><span class="comment"># if target_file.writable():</span></span><br><span class="line"><span class="comment"># target_file.write(content)</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">    content = source_file.read(<span class="number">1024</span>)</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(content) == <span class="number">0</span>:</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">    target_file.write(content)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 刷新流</span></span><br><span class="line">target_file.flush()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3.关闭流</span></span><br><span class="line">source_file.close()</span><br><span class="line">target_file.close()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;--------------------------------------------&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="comment"># 创建于扩展名相同目录并移动到该目录下，进行分类</span></span><br><span class="line"><span class="comment"># 获取文件名称列表</span></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> shutil</span><br><span class="line"></span><br><span class="line">path = <span class="string">&quot;../file&quot;</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(path):</span><br><span class="line">    exit()</span><br><span class="line"></span><br><span class="line">os.chdir(path)</span><br><span class="line">file_list = os.listdir(<span class="string">&quot;./&quot;</span>)</span><br><span class="line"><span class="comment"># print(file_list)</span></span><br><span class="line"><span class="comment"># 1 遍历所有文件</span></span><br><span class="line"><span class="keyword">for</span> file_name <span class="keyword">in</span> file_list:</span><br><span class="line">    <span class="comment"># print(file_name)</span></span><br><span class="line">    <span class="comment"># 2 分解文件后缀名</span></span><br><span class="line">    <span class="comment"># 2.1获取最后一个.的索引位置</span></span><br><span class="line">    index = file_name.rfind(<span class="string">&quot;.&quot;</span>)</span><br><span class="line">    <span class="comment"># print(index)</span></span><br><span class="line">    <span class="comment"># 2.2根据这个索引开始截取后续内容</span></span><br><span class="line">    extension = file_name[index + <span class="number">1</span>:]</span><br><span class="line">    <span class="comment"># print(extension)</span></span><br><span class="line">    <span class="keyword">if</span> extension == -<span class="number">1</span>:</span><br><span class="line">        <span class="keyword">continue</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 3 查看一下， 是否存在同名的目录</span></span><br><span class="line">    <span class="comment"># 4 如果不存在这样的目录，创建该名称的目录</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(extension):</span><br><span class="line">        <span class="comment"># 创建</span></span><br><span class="line">        os.mkdir(extension)</span><br><span class="line">    <span class="comment"># 移动</span></span><br><span class="line">    <span class="comment"># 5 目录存在后，移动对应文件</span></span><br><span class="line">    shutil.move(file_name, extension)</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;------------------------------------&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="comment"># 打印文件目录文件夹及文件清单</span></span><br><span class="line"><span class="comment"># 获取文件名称列表</span></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> shutil</span><br><span class="line"></span><br><span class="line"><span class="comment"># path = &quot;../file&quot;</span></span><br><span class="line"><span class="comment"># if not os.path.exists(path):</span></span><br><span class="line"><span class="comment">#     exit()</span></span><br><span class="line"><span class="comment"># listdir = os.listdir(path)</span></span><br><span class="line"><span class="comment"># print(listdir)</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">listFiles</span>(<span class="params"><span class="built_in">dir</span>, f</span>):</span><br><span class="line">    file_list = os.listdir(<span class="built_in">dir</span>)</span><br><span class="line">    <span class="comment"># print(file_list)</span></span><br><span class="line">    <span class="keyword">for</span> file_name <span class="keyword">in</span> file_list:</span><br><span class="line">        new_file_name = <span class="built_in">dir</span> + <span class="string">&quot;/&quot;</span> + file_name</span><br><span class="line">        <span class="comment"># 判断是不是目录</span></span><br><span class="line">        <span class="keyword">if</span> os.path.isdir(new_file_name):</span><br><span class="line">            <span class="comment"># print(new_file_name)</span></span><br><span class="line">            f.write(new_file_name + <span class="string">&quot;\n&quot;</span>)</span><br><span class="line">            <span class="comment"># 是目录，递归</span></span><br><span class="line">            listFiles(new_file_name, f)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="comment"># print(&quot;\t&quot; + file_name)</span></span><br><span class="line">            f.write(<span class="string">&quot;\t&quot;</span> + file_name + <span class="string">&quot;\n&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># print(&quot;&quot;)</span></span><br><span class="line">    f.write(<span class="string">&quot;\n&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">f = <span class="built_in">open</span>(<span class="string">&quot;list.txt&quot;</span>, <span class="string">&quot;a&quot;</span>)</span><br><span class="line">listFiles(<span class="string">&quot;../file&quot;</span>, f)</span><br></pre></td></tr></table></figure></li></ol><h2 id="二、py核心知识点-oop"><a href="#二、py核心知识点-oop" class="headerlink" title="二、py核心知识点(oop)"></a>二、py核心知识点(oop)</h2><ul><li>python面向对象(Object-oriented programming (OOP) )</li></ul><h3 id="1-面向对象基本理论"><a href="#1-面向对象基本理论" class="headerlink" title="1.面向对象基本理论"></a>1.面向对象基本理论</h3><ul><li>面向对象：解决问题时关注的是需要解决问题所需要的的对象，根本是不同具体对象面向过程的封装</li><li>面向过程：解决问题时关注解决问题的每一个步骤(过程)</li><li>类：某一个对象的特征行为的抽象，包特征(属性)和行为(方法)</li><li>实例化对象：拥有某个类的属性和方法，且属性方法得到具体实现</li></ul><h3 id="2-面向对象在python中实现"><a href="#2-面向对象在python中实现" class="headerlink" title="2.面向对象在python中实现"></a>2.面向对象在python中实现</h3><h4 id="2-1-定义一个类-类也是对象，万物皆对象"><a href="#2-1-定义一个类-类也是对象，万物皆对象" class="headerlink" title="2.1  定义一个类(类也是对象，万物皆对象)"></a>2.1  定义一个类(类也是对象，万物皆对象)</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">类名</span>:</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"><span class="comment"># 类名驼峰命名法，与java一致</span></span><br><span class="line"><span class="comment"># 类名也可以作为变量，可以给他赋值</span></span><br></pre></td></tr></table></figure><h4 id="2-2-实例化对象"><a href="#2-2-实例化对象" class="headerlink" title="2.2  实例化对象"></a>2.2  实例化对象</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">对象名 = 类名()</span><br></pre></td></tr></table></figure><h4 id="2-3-属性：某个对象的特性，通过实例化对象来调；而变量是可以改变的量值"><a href="#2-3-属性：某个对象的特性，通过实例化对象来调；而变量是可以改变的量值" class="headerlink" title="2.3  属性：某个对象的特性，通过实例化对象来调；而变量是可以改变的量值"></a>2.3  属性：某个对象的特性，通过实例化对象来调；而变量是可以改变的量值</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">对象(实例)属性(java没有对象属性概念，python有)</span></span><br><span class="line"><span class="string">    * 使对象具有一些属性（增）</span></span><br><span class="line"><span class="string">        1.直接通过对象，动态添加，对象.属性 = 值</span></span><br><span class="line"><span class="string">        2.通过类的初始化方法(构造方法） __init__方法(当我们创建好一个对象后，会自动调用该方法，初始化对象)</span></span><br><span class="line"><span class="string">    * 访问对象的属性（查）</span></span><br><span class="line"><span class="string">        对象.属性</span></span><br><span class="line"><span class="string">        查看对象属性是否添加成功:打印对象.属性,或者获取所有该对象属性，对象.__dict__</span></span><br><span class="line"><span class="string">    * 修改对象的属性（改）</span></span><br><span class="line"><span class="string">        对象.属性 = 新值</span></span><br><span class="line"><span class="string">        修改操作，属性会指向新的空间(不可变类型),可变类型的值会修改值，指向的内存地址不变</span></span><br><span class="line"><span class="string">    * 删除对象的属性（删）</span></span><br><span class="line"><span class="string">        del 对象.属性</span></span><br><span class="line"><span class="string">    * 对象名访问属性，其实是访问对象的__dict__属性指向地址的属性值，可以通过（对象.__dict__ = 字典）给对象设置属性,说明了__dict__属性可以修改</span></span><br><span class="line"><span class="string">        </span></span><br><span class="line"><span class="string">    可以通过对象.__class__ = 类名 来修改所属类</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">类属性(类本身、及根据该类创建的对象都可以共享)</span></span><br><span class="line"><span class="string">    * 使类具有一些属性（增）</span></span><br><span class="line"><span class="string">        1.直接通过类名，动态添加，类名.属性 = 值</span></span><br><span class="line"><span class="string">        2.在类的代码块直接写属性名 = 值</span></span><br><span class="line"><span class="string">    * 访问类的属性（查）</span></span><br><span class="line"><span class="string">        类名.属性</span></span><br><span class="line"><span class="string">        查看类属性是否添加成功:打印 类名.属性,或者获取所有该类属性，类名.__dict__</span></span><br><span class="line"><span class="string">        * python对象属性查找机制，python对象会优先查找对象自身属性，找不到才根据__class__去对象对应的类属性查找</span></span><br><span class="line"><span class="string">    * 修改类的属性（改）</span></span><br><span class="line"><span class="string">        类名.属性 = 新值</span></span><br><span class="line"><span class="string">        修改操作，属性会指向新的空间(不可变类型),可变类型的值会修改值，指向的内存地址不变</span></span><br><span class="line"><span class="string">        * 属于该类创建的对象修改类属性，成为对象自己的属性，属于新增操作，但不会修改类属性</span></span><br><span class="line"><span class="string">    * 删除类的属性（删）</span></span><br><span class="line"><span class="string">        del 类名.属性</span></span><br><span class="line"><span class="string">        不能使用del 对象.属性,会报错，即不能通过对象删除类属性</span></span><br><span class="line"><span class="string">        </span></span><br><span class="line"><span class="string">        </span></span><br><span class="line"><span class="string">通过设置__slots__属性(在类的内部设置)</span></span><br><span class="line"><span class="string">    列表中的元素，即为通过这个类创建出的对象可以添加的对象属性</span></span><br><span class="line"><span class="string">    如果这个类实例出的对象，添加了非列表之内的属性，则会报错</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-4-方法：描述一个目标的行为动作"><a href="#2-4-方法：描述一个目标的行为动作" class="headerlink" title="2.4  方法：描述一个目标的行为动作"></a>2.4  方法：描述一个目标的行为动作</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string"> 方法与普通函数异同：</span></span><br><span class="line"><span class="string">    都封装了一系列行为动作</span></span><br><span class="line"><span class="string">    都可以被调用的之后，执行一系列行为动作</span></span><br><span class="line"><span class="string">    最主要的区别就是：调用方式，方法需要对象调</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">    方法的划分：</span></span><br><span class="line"><span class="string">    * 实例方法</span></span><br><span class="line"><span class="string">        默认第一个参数需要接收到一个实例</span></span><br><span class="line"><span class="string">    * 类方法(加@classmethod注解,原理就是装饰器)</span></span><br><span class="line"><span class="string">        默认第一个参数需要接收到一个类</span></span><br><span class="line"><span class="string">    * 静态方法(加@staticmethod注解)</span></span><br><span class="line"><span class="string">        第一个参数什么都不默认接收</span></span><br><span class="line"><span class="string">    * 注意:</span></span><br><span class="line"><span class="string">       1.划分的依据是：方法的第一个参数必须要接收的数据类型</span></span><br><span class="line"><span class="string">       2.不管是哪一种类型的方法，都是存储在类当中；没有在实例当中的</span></span><br><span class="line"><span class="string">       3.不同类型方法的调用方式不同</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-5-实例方法：可以使用实例属性和类属性-self-属性"><a href="#2-5-实例方法：可以使用实例属性和类属性-self-属性" class="headerlink" title="2.5  实例方法：可以使用实例属性和类属性 self.属性"></a>2.5  实例方法：可以使用实例属性和类属性 self.属性</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">class 类名:</span></span><br><span class="line"><span class="string">    def 方法名(self):</span></span><br><span class="line"><span class="string">        方法体</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">标准调用：</span></span><br><span class="line"><span class="string">    使用实例调用实例方法，不用手动传参，解释器默认将当前实例本身传递过去</span></span><br><span class="line"><span class="string">    注意：至少有一个参数，不然报错，一般形参用self，也可以自定义</span></span><br><span class="line"><span class="string">其他调用：</span></span><br><span class="line"><span class="string">    使用类调用: 类名.方法名(参数列表)</span></span><br><span class="line"><span class="string">    间接调用: 函数名 = 类名.方法名   函数名(参数列表)</span></span><br><span class="line"><span class="string">    本质就是找到函数本身取调用它</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-6-类方法：可以使用类属性-cls-类属性-没有传实例对象参数前提"><a href="#2-6-类方法：可以使用类属性-cls-类属性-没有传实例对象参数前提" class="headerlink" title="2.6  类方法：可以使用类属性 cls.类属性(没有传实例对象参数前提)"></a>2.6  类方法：可以使用类属性 cls.类属性(没有传实例对象参数前提)</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">class 类名:</span></span><br><span class="line"><span class="string">    @classmethod</span></span><br><span class="line"><span class="string">    def 方法名(cls):</span></span><br><span class="line"><span class="string">        方法体</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">类调用：不用手动传递第一个参数，会自动的把调用的类本身给传递过去(一般使用类调用)</span></span><br><span class="line"><span class="string">实例调用：不用手动传递第一个参数，会自动的把调用的对象对应的类给传递过去</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-7-静态方法：可以使用类属性，类名-属性-没有传实例对象参数前提"><a href="#2-7-静态方法：可以使用类属性，类名-属性-没有传实例对象参数前提" class="headerlink" title="2.7  静态方法：可以使用类属性，类名.属性(没有传实例对象参数前提)"></a>2.7  静态方法：可以使用类属性，类名.属性(没有传实例对象参数前提)</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">class 类名:</span></span><br><span class="line"><span class="string">    @staticmethod</span></span><br><span class="line"><span class="string">    def 方法名():</span></span><br><span class="line"><span class="string">        方法体</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">类调用：不用传递参数</span></span><br><span class="line"><span class="string">实例调用：不用传递参数</span></span><br><span class="line"><span class="string">看场景使用什么调用方法</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-8-元类：创建类对象的类（type类，继承于object）"><a href="#2-8-元类：创建类对象的类（type类，继承于object）" class="headerlink" title="2.8  元类：创建类对象的类（type类，继承于object）"></a>2.8  元类：创建类对象的类（type类，继承于object）</h4><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221004214611006.png" alt="类的关系"></p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">另一种创建类方式：使用type创建类</span></span><br><span class="line"><span class="string"> 自定义的类变量 = type(类名, 元组, 字典&#123;属性键值对或方法键值对&#125;)</span></span><br><span class="line"><span class="string">实例 = 自定义的类变量()</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221004221037180.png" alt="image-20221004221037180"></p><h4 id="2-9-类创建流程"><a href="#2-9-类创建流程" class="headerlink" title="2.9  类创建流程"></a>2.9  类创建流程</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">类创建流程：</span></span><br><span class="line"><span class="string">    1. 检测类中是否有明确 __metaclass__属性，有, 则通过指定元类来创建这个类对象</span></span><br><span class="line"><span class="string">    2. 检测父类中是否存在__metaclass__属性，有, 则通过指定元类来创建这个类对象</span></span><br><span class="line"><span class="string">    3. 检测模块中是否存在__metaclass__属性，有, 则通过指定元类来创建这个类对象</span></span><br><span class="line"><span class="string">    4. 通过内置的type这个元类,来创建这个类对象</span></span><br><span class="line"><span class="string">    4. 通过内置的type这个元类,来创建这个类对象</span></span><br><span class="line"><span class="string">场景：1)   拦截类的创建  2)   修改类   3)   返回修改之后的类</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-10-类的描述"><a href="#2-10-类的描述" class="headerlink" title="2.10  类的描述"></a>2.10  类的描述</h4><ul><li>三个双引号对“”“类、方法描述”“”，属性的描述写在类描述里面，具体参考官方文档</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">方式1:</span></span><br><span class="line"><span class="string">使用内置模块pydoc</span></span><br><span class="line"><span class="string">具体步骤</span></span><br><span class="line"><span class="string">    1.查看文档描述</span></span><br><span class="line"><span class="string">        python -m pydoc 模块名称</span></span><br><span class="line"><span class="string">    2.启动本地服务, 浏览文档</span></span><br><span class="line"><span class="string">        python -m pydoc -p 1234</span></span><br><span class="line"><span class="string">        # 自动生成端口号</span></span><br><span class="line"><span class="string">        python -m pydoc -b</span></span><br><span class="line"><span class="string">    3.生成指定模块html文档</span></span><br><span class="line"><span class="string">        python -m pydoc -w 模块名称</span></span><br><span class="line"><span class="string">方式2</span></span><br><span class="line"><span class="string">使用三方模块</span></span><br><span class="line"><span class="string">    Sphinx</span></span><br><span class="line"><span class="string">    epydoc</span></span><br><span class="line"><span class="string">    doxygen</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-11-属性相关补充"><a href="#2-11-属性相关补充" class="headerlink" title="2.11  属性相关补充"></a>2.11  属性相关补充</h4><h5 id="2-11-1-私有化属性"><a href="#2-11-1-私有化属性" class="headerlink" title="2.11.1  私有化属性"></a>2.11.1  私有化属性</h5><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">私有化属性</span></span><br><span class="line"><span class="string">概念</span></span><br><span class="line"><span class="string">    是指将一些原本公开的属性设置权限, 只能小范围访问, 其他地方访问不了</span></span><br><span class="line"><span class="string">意义</span></span><br><span class="line"><span class="string">    保证数据的安全性</span></span><br><span class="line"><span class="string">    提高代码的可维护性</span></span><br><span class="line"><span class="string">* 注意</span></span><br><span class="line"><span class="string">    Python并没有真正的私有化支持，但是, 可以使用下划线完成伪私有的效果</span></span><br><span class="line"><span class="string">    类属性(方法)和实例属性(方法)遵循相同的规则</span></span><br><span class="line"><span class="string">x</span></span><br><span class="line"><span class="string">公有属性</span></span><br><span class="line"><span class="string">    类内部访问</span></span><br><span class="line"><span class="string">    子类内部访问</span></span><br><span class="line"><span class="string">    模块内其他位置访问</span></span><br><span class="line"><span class="string">        类访问</span></span><br><span class="line"><span class="string">            父类</span></span><br><span class="line"><span class="string">            派生类(继承的类)</span></span><br><span class="line"><span class="string">        实例访问</span></span><br><span class="line"><span class="string">            父类实例</span></span><br><span class="line"><span class="string">            派生类实例</span></span><br><span class="line"><span class="string">    跨模块访问</span></span><br><span class="line"><span class="string">        import形式导入</span></span><br><span class="line"><span class="string">        from 模块 import * 形式导入</span></span><br><span class="line"><span class="string">_y</span></span><br><span class="line"><span class="string">    受保护属性</span></span><br><span class="line"><span class="string">        类内部访问</span></span><br><span class="line"><span class="string">        子类内部访问</span></span><br><span class="line"><span class="string">        模块内其他位置访问(有警告，但是可以访问)</span></span><br><span class="line"><span class="string">            类访问</span></span><br><span class="line"><span class="string">                父类</span></span><br><span class="line"><span class="string">                派生类</span></span><br><span class="line"><span class="string">            实例访问</span></span><br><span class="line"><span class="string">                父类实例</span></span><br><span class="line"><span class="string">                派生类实例</span></span><br><span class="line"><span class="string">        跨模块访问</span></span><br><span class="line"><span class="string">            import形式导入(有警告，但是可以访问)</span></span><br><span class="line"><span class="string">            from module import * 形式导入</span></span><br><span class="line"><span class="string">                * 有__all__指明对应变量(提前使用__all__ = [&quot;_y&quot;]，可以访问，不警告)</span></span><br><span class="line"><span class="string">                * 没有__all__指明对应变量(报错,不能访问)</span></span><br><span class="line"><span class="string">__z</span></span><br><span class="line"><span class="string">    私有属性</span></span><br><span class="line"><span class="string">        类内部访问</span></span><br><span class="line"><span class="string">        子类内部访问(报错,不能访问)</span></span><br><span class="line"><span class="string">        模块内其他位置访问(报错,不能访问)</span></span><br><span class="line"><span class="string">            类访问</span></span><br><span class="line"><span class="string">                父类</span></span><br><span class="line"><span class="string">                派生类</span></span><br><span class="line"><span class="string">            实例访问</span></span><br><span class="line"><span class="string">                父类实例</span></span><br><span class="line"><span class="string">                派生类实例</span></span><br><span class="line"><span class="string">        跨模块访问(属性报错,不能访问,模块可以按照下面方案访问)</span></span><br><span class="line"><span class="string">            import形式导入(可以访问)</span></span><br><span class="line"><span class="string">            from module import * 形式导入</span></span><br><span class="line"><span class="string">                * 有__all__指明对应变量(提前使用__all__ = [&quot;_y&quot;]，可以访问，不警告)</span></span><br><span class="line"><span class="string">                * 没有__all__指明对应变量(报错,不能访问)</span></span><br><span class="line"><span class="string">    私有属性的实现机制</span></span><br><span class="line"><span class="string">        名字重整(Name Mangling)</span></span><br><span class="line"><span class="string">            重改__x为另外一个名称, 如</span></span><br><span class="line"><span class="string">                _类名__x</span></span><br><span class="line"><span class="string">        目的</span></span><br><span class="line"><span class="string">            防止外界直接访问</span></span><br><span class="line"><span class="string">            防止被子类同名称属性覆盖</span></span><br><span class="line"><span class="string">    应用场景</span></span><br><span class="line"><span class="string">        数据保护</span></span><br><span class="line"><span class="string">        数据过滤</span></span><br><span class="line"><span class="string">补充</span></span><br><span class="line"><span class="string">    xx_</span></span><br><span class="line"><span class="string">        &quot;变量名_&quot; 这个格式是为了与系统属性作区分</span></span><br><span class="line"><span class="string">    __xx__</span></span><br><span class="line"><span class="string">        两端__一般为系统内置属性或方法, 所以以后命名注意避免</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h5 id="2-11-2-只读属性"><a href="#2-11-2-只读属性" class="headerlink" title="2.11.2  只读属性"></a>2.11.2  只读属性</h5><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">只读属性</span></span><br><span class="line"><span class="string">概念</span></span><br><span class="line"><span class="string">    一个属性(一般指实例属性), 只能读取, 不能写入</span></span><br><span class="line"><span class="string">应用场景</span></span><br><span class="line"><span class="string">    有些属性, 只限在内部根据不同场景进行修改, 而对外界来说, 不能修改, 只能读取</span></span><br><span class="line"><span class="string">    比如</span></span><br><span class="line"><span class="string">        电脑类的网速属性, 网络状态属性</span></span><br><span class="line"><span class="string">方式1</span></span><br><span class="line"><span class="string">    方案</span></span><br><span class="line"><span class="string">        全部隐藏</span></span><br><span class="line"><span class="string">            私有化</span></span><br><span class="line"><span class="string">                既不能读</span></span><br><span class="line"><span class="string">                也不能写</span></span><br><span class="line"><span class="string">        部分公开</span></span><br><span class="line"><span class="string">            公开读的操作(设置方法返回私有属性)</span></span><br><span class="line"><span class="string">    具体实现</span></span><br><span class="line"><span class="string">        私有化</span></span><br><span class="line"><span class="string">            通过&quot;属性前置双下划线&quot;实现</span></span><br><span class="line"><span class="string">        部分公开</span></span><br><span class="line"><span class="string">            通过公开的方法</span></span><br><span class="line"><span class="string">            优化(加装饰器@property)</span></span><br><span class="line"><span class="string">                property</span></span><br><span class="line"><span class="string">                    作用</span></span><br><span class="line"><span class="string">                        将一些&quot;属性的操作方法&quot;关联到某一个属性中</span></span><br><span class="line"><span class="string">                    概念补充(使用__bases__属性查看继承的基类)</span></span><br><span class="line"><span class="string">                        经典类</span></span><br><span class="line"><span class="string">                            没有继承(object)</span></span><br><span class="line"><span class="string">                        新式类</span></span><br><span class="line"><span class="string">                            继承(object)</span></span><br><span class="line"><span class="string">                        Python2.x版本定义一个类时, 默认不继承(object)</span></span><br><span class="line"><span class="string">                        Python3.x版本定义一个类时, 默认继承(object)</span></span><br><span class="line"><span class="string">                        建议使用</span></span><br><span class="line"><span class="string">                            新式类</span></span><br><span class="line"><span class="string">                    property</span></span><br><span class="line"><span class="string">                        在经典类中</span></span><br><span class="line"><span class="string">                            只能管理一个属性的读取操作</span></span><br><span class="line"><span class="string">                        在新式类中</span></span><br><span class="line"><span class="string">                            可以管理一个属性的删改查操作</span></span><br><span class="line"><span class="string">方式2</span></span><br><span class="line"><span class="string">    方案</span></span><br><span class="line"><span class="string">        借助系统内置的方法进行拦截</span></span><br><span class="line"><span class="string">    具体实现</span></span><br><span class="line"><span class="string">        __setattr__方法</span></span><br><span class="line"><span class="string">            当我们使用 &quot;实例.属性 = 值&quot; 这种格式给一个实例增加或修改属性的时候, 都会调用系统内置的这个方法</span></span><br><span class="line"><span class="string">            在这个方法的内部, 才会真正的把属性以及对应的值给存储到 __dict__当中</span></span><br><span class="line"><span class="string">        解决方案</span></span><br><span class="line"><span class="string">            在这个方法中, 进行拦截</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 在python3.x环境下</span></span><br><span class="line"><span class="comment"># property在新式类使用方式一</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self.__age = <span class="number">18</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">set_age</span>(<span class="params">self, age</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;setAge...&quot;</span>)</span><br><span class="line">        self.__age = age</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">get_age</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;getAge...&quot;</span>)</span><br><span class="line">        <span class="keyword">return</span> self.__age</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 参数顺序不能反</span></span><br><span class="line">    age = <span class="built_in">property</span>(get_age, set_age)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># p = Person()</span></span><br><span class="line"><span class="comment"># p.age = 666</span></span><br><span class="line"><span class="comment"># print(p.age)</span></span><br><span class="line"><span class="comment"># print(p.__dict__)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># property在新式类使用方式二</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self.__age = <span class="number">15</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">age</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;get___________&quot;</span>)</span><br><span class="line">        <span class="keyword">return</span> self.__age</span><br><span class="line"></span><br><span class="line"><span class="meta">    @age.setter</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">age</span>(<span class="params">self, age</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;set__________&quot;</span>)</span><br><span class="line">        self.__age = age</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">animal = Animal()</span><br><span class="line">animal.age = <span class="number">666</span></span><br><span class="line"><span class="built_in">print</span>(animal.age)</span><br><span class="line"><span class="built_in">print</span>(animal.__dict__)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># python2.x环境下测试</span></span><br><span class="line"><span class="comment"># property在经典类使用方式一</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self.__age = <span class="number">18</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">set_age</span>(<span class="params">self, age</span>):</span><br><span class="line">        <span class="built_in">print</span> <span class="string">&quot;setAge...&quot;</span></span><br><span class="line">        self.__age = age</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">get_age</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span> <span class="string">&quot;getAge...&quot;</span></span><br><span class="line">        <span class="keyword">return</span> self.__age</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 参数顺序不能反</span></span><br><span class="line">    age = <span class="built_in">property</span>(get_age, set_age)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># p = Person()</span></span><br><span class="line"><span class="comment"># # 经典类不能修改属性，只会新增属性，只关联了property的读取方法</span></span><br><span class="line"><span class="comment"># p.age = 666</span></span><br><span class="line"><span class="comment"># print p.age</span></span><br><span class="line"><span class="comment"># print p.__dict__</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># property在经典类使用方式二</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self.__age = <span class="number">15</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">age</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span> <span class="string">&quot;get___________&quot;</span></span><br><span class="line">        <span class="keyword">return</span> self.__age</span><br><span class="line"></span><br><span class="line"><span class="meta">    @age.setter</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">age</span>(<span class="params">self, age</span>):</span><br><span class="line">        <span class="built_in">print</span> <span class="string">&quot;set__________&quot;</span></span><br><span class="line">        self.__age = age</span><br><span class="line"></span><br><span class="line">animal = Animal()</span><br><span class="line"><span class="comment"># # 经典类不能修改属性，只会新增属性，只关联了property的读取方法</span></span><br><span class="line">animal.age = <span class="number">666</span></span><br><span class="line"><span class="built_in">print</span> animal.age</span><br><span class="line"><span class="built_in">print</span> animal.__dict__</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 只读属性的方式二</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>:</span><br><span class="line">    <span class="comment"># 当我们使用 &quot;实例.属性 = 值&quot; 这种格式给一个实例增加或修改属性的时候, 都会调用系统内置的这个方法</span></span><br><span class="line">    <span class="comment"># 在这个方法的内部, 才会真正的把属性以及对应的值给存储到 __dict__当中</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__setattr__</span>(<span class="params">self, key, value</span>):</span><br><span class="line">        <span class="built_in">print</span>(key, value)</span><br><span class="line">        <span class="keyword">if</span> key == <span class="string">&quot;age&quot;</span> <span class="keyword">and</span> key <span class="keyword">in</span> self.__dict__.keys():</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;只读属性，不能设置属性&quot;</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="comment"># self.key = value 死循环</span></span><br><span class="line">            self.__dict__[key] = value</span><br><span class="line"></span><br><span class="line">p = Person()</span><br><span class="line">p.age = <span class="number">15</span></span><br><span class="line"><span class="built_in">print</span>(p.age)</span><br><span class="line"><span class="comment"># p.name = &quot;zz&quot;</span></span><br><span class="line"></span><br><span class="line">p.age = <span class="number">66</span></span><br><span class="line"><span class="built_in">print</span>(p.age)</span><br><span class="line"><span class="built_in">print</span>(p.__dict__)</span><br><span class="line"></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h5 id="2-11-3-内置特殊属性"><a href="#2-11-3-内置特殊属性" class="headerlink" title="2.11.3  内置特殊属性"></a>2.11.3  内置特殊属性</h5><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 内置特殊属性</span></span><br><span class="line"><span class="comment">#  类属性</span></span><br><span class="line"><span class="comment">#     __dict__ : 类的属性</span></span><br><span class="line"><span class="comment">#     __bases__ : 类的所有父类构成元组</span></span><br><span class="line"><span class="comment">#     __doc__ :类的文档字符串</span></span><br><span class="line"><span class="comment">#     __name__: 类名</span></span><br><span class="line"><span class="comment">#     __module__: 类定义所在的模块</span></span><br><span class="line"><span class="comment">#  实例属性</span></span><br><span class="line"><span class="comment">#     __dict__ : 实例的属性</span></span><br><span class="line"><span class="comment">#     __class__: 实例对应的类</span></span><br></pre></td></tr></table></figure><h4 id="2-12-私有化方法"><a href="#2-12-私有化方法" class="headerlink" title="2.12  私有化方法"></a>2.12  私有化方法</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">私有方法(与私有化属性类似)</span></span><br><span class="line"><span class="string">def __方法():</span></span><br><span class="line"><span class="string">pass</span></span><br><span class="line"><span class="string">注意</span></span><br><span class="line"><span class="string">不要定义 &quot;_类名__方法名&quot; 这种方法,会把名字重整机制的方法覆盖掉</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-13-内置特殊方法"><a href="#2-13-内置特殊方法" class="headerlink" title="2.13  内置特殊方法"></a>2.13  内置特殊方法</h4><h5 id="2-13-1-生命周期方法"><a href="#2-13-1-生命周期方法" class="headerlink" title="2.13.1  生命周期方法"></a>2.13.1  <a href="#3.3  监听对象生命周期">生命周期方法</a></h5><h5 id="2-13-2-其他内置方法"><a href="#2-13-2-其他内置方法" class="headerlink" title="2.13 .2 其他内置方法"></a>2.13 .2 其他内置方法</h5><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># ----------------信息格式化操作:__str__方法-------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     # 类的构造方法，self相当于java的this关键字</span></span><br><span class="line"><span class="comment">#     def __init__(self, weight, height):</span></span><br><span class="line"><span class="comment">#         self.weight = weight</span></span><br><span class="line"><span class="comment">#         self.height = height</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     # 相当于java自己重写的toString()方法</span></span><br><span class="line"><span class="comment">#     def __str__(self):</span></span><br><span class="line"><span class="comment">#         # return &quot;这个人的身高是%s, 年龄是%s&quot; % (self.height, self.weight)</span></span><br><span class="line"><span class="comment">#         # return &quot;这个人的身高是%(height)s, 年龄是%(weight)s&quot; % (&#123;&quot;height&quot;: self.height, &quot;weight&quot;: self.weight&#125;)</span></span><br><span class="line"><span class="comment">#         # return &quot;这个人的身高是&#123;0&#125;, 年龄是&#123;1&#125;&quot;.format(self.height, self.weight)</span></span><br><span class="line"><span class="comment">#         return f&quot;这个人的身高是&#123;self.height&#125;, 年龄是&#123;self.weight&#125;&quot;</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p1 = Person(40, 152)</span></span><br><span class="line"><span class="comment"># print(p1.height)</span></span><br><span class="line"><span class="comment"># print(p1.weight)</span></span><br><span class="line"><span class="comment"># print(p1)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p2 = Person(70, 190)</span></span><br><span class="line"><span class="comment"># print(p2.height)</span></span><br><span class="line"><span class="comment"># print(p2.weight)</span></span><br><span class="line"><span class="comment"># print(p2)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># s = str(p1)</span></span><br><span class="line"><span class="comment"># print(s, type(s))</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------信息格式化操作:__repr__方法-------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     # 类的构造方法，self相当于java的this关键字</span></span><br><span class="line"><span class="comment">#     def __init__(self, weight, height):</span></span><br><span class="line"><span class="comment">#         self.weight = weight</span></span><br><span class="line"><span class="comment">#         self.height = height</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     # 相当于java自己重写的toString()方法</span></span><br><span class="line"><span class="comment">#     def __str__(self):</span></span><br><span class="line"><span class="comment">#         # return &quot;这个人的身高是%s, 年龄是%s&quot; % (self.height, self.weight)</span></span><br><span class="line"><span class="comment">#         # return &quot;这个人的身高是%(height)s, 年龄是%(weight)s&quot; % (&#123;&quot;height&quot;: self.height, &quot;weight&quot;: self.weight&#125;)</span></span><br><span class="line"><span class="comment">#         # return &quot;这个人的身高是&#123;0&#125;, 年龄是&#123;1&#125;&quot;.format(self.height, self.weight)</span></span><br><span class="line"><span class="comment">#         return f&quot;这个人的身高是&#123;self.height&#125;, 年龄是&#123;self.weight&#125;&quot;</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __repr__(self):</span></span><br><span class="line"><span class="comment">#         return &quot;vvv&quot;</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p1 = Person(40, 152)</span></span><br><span class="line"><span class="comment"># print(p1)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p2 = Person(70, 190)</span></span><br><span class="line"><span class="comment"># print(p2)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># # s = str(p1)</span></span><br><span class="line"><span class="comment"># # print(s, type(s))</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># print(repr(p1))</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># import datetime</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># t = datetime.datetime.now()</span></span><br><span class="line"><span class="comment"># print(t)</span></span><br><span class="line"><span class="comment"># tmp = repr(t)</span></span><br><span class="line"><span class="comment"># # 面向开发人员</span></span><br><span class="line"><span class="comment"># print(tmp)</span></span><br><span class="line"><span class="comment"># # 面向用户</span></span><br><span class="line"><span class="comment"># print(eval(tmp))</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------调用操作: __call__方法-------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __call__(self, *args, **kwargs):</span></span><br><span class="line"><span class="comment">#         print(&quot;xxx&quot;, args, kwargs)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     pass</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p = Person()</span></span><br><span class="line"><span class="comment"># p(12, 56, name=&quot;jj&quot;)</span></span><br><span class="line"><span class="keyword">import</span> collections.abc</span><br><span class="line"><span class="keyword">import</span> functools</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 关键字参数放后面</span></span><br><span class="line"><span class="comment"># def getColorPen(pen_color, pen_type):</span></span><br><span class="line"><span class="comment">#     print(f&quot;&#123;pen_type&#125;的颜色是&#123;pen_color&#125;&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># pen = functools.partial(getColorPen, pen_type=&quot;钢笔&quot;)</span></span><br><span class="line"><span class="comment"># pen(&quot;红色&quot;)</span></span><br><span class="line"><span class="comment"># pen(&quot;绿色&quot;)</span></span><br><span class="line"><span class="comment"># pen(&quot;蓝色&quot;)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># class PenFactory:</span></span><br><span class="line"><span class="comment">#     def __init__(self, pen_type):</span></span><br><span class="line"><span class="comment">#         self.pen_type = pen_type</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __call__(self, pen_color):</span></span><br><span class="line"><span class="comment">#         print(f&quot;&#123;self.pen_type&#125;的颜色是&#123;pen_color&#125;&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p = PenFactory(&quot;钢笔&quot;)</span></span><br><span class="line"><span class="comment"># p(&quot;红色&quot;)</span></span><br><span class="line"><span class="comment"># p(&quot;绿色&quot;)</span></span><br><span class="line"><span class="comment"># p(&quot;蓝色&quot;)</span></span><br><span class="line"><span class="comment"># pencil = PenFactory(&quot;铅笔&quot;)</span></span><br><span class="line"><span class="comment"># pencil(&quot;红色&quot;)</span></span><br><span class="line"><span class="comment"># pencil(&quot;绿色&quot;)</span></span><br><span class="line"><span class="comment"># pencil(&quot;蓝色&quot;)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------索引操作-------------------------</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __init__(self):</span></span><br><span class="line"><span class="comment">#         self.cache = &#123;&#125;</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __setitem__(self, key, value):</span></span><br><span class="line"><span class="comment">#         # print(&quot;__setitem__&quot;, key, value)</span></span><br><span class="line"><span class="comment">#         self.cache[key] = value</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __getitem__(self, item):</span></span><br><span class="line"><span class="comment">#         # print(&quot;__getitem__&quot;, item)</span></span><br><span class="line"><span class="comment">#         return self.cache[item]</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __delitem__(self, key):</span></span><br><span class="line"><span class="comment">#         # print(&quot;__delitem__&quot;, key)</span></span><br><span class="line"><span class="comment">#         del self.cache[key]</span></span><br><span class="line"><span class="comment">#     pass</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># person = Person()</span></span><br><span class="line"><span class="comment"># person[&quot;name&quot;] = &quot;zhangsan&quot;</span></span><br><span class="line"><span class="comment"># print(person[&quot;name&quot;])</span></span><br><span class="line"><span class="comment"># del person[&quot;name&quot;]</span></span><br><span class="line"><span class="comment"># # print(person[&quot;name&quot;])</span></span><br><span class="line"><span class="comment"># print(person.cache)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------索引操作-------------------------</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __init__(self):</span></span><br><span class="line"><span class="comment">#         self.items = [1, 2, 3, 5, 6, 8, 9]</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __setitem__(self, key, value):</span></span><br><span class="line"><span class="comment">#         # 判断是不是切片对象</span></span><br><span class="line"><span class="comment">#         if isinstance(key, slice):</span></span><br><span class="line"><span class="comment">#             self.items[key.start: key.stop: key.step] = value</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __getitem__(self, item):</span></span><br><span class="line"><span class="comment">#         # print(&quot;get&quot;, item)</span></span><br><span class="line"><span class="comment">#         if isinstance(item, slice):</span></span><br><span class="line"><span class="comment">#             return self.items[item.start:item.stop:item.step]</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __delitem__(self, key):</span></span><br><span class="line"><span class="comment">#         # print(&quot;del&quot;, key)</span></span><br><span class="line"><span class="comment">#         del self.items[key]</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p = Person()</span></span><br><span class="line"><span class="comment"># p[0:4:2] = [&quot;l&quot;, &quot;m&quot;]</span></span><br><span class="line"><span class="comment"># print(p[0:4:2])</span></span><br><span class="line"><span class="comment"># del p[0:4:2]</span></span><br><span class="line"><span class="comment"># print(p.items)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------比较操作-------------------------</span></span><br><span class="line"><span class="comment"># python 2.x 可以直接使用 &gt; &lt; &gt;= &lt;= != ==比较</span></span><br><span class="line"><span class="comment"># python3.x需要实现六个方法才能使用，实现逻辑，但是方法不会叠加操作，不如eq方法与lt方法不会叠加为le方法</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __init__(self, age, height):</span></span><br><span class="line"><span class="comment">#         self.age = age</span></span><br><span class="line"><span class="comment">#         self.height = height</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     # 等于，可以由__ne__通过调换参数反推导出来，也可以自己写</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # def __eq__(self, other):</span></span><br><span class="line"><span class="comment">#     #     print(&quot;__eq__&quot;)</span></span><br><span class="line"><span class="comment">#     #     return self.age == other.age</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     #    不等于，可以由__eq__通过调换参数反推导出来，也可以自己写</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # def __ne__(self, other):</span></span><br><span class="line"><span class="comment">#     #     print(&quot;__ne__&quot;)</span></span><br><span class="line"><span class="comment">#     #     return self.age != other.age or self.height != other.height</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     #  大于，可以由__lt__通过调换参数反推导出来，也可以自己写</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # def __gt__(self, other):</span></span><br><span class="line"><span class="comment">#     #     print(&quot;__gt__&quot;)</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#        小于，可以由__gt__通过调换参数反推导出来，也可以自己写</span></span><br><span class="line"><span class="comment">#     &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __lt__(self, other):</span></span><br><span class="line"><span class="comment">#         print(&quot;__lt__&quot;)</span></span><br><span class="line"><span class="comment">#         # 当为大于号时参数调换</span></span><br><span class="line"><span class="comment">#         print(self.age)</span></span><br><span class="line"><span class="comment">#         print(other.age)</span></span><br><span class="line"><span class="comment">#         return self.age &lt; other.age</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     # 于等于，可以由__le__通过调换参数反推导出来，也可以自己写</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # def __ge__(self, other):</span></span><br><span class="line"><span class="comment">#     #     print(&quot;__ge__&quot;)</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     # 大于等于，可以由__ge__通过调换参数反推导出来，也可以自己写</span></span><br><span class="line"><span class="comment">#     # &quot;&quot;&quot;</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # def __le__(self, other):</span></span><br><span class="line"><span class="comment">#     #     print(&quot;__le__&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p1 = Person(10, 160)</span></span><br><span class="line"><span class="comment"># p2 = Person(19, 170)</span></span><br><span class="line"><span class="comment"># print(p1 &lt; p2)</span></span><br><span class="line"><span class="comment"># print(p1 &gt; p2)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------比较操作_补充-------------------------</span></span><br><span class="line"><span class="comment"># import functools</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># # 加下面装饰器至少必须有六个方法的其中一个</span></span><br><span class="line"><span class="comment"># @functools.total_ordering</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __eq__(self, other):</span></span><br><span class="line"><span class="comment">#         print(&quot;eq&quot;)</span></span><br><span class="line"><span class="comment">#         pass</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __lt__(self, other):</span></span><br><span class="line"><span class="comment">#         print(&quot;lt&quot;)</span></span><br><span class="line"><span class="comment">#         return False</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p1 = Person()</span></span><br><span class="line"><span class="comment"># p2 = Person()</span></span><br><span class="line"><span class="comment"># print(p1 &lt;= p2)</span></span><br><span class="line"><span class="comment"># # print(Person.__dict__)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># # ----------------上下文环境中的布尔值-------------------------</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __init__(self):</span></span><br><span class="line"><span class="comment">#         self.age = 18</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __bool__(self):</span></span><br><span class="line"><span class="comment">#         return self.age &gt;= 18</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p1 = Person()</span></span><br><span class="line"><span class="comment"># if p1:</span></span><br><span class="line"><span class="comment">#     print(&quot;实例为真&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------遍历操作-------------------------</span></span><br><span class="line"><span class="comment"># 遍历操作方式一</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __init__(self):</span></span><br><span class="line"><span class="comment">#         self.res = 1</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __getitem__(self, item):</span></span><br><span class="line"><span class="comment">#         self.res += 1</span></span><br><span class="line"><span class="comment">#         if self.res &gt;= 6:</span></span><br><span class="line"><span class="comment">#             raise StopIteration(&quot;停止遍历&quot;)</span></span><br><span class="line"><span class="comment">#         return self.res</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p = Person()</span></span><br><span class="line"><span class="comment"># for i in p:</span></span><br><span class="line"><span class="comment">#     print(i)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 遍历操作方式二</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __init__(self):</span></span><br><span class="line"><span class="comment">#         self.res = 1</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __iter__(self):</span></span><br><span class="line"><span class="comment">#         print(&quot;iter&quot;)</span></span><br><span class="line"><span class="comment">#         # 返回迭代器</span></span><br><span class="line"><span class="comment">#         # return iter([1, 2, 3, 4, 6])</span></span><br><span class="line"><span class="comment">#         return self</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __next__(self):</span></span><br><span class="line"><span class="comment">#         self.res += 1</span></span><br><span class="line"><span class="comment">#         if self.res &gt;= 6:</span></span><br><span class="line"><span class="comment">#             raise StopIteration(&quot;停止遍历&quot;)</span></span><br><span class="line"><span class="comment">#         return self.res</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p = Person()</span></span><br><span class="line"><span class="comment"># # for i in p:</span></span><br><span class="line"><span class="comment"># #     print(i)</span></span><br><span class="line"><span class="comment"># print(next(p))</span></span><br><span class="line"><span class="comment"># print(next(p))</span></span><br><span class="line"><span class="comment"># print(next(p))</span></span><br><span class="line"><span class="comment"># print(next(p))</span></span><br><span class="line"><span class="comment"># # print(next(p))</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------遍历操作,恢复迭代器初始值-------------------------</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __init__(self):</span></span><br><span class="line"><span class="comment">#         self.res = 1</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     # 方式一</span></span><br><span class="line"><span class="comment">#     # def __getitem__(self, item):</span></span><br><span class="line"><span class="comment">#     #     self.res += 1</span></span><br><span class="line"><span class="comment">#     #     if self.res &gt;= 6:</span></span><br><span class="line"><span class="comment">#     #         raise StopIteration(&quot;停止遍历&quot;)</span></span><br><span class="line"><span class="comment">#     #     return self.res</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     # 方式二</span></span><br><span class="line"><span class="comment">#     def __iter__(self):</span></span><br><span class="line"><span class="comment">#         # 每次迭代重新赋值，使得迭代器重用</span></span><br><span class="line"><span class="comment">#         self.res = 1</span></span><br><span class="line"><span class="comment">#         return self</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     # def __next__(self):</span></span><br><span class="line"><span class="comment">#     #     self.res += 1</span></span><br><span class="line"><span class="comment">#     #     if self.res &gt;= 6:</span></span><br><span class="line"><span class="comment">#     #         raise StopIteration(&quot;停止遍历&quot;)</span></span><br><span class="line"><span class="comment">#     #     return self.res</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __call__(self, *args, **kwargs):</span></span><br><span class="line"><span class="comment">#         self.res += 1</span></span><br><span class="line"><span class="comment">#         if self.res &gt;= 6:</span></span><br><span class="line"><span class="comment">#             raise StopIteration(&quot;停止遍历&quot;)</span></span><br><span class="line"><span class="comment">#         return self.res</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># p = Person()</span></span><br><span class="line"><span class="comment"># # 前提是实现了__getitem__方法，才可以使用iter()</span></span><br><span class="line"><span class="comment"># # pt = iter(p.__next__, 4)</span></span><br><span class="line"><span class="comment"># # 实例可以被调用，实现call方法</span></span><br><span class="line"><span class="comment"># pt = iter(p, 4)</span></span><br><span class="line"><span class="comment"># print(pt)</span></span><br><span class="line"><span class="comment"># print(p is pt)</span></span><br><span class="line"><span class="comment"># for i in pt:</span></span><br><span class="line"><span class="comment">#     print(i)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># # for i in p:</span></span><br><span class="line"><span class="comment"># #     print(i)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># # 可迭代对象或迭代器肯定可以for in，但是可以for in 不一定是可迭代对象或迭代器</span></span><br><span class="line"><span class="comment"># from collections.abc import *</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># # 实例成为迭代器条件：写__iter__方法与__next__方法</span></span><br><span class="line"><span class="comment"># # 判断是不是迭代器对象</span></span><br><span class="line"><span class="comment"># print(isinstance(p, Iterator))</span></span><br><span class="line"><span class="comment"># # 判断是不是可迭代对象</span></span><br><span class="line"><span class="comment"># print(isinstance(p, Iterable))</span></span><br><span class="line"><span class="comment"># print(isinstance(pt, Iterator))</span></span><br><span class="line"><span class="comment"># print(isinstance(pt, Iterable))</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------描述器定义方式一-------------------------</span></span><br><span class="line"><span class="comment"># class Person:</span></span><br><span class="line"><span class="comment">#     def __init__(self):</span></span><br><span class="line"><span class="comment">#         self.__age = 18</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     @property</span></span><br><span class="line"><span class="comment">#     def age(self):</span></span><br><span class="line"><span class="comment">#         return self.__age</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     @age.setter</span></span><br><span class="line"><span class="comment">#     def age(self, value):</span></span><br><span class="line"><span class="comment">#         if value &lt; 0:</span></span><br><span class="line"><span class="comment">#             value = 0</span></span><br><span class="line"><span class="comment">#         self.__age = value</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     @age.deleter</span></span><br><span class="line"><span class="comment">#     def age(self):</span></span><br><span class="line"><span class="comment">#         del self.__age</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     num = &quot;jj&quot;</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># person = Person()</span></span><br><span class="line"><span class="comment"># person.age = 10</span></span><br><span class="line"><span class="comment"># print(person.age)</span></span><br><span class="line"><span class="comment"># del person.age</span></span><br><span class="line"><span class="comment"># # print(person.age)</span></span><br><span class="line"><span class="comment"># help(person)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------描述器定义方式二-------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># class Age(object):</span></span><br><span class="line"><span class="comment">#     def __get__(self, instance, owner):</span></span><br><span class="line"><span class="comment">#         print(&quot;get&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __set__(self, instance, value):</span></span><br><span class="line"><span class="comment">#         print(&quot;set&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __delete__(self, instance):</span></span><br><span class="line"><span class="comment">#         print(&quot;delete&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># class Person(object):</span></span><br><span class="line"><span class="comment">#     age = Age()</span></span><br><span class="line"><span class="comment">#     # def __getattribute__(self, item):</span></span><br><span class="line"><span class="comment">#     #     print(&quot;kkkk&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># # 只要新式类才会转换操作描述器</span></span><br><span class="line"><span class="comment"># person = Person()</span></span><br><span class="line"><span class="comment"># person.age = 10</span></span><br><span class="line"><span class="comment"># print(person.age)</span></span><br><span class="line"><span class="comment"># del person.age</span></span><br><span class="line"><span class="comment"># print(person.age)</span></span><br><span class="line"><span class="comment"># help(person)</span></span><br><span class="line"><span class="comment"># 只打印get。不会转换set和delete。所以一般通过实例操作描述器</span></span><br><span class="line"><span class="comment"># print(Person.age)</span></span><br><span class="line"><span class="comment"># Person.age = 20</span></span><br><span class="line"><span class="comment"># del Person.age</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 如果实现了__get__, 判定为&quot;非资料描述器&quot;</span></span><br><span class="line"><span class="comment"># 如果实现了__get__、 __set__，判定为&quot;资料描述器&quot;</span></span><br><span class="line"><span class="comment"># 资料描述器 &gt; 实例字典 &gt; 非资料描述器</span></span><br><span class="line"><span class="comment"># ----------------描述器优先级-------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># class Age(object):</span></span><br><span class="line"><span class="comment">#     def __get__(self, instance, owner):</span></span><br><span class="line"><span class="comment">#         print(&quot;get&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     # def __set__(self, instance, value):</span></span><br><span class="line"><span class="comment">#     #     print(&quot;set&quot;)</span></span><br><span class="line"><span class="comment">#     #</span></span><br><span class="line"><span class="comment">#     # def __delete__(self, instance):</span></span><br><span class="line"><span class="comment">#     #     print(&quot;delete&quot;)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># class Person(object):</span></span><br><span class="line"><span class="comment">#     age = Age()</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __init__(self):</span></span><br><span class="line"><span class="comment">#         self.age = 100</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># # 只要新式类才会转换操作描述器</span></span><br><span class="line"><span class="comment"># person = Person()</span></span><br><span class="line"><span class="comment"># person.age = 10</span></span><br><span class="line"><span class="comment"># print(person.age)</span></span><br><span class="line"><span class="comment"># # del person.age</span></span><br><span class="line"><span class="comment"># print(person.__dict__)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------描述器值存在问题-------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># class Age(object):</span></span><br><span class="line"><span class="comment">#     def __get__(self, instance, owner):</span></span><br><span class="line"><span class="comment">#         print(&quot;get&quot;)</span></span><br><span class="line"><span class="comment">#         return instance.v</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __set__(self, instance, value):</span></span><br><span class="line"><span class="comment">#         print(&quot;set&quot;, self, instance, value)</span></span><br><span class="line"><span class="comment">#         instance.v = value</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     def __delete__(self, instance):</span></span><br><span class="line"><span class="comment">#         print(&quot;delete&quot;)</span></span><br><span class="line"><span class="comment">#         del instance.v</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># class Person(object):</span></span><br><span class="line"><span class="comment">#     age = Age()</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># # 多个实例的age对象相同，通过instance来修改值</span></span><br><span class="line"><span class="comment"># person = Person()</span></span><br><span class="line"><span class="comment"># person.age = 10</span></span><br><span class="line"><span class="comment"># print(person.age)</span></span><br><span class="line"><span class="comment"># # del person.age</span></span><br><span class="line"><span class="comment"># person2 = Person()</span></span><br><span class="line"><span class="comment"># person2.age = 100</span></span><br><span class="line"><span class="comment"># print(person2.age)</span></span><br><span class="line"><span class="comment"># print(person.age)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># ----------------使用类实现装饰器-------------------------</span></span><br><span class="line"><span class="comment"># def check(func):</span></span><br><span class="line"><span class="comment">#     def inner():</span></span><br><span class="line"><span class="comment">#         print(&quot;登录验证&quot;)</span></span><br><span class="line"><span class="comment">#         func()</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#     return inner</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Check</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, func</span>):</span><br><span class="line">        self.func = func</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__call__</span>(<span class="params">self, *args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;登录验证&quot;</span>)</span><br><span class="line">        self.func()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 语法糖装饰器 函数装饰器：@check   类装饰器：@Check</span></span><br><span class="line"><span class="comment"># @check</span></span><br><span class="line"><span class="comment"># @Check</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">publish_novels</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;发说说&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 函数装饰器</span></span><br><span class="line"><span class="comment"># publish_novels = check(publish_novels)</span></span><br><span class="line"><span class="comment"># 类装饰器</span></span><br><span class="line">publish_novels = Check(publish_novels)</span><br><span class="line">publish_novels()</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">内置特殊方法</span></span><br><span class="line"><span class="string">    1.生命周期方法[链接过去]</span></span><br><span class="line"><span class="string">    2.其他内置方法</span></span><br><span class="line"><span class="string">        a.信息格式化操作</span></span><br><span class="line"><span class="string">            __str__方法</span></span><br><span class="line"><span class="string">                作用</span></span><br><span class="line"><span class="string">                    一个对象的描述字符串, 更加方便用户阅读, 对用户更友好</span></span><br><span class="line"><span class="string">                触发方式</span></span><br><span class="line"><span class="string">                    print 打印一个对象时</span></span><br><span class="line"><span class="string">                    str() 函数时</span></span><br><span class="line"><span class="string">                格式</span></span><br><span class="line"><span class="string">                    def __str__(self):</span></span><br><span class="line"><span class="string">    return &quot;描述信息&quot;</span></span><br><span class="line"><span class="string">            __repr__方法</span></span><br><span class="line"><span class="string">                作用</span></span><br><span class="line"><span class="string">                    一个对象的描述字符串, 更加方便机器处理, 对机器更友好(开发人员查看)</span></span><br><span class="line"><span class="string">                触发方式</span></span><br><span class="line"><span class="string">                    当我们在交互模式下, 直接执行某个变量, 就会输出对应信息</span></span><br><span class="line"><span class="string">                    repr() 函数时</span></span><br><span class="line"><span class="string">                格式</span></span><br><span class="line"><span class="string">                    def __repr__(self):</span></span><br><span class="line"><span class="string">    return &quot;描述信息&quot;</span></span><br><span class="line"><span class="string">                注意</span></span><br><span class="line"><span class="string">                    一般情况下, 应满足如下等式</span></span><br><span class="line"><span class="string">                        obj == eval(repr(obj))</span></span><br><span class="line"><span class="string">                    或者描述一个实例详细的信息(类名等等)</span></span><br><span class="line"><span class="string">        b.调用操作</span></span><br><span class="line"><span class="string">            __call__方法</span></span><br><span class="line"><span class="string">                作用</span></span><br><span class="line"><span class="string">                    使得“对象”具备当做函数，来调用的能力</span></span><br><span class="line"><span class="string">                使用</span></span><br><span class="line"><span class="string">                    1. 实现实例方法 __call__</span></span><br><span class="line"><span class="string">                    2. 那么创建好的实例, 就可以通过函数的形式来调用</span></span><br><span class="line"><span class="string">                        实例(参数)</span></span><br><span class="line"><span class="string">                应用场景</span></span><br><span class="line"><span class="string">                    有点类似于之前所讲的&quot;偏函数&quot;的应用场景</span></span><br><span class="line"><span class="string">                    可以将&quot;常变参数&quot;和&quot;不常变参数&quot;进行分离</span></span><br><span class="line"><span class="string">                案例</span></span><br><span class="line"><span class="string">                    不同类型的笔, 画不同的图形</span></span><br><span class="line"><span class="string">        c.索引操作</span></span><br><span class="line"><span class="string">            作用</span></span><br><span class="line"><span class="string">                可以对一个实例对象进行索引操作</span></span><br><span class="line"><span class="string">            步骤</span></span><br><span class="line"><span class="string">                1. 实现三个内置方法</span></span><br><span class="line"><span class="string">                    设置元素的方法</span></span><br><span class="line"><span class="string">                        def __setitem__(self, key, value):</span></span><br><span class="line"><span class="string">                    获取元素的方法</span></span><br><span class="line"><span class="string">                        def __getitem__(self, item):</span></span><br><span class="line"><span class="string">                    删除元素的方法</span></span><br><span class="line"><span class="string">                        def __delitem__(self, key):</span></span><br><span class="line"><span class="string">                2. 可以以索引的形式操作对象</span></span><br><span class="line"><span class="string">                    增/改</span></span><br><span class="line"><span class="string">                        p[1] = 666</span></span><br><span class="line"><span class="string">                        p[&quot;name&quot;] = &quot;sz&quot;</span></span><br><span class="line"><span class="string">                    查</span></span><br><span class="line"><span class="string">                        p[&quot;name&quot;]</span></span><br><span class="line"><span class="string">                        p[1]</span></span><br><span class="line"><span class="string">                    删</span></span><br><span class="line"><span class="string">                        del p[&quot;name&quot;]</span></span><br><span class="line"><span class="string">                        del p[1]</span></span><br><span class="line"><span class="string">        d.切片操作</span></span><br><span class="line"><span class="string">            作用</span></span><br><span class="line"><span class="string">                可以对一个实例对象进行切片操作</span></span><br><span class="line"><span class="string">            步骤</span></span><br><span class="line"><span class="string">                Python2.x</span></span><br><span class="line"><span class="string">                    1. 实现三个内置方法</span></span><br><span class="line"><span class="string">                        __setspice__</span></span><br><span class="line"><span class="string">                            设置某个元素切片时调用</span></span><br><span class="line"><span class="string">                        __getspice__</span></span><br><span class="line"><span class="string">                            获取某个元素切片时调用</span></span><br><span class="line"><span class="string">                        __delspice__</span></span><br><span class="line"><span class="string">                            删除某个元素切片时调用</span></span><br><span class="line"><span class="string">                    2. 可以直接按照切片的方式操作对象</span></span><br><span class="line"><span class="string">                        p[1, 6, 2]</span></span><br><span class="line"><span class="string">                    * 注意: 过期</span></span><br><span class="line"><span class="string">                Python3.x</span></span><br><span class="line"><span class="string">                    统一由&quot;索引操作&quot;进行管理</span></span><br><span class="line"><span class="string">                        def __setitem__(self, key, value):</span></span><br><span class="line"><span class="string">                        def __getitem__(self, item):</span></span><br><span class="line"><span class="string">                        def __delitem__(self, key):</span></span><br><span class="line"><span class="string">        e.比较操作</span></span><br><span class="line"><span class="string">            作用</span></span><br><span class="line"><span class="string">                可以自定义对象 &quot;比较大小, 相等以及真假&quot; 规则</span></span><br><span class="line"><span class="string">            步骤</span></span><br><span class="line"><span class="string">                实现6个方法</span></span><br><span class="line"><span class="string">                    相等</span></span><br><span class="line"><span class="string">                        __eq__</span></span><br><span class="line"><span class="string">                    不相等</span></span><br><span class="line"><span class="string">                        __ne__</span></span><br><span class="line"><span class="string">                    小于</span></span><br><span class="line"><span class="string">                        __lt__</span></span><br><span class="line"><span class="string">                    小于或等于</span></span><br><span class="line"><span class="string">                        __le__</span></span><br><span class="line"><span class="string">                    大于</span></span><br><span class="line"><span class="string">                        __gt__</span></span><br><span class="line"><span class="string">                    大于或等于</span></span><br><span class="line"><span class="string">                        __ge__</span></span><br><span class="line"><span class="string">            注意</span></span><br><span class="line"><span class="string">                如果对于反向操作的比较符, 只定义了其中一个方法, 但使用的是另外一种比较运算, 那么, 解释器会采用调换参数的方式进行调用该方法</span></span><br><span class="line"><span class="string">                    例如</span></span><br><span class="line"><span class="string">                        定义了 &quot;小于&quot; 操作</span></span><br><span class="line"><span class="string">                            x &lt; y</span></span><br><span class="line"><span class="string">                        使用 x &gt; y</span></span><br><span class="line"><span class="string">                            会被调换参数, 调用上面的 &quot;小于操作&quot;</span></span><br><span class="line"><span class="string">                但是, 不支持叠加操作</span></span><br><span class="line"><span class="string">                    例如</span></span><br><span class="line"><span class="string">                        定义了 &quot;小于&quot; 和 &quot;等于&quot; 操作</span></span><br><span class="line"><span class="string">                        不能使用 x &lt;= y</span></span><br><span class="line"><span class="string">            补充</span></span><br><span class="line"><span class="string">                使用装饰器, 自动生成&quot;反向&quot; &quot;组合&quot;的方法</span></span><br><span class="line"><span class="string">                    步骤</span></span><br><span class="line"><span class="string">                        1. 使用装饰器装饰类</span></span><br><span class="line"><span class="string">                            @functools.total_ordering</span></span><br><span class="line"><span class="string">                        2. 实现</span></span><br><span class="line"><span class="string">                            &gt; 或 &gt;= 或 &lt; 或 &lt;= 其中一个</span></span><br><span class="line"><span class="string">                            实现 ==</span></span><br><span class="line"><span class="string">                上下文环境中的布尔值</span></span><br><span class="line"><span class="string">                    控制类中__bool__方法，返回布尔值来控制实例真假</span></span><br><span class="line"><span class="string">        f.遍历操作</span></span><br><span class="line"><span class="string">            怎样让我们自己创建的对象可以使用for in 进行遍历?</span></span><br><span class="line"><span class="string">                * 实现__getitem__方法</span></span><br><span class="line"><span class="string">                    优先级低</span></span><br><span class="line"><span class="string">                    每次for in 获取数据时, 都会调用这个方法</span></span><br><span class="line"><span class="string">                * 或者实现__iter__方法</span></span><br><span class="line"><span class="string">                    优先级高</span></span><br><span class="line"><span class="string">                    这个方法, 必须返回一个&quot;迭代器&quot;;即, 具备&quot;__iter__&quot;和&quot;__next__&quot;方法</span></span><br><span class="line"><span class="string">                    当for in 遍历这个对象时, 会调用这个__iter__方法;返回的迭代器对象的__next__方法</span></span><br><span class="line"><span class="string">            怎样让我们自己创建的对象可以使用next函数进行访问?</span></span><br><span class="line"><span class="string">                实现__next__方法</span></span><br><span class="line"><span class="string">            补充</span></span><br><span class="line"><span class="string">                1. __iter__方法可以恢复迭代器的初始化值, 复用迭代器</span></span><br><span class="line"><span class="string">                2. &quot;可迭代&quot; 与 &quot;迭代器&quot;必须实现的方法</span></span><br><span class="line"><span class="string">                3. iter方法的使用</span></span><br><span class="line"><span class="string">        描述器</span></span><br><span class="line"><span class="string">            概念</span></span><br><span class="line"><span class="string">                可以描述一个属性操作的对象</span></span><br><span class="line"><span class="string">                    对象</span></span><br><span class="line"><span class="string">                    属性的操作</span></span><br><span class="line"><span class="string">                        增/改</span></span><br><span class="line"><span class="string">                        删</span></span><br><span class="line"><span class="string">                        查</span></span><br><span class="line"><span class="string">                    描述</span></span><br><span class="line"><span class="string">            作用</span></span><br><span class="line"><span class="string">                可以代为管理一个类属性的读写删操作, 在相关方法中, 对数据进行验证处理, 过滤处理等等</span></span><br><span class="line"><span class="string">                如果一个类属性被定义为描述器，那么以后对这个类属性的操作(读写删), 都将由这个描述器代理</span></span><br><span class="line"><span class="string">            定义</span></span><br><span class="line"><span class="string">                定义方式1</span></span><br><span class="line"><span class="string">                    property</span></span><br><span class="line"><span class="string">                定义方式2</span></span><br><span class="line"><span class="string">                    三个方法</span></span><br><span class="line"><span class="string">                        __get__</span></span><br><span class="line"><span class="string">                        __set__</span></span><br><span class="line"><span class="string">                        __delete__</span></span><br><span class="line"><span class="string">            调用细节</span></span><br><span class="line"><span class="string">                使用实例进行调用</span></span><br><span class="line"><span class="string">                    最多三个方法都会被调用</span></span><br><span class="line"><span class="string">                使用类进行调用</span></span><br><span class="line"><span class="string">                    最多会调用get方法</span></span><br><span class="line"><span class="string">                不能够顺利转换的场景</span></span><br><span class="line"><span class="string">                    新式类和经典类</span></span><br><span class="line"><span class="string">                        描述器仅在新式类中生效</span></span><br><span class="line"><span class="string">                    方法拦截</span></span><br><span class="line"><span class="string">                        一个实例属性的正常访问顺序</span></span><br><span class="line"><span class="string">                            实例对象自身的__dict__字典</span></span><br><span class="line"><span class="string">                            对应类对象的__dict__字典</span></span><br><span class="line"><span class="string">                            如果有父类, 会再往上层的__dict__字典中检测</span></span><br><span class="line"><span class="string">                            如果没找到, 又定义了__getattr__方法, 就会调用这个方法</span></span><br><span class="line"><span class="string">                        而在上述的整个过程当中, 是如何将描述器的__get__方法给嵌入到查找机制当中?</span></span><br><span class="line"><span class="string">                        就是通过这个方法进行实现</span></span><br><span class="line"><span class="string">                            __getattribute__</span></span><br><span class="line"><span class="string">                            内部实现模拟</span></span><br><span class="line"><span class="string">                                如果实现了描述器方法__get__就会直接调用</span></span><br><span class="line"><span class="string">                                如果没有, 则按照上面的机制去查找</span></span><br><span class="line"><span class="string">            注意</span></span><br><span class="line"><span class="string">                &quot;资料描述器&quot;和&quot;非资料描述器&quot;</span></span><br><span class="line"><span class="string">                    如果实现了</span></span><br><span class="line"><span class="string">                        _get__</span></span><br><span class="line"><span class="string">                        判定为&quot;非资料描述器&quot;</span></span><br><span class="line"><span class="string">                    如果实现了</span></span><br><span class="line"><span class="string">                        __get__</span></span><br><span class="line"><span class="string">                        __set__</span></span><br><span class="line"><span class="string">                        判定为&quot;资料描述器&quot;</span></span><br><span class="line"><span class="string">                描述器和实例属性同名时, 操作的优先级问题</span></span><br><span class="line"><span class="string">                    资料描述器 &gt; 实例字典 &gt; 非资料描述器</span></span><br><span class="line"><span class="string">        装饰器</span></span><br><span class="line"><span class="string">            使用类当做装饰器来使用</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="2-14-浅拷贝与深拷贝"><a href="#2-14-浅拷贝与深拷贝" class="headerlink" title="2.14  浅拷贝与深拷贝"></a>2.14  浅拷贝与深拷贝</h4><ul><li><p>变量的赋值操作：只是形成两个变量，实际上还是指向同一个对象</p></li><li><p>浅拷贝：python拷贝一般都是浅拷贝，使用copy模块的copy函数拷贝时，对象包含的子对象内容不拷贝，因此源对象与拷贝对象会引用同一个子对象</p></li><li><p>深拷贝：使用copy模块的deepcopy函数，递归拷贝对象中包含的子对象，源对象与拷贝对象的所有子对象也不同</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># -----------------------深拷贝-----------------------------------</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Cpu</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, value</span>):</span><br><span class="line">        self.cpu = value</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Disk</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, value</span>):</span><br><span class="line">        self.disk = value</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Computer</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, cpu, disk</span>):</span><br><span class="line">        self.cpu = cpu</span><br><span class="line">        self.disk = disk</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># print(&quot;--------------变量赋值---------------&quot;)</span></span><br><span class="line"><span class="comment"># num1 = 12</span></span><br><span class="line"><span class="comment"># num2 = num1</span></span><br><span class="line"><span class="comment"># 同时指向一块内存空间</span></span><br><span class="line"><span class="comment"># print(id(num1), id(num2))</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># print(&quot;--------------实例变量赋值---------------&quot;)</span></span><br><span class="line"><span class="comment"># cpu = Cpu(&quot;英特尔&quot;)</span></span><br><span class="line"><span class="comment"># disk = Disk(&quot;联想&quot;)</span></span><br><span class="line"><span class="comment"># computer = Computer(cpu, disk)</span></span><br><span class="line"><span class="comment"># 你要是认为是computer2没有实例化才会一模一样，你也可以实例化，发现就是一样的</span></span><br><span class="line"><span class="comment"># computer2 = computer</span></span><br><span class="line"><span class="comment"># print(computer, computer.disk, computer.cpu)</span></span><br><span class="line"><span class="comment"># print(computer2, computer2.disk, computer2.cpu)</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;--------------实例浅拷贝---------------&quot;</span>)</span><br><span class="line"><span class="comment"># import copy</span></span><br><span class="line"><span class="comment"># cpu = Cpu(&quot;英特尔&quot;)</span></span><br><span class="line"><span class="comment"># disk = Disk(&quot;联想&quot;)</span></span><br><span class="line"><span class="comment"># computer = Computer(cpu, disk)</span></span><br><span class="line"><span class="comment"># computer2 = copy.copy(computer)</span></span><br><span class="line"><span class="comment"># # 只有子对象相同，指明子对象没有拷贝，对象本身拷贝了</span></span><br><span class="line"><span class="comment"># print(computer, computer.disk, computer.cpu)</span></span><br><span class="line"><span class="comment"># print(computer2, computer2.disk, computer2.cpu)</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;--------------实例深拷贝---------------&quot;</span>)</span><br><span class="line"><span class="keyword">import</span> copy</span><br><span class="line">cpu = Cpu(<span class="string">&quot;英特尔&quot;</span>)</span><br><span class="line">disk = Disk(<span class="string">&quot;联想&quot;</span>)</span><br><span class="line">computer = Computer(cpu, disk)</span><br><span class="line">computer2 = copy.deepcopy(computer)</span><br><span class="line"><span class="comment"># 对象本身与他的子对象都拷贝了</span></span><br><span class="line"><span class="built_in">print</span>(computer, computer.disk, computer.cpu)</span><br><span class="line"><span class="built_in">print</span>(computer2, computer2.disk, computer2.cpu)</span><br></pre></td></tr></table></figure></li></ul><h3 id="3-python对象的生命周期，以及周期方法"><a href="#3-python对象的生命周期，以及周期方法" class="headerlink" title="3.python对象的生命周期，以及周期方法"></a>3.python对象的生命周期，以及周期方法</h3><h4 id="3-1-生命周期概念"><a href="#3-1-生命周期概念" class="headerlink" title="3.1  生命周期概念"></a>3.1  生命周期概念</h4><ul><li>指的是一个对象, 从诞生到消亡的过程</li><li>当一个对象被创建时, 会在内存中分配相应的内存空间进行存储</li><li>当这个对象不再使用, 为了节约内存, 就会把这个对象释放</li></ul><h4 id="3-2-涉及问题"><a href="#3-2-涉及问题" class="headerlink" title="3.2  涉及问题"></a>3.2  涉及问题</h4><ul><li>如何监听一个对象的生命过程?</li><li>Python是如何掌控一个对象的生命?</li></ul><h4 id="3-3-监听对象生命周期"><a href="#3-3-监听对象生命周期" class="headerlink" title="3.3  监听对象生命周期"></a>3.3  监听对象生命周期</h4><p><a href="# 2.13  内置特殊方法">返回</a></p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">__new__方法</span></span><br><span class="line"><span class="string">当我们创建一个对象是, 用于给这个对象分配内存的方法</span></span><br><span class="line"><span class="string">通过拦截这个方法, 可以修改对象的创建过程</span></span><br><span class="line"><span class="string">比如:单例设计模式</span></span><br><span class="line"><span class="string">__init__方法</span></span><br><span class="line"><span class="string">每个对象实例化的时候，都会自动执行这个方法</span></span><br><span class="line"><span class="string">可以在这个方法里面，初始化一些实例属性</span></span><br><span class="line"><span class="string">__del__方法</span></span><br><span class="line"><span class="string">当对象被释放的时候调用这个方法</span></span><br><span class="line"><span class="string">可用于在这个方法中清理资源</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="3-4-内存管理机制-存储方面"><a href="#3-4-内存管理机制-存储方面" class="headerlink" title="3.4  内存管理机制-存储方面"></a>3.4  内存管理机制-存储方面</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">1. 在Python中万物皆对象</span></span><br><span class="line"><span class="string">* 不存在基本数据类型</span></span><br><span class="line"><span class="string">* 0,  1.2,  True, False, &quot;abc&quot;,这些全都是对象</span></span><br><span class="line"><span class="string">2. 所有对象, 都会在内存中开辟一块空间进行存储</span></span><br><span class="line"><span class="string">* 会根据不同的类型以及内容, 开辟不同的空间大小进行存储</span></span><br><span class="line"><span class="string">* 返回该空间的地址给外界接收(称为&quot;引用&quot;), 用于后续对这个对象的操作</span></span><br><span class="line"><span class="string">a.可通过id()函数获取内存地址(10进制)</span></span><br><span class="line"><span class="string">b.通过hex()函数可以查看对应的16进制地址</span></span><br><span class="line"><span class="string">3. 对于整数和短小的字符, Python会进行缓存; 不会创建多个相同对象;此时, 被多次赋值, 只会有多份引用</span></span><br><span class="line"><span class="string">4. 容器对象, 存储的其他对象, 仅仅是其他对象的引用, 并不是其他对象本身</span></span><br><span class="line"><span class="string">* 比如字典, 列表, 元组这些&quot;容器对象&quot;</span></span><br><span class="line"><span class="string">* 全局变量是由一个大字典进行引用;global()查看</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="3-5-内存管理机制-垃圾回收方面"><a href="#3-5-内存管理机制-垃圾回收方面" class="headerlink" title="3.5  内存管理机制-垃圾回收方面"></a>3.5  内存管理机制-垃圾回收方面</h4><ol><li><p><strong>引用计数器机制</strong></p><ul><li>概念<pre><code>一个对象, 会记录着自身被引用的个数，每增加一个引用, 这个对象的引用计数会自动+1，每减少一个引用, 这个对象的引用计数会自动-1</code></pre></li></ul></li><li><p>举例</p><ul><li>引用计数+1场景<ul><li>对象被创建<pre><code>        p1 = Person()</code></pre></li><li>对象被引用<pre><code>        p2 = p1</code></pre></li><li>对象被作为参数，传入到一个函数中<pre><code>        log(p1)          这里注意会+2, 因为内部有两个属性引用着这个参数</code></pre></li><li>对象作为一个元素，存储在容器中<pre><code>        l = [p1]</code></pre></li></ul></li><li>引用计数-1场景<ul><li>对象的别名被显式销毁<pre><code>        del p1</code></pre></li><li>对象的别名被赋予新的对象<pre><code>        p1 = 123</code></pre></li><li>一个对象离开它的作用域<pre><code>         a.一个函数执行完毕时;               b.内部的局部变量关联的对象, 它的引用计数就会-1;</code></pre></li><li>对象所在的容器被销毁，或从容器中删除对象</li></ul></li></ul></li><li><p>查看引用计数</p></li></ol>   <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> sys</span><br><span class="line">sys.getrefcount(对象)    <span class="comment"># **注意会大1，结果要减1**</span></span><br></pre></td></tr></table></figure><p>   ​    </p><ol><li><p><strong>垃圾回收机制</strong></p><ul><li><p>主要作用：从经历过”引用计数器机制”仍未被释放的对象中, 找到”循环引用”, 干掉相关对象</p></li><li><p>底层机制(了解&amp;难)</p><ul><li><p>怎样找到”循环引用”?</p><pre><code>           1. 收集所有的&quot;容器对象&quot;, 通过一个双向链表进行引用                 容器对象                     可以引用其他对象的对象                         列表                         元组                         字典                         自定义类对象                         ...                 非容器对象                     不能引用其他对象的对象                         数值                         字符串                         布尔                         ...                     注意: 针对于这些对象的内存, 有其他的管理机制                2. 针对于每一个&quot;容器对象&quot;, 通过一个变量gc_refs来记录当前对应的引用计数                3. 对于每个&quot;容器对象&quot;，找到它引用的&quot;容器对象&quot;, 并将这个&quot;容器对象&quot;的引用计数 -1                4. 经过步骤3之后, 如果一个&quot;容器对象&quot;的引用计数为0, 就代表这玩意可以被回收了, 肯定是&quot;循环引用&quot;导致它活到现在的</code></pre></li><li><p>如何提升查找”循环引用”的性能?</p><ul><li><p>如果程序当中创建了很多个对象, 而针对于每一个对象都要参与”检测”过程; 则会非常的耗费性能</p></li><li><p>所以, 基于这个问题, 产生了一种假设:</p><pre><code>            a.越命大的对象, 越长寿                  b.假设一个对象10次检测都没给它干掉, 那认定这个对象一定很长寿, 就减少这货的&quot;检测频率&quot;</code></pre></li><li><p>基于这种假设, 设计了一套机制</p><pre><code>            1.分代回收机制</code></pre><p>​                    a.默认一个对象被创建出来后, 属于 0 代</p><p>​                    b.如果经历过这一代”垃圾回收”后, 依然存活, 则划分到下一代</p><p>​                    c.”垃圾回收”的周期顺序为</p><p>​                      1）0代”垃圾回收”一定次数, 会触发 0代和1代回收<br>​                      2）1代”垃圾回收”一定次数, 会触发0代, 1代和2代回收</p><p>​                2.查看和设置相关参数<br>​                    import gc<br>​                    print(gc.get_threshold())<br>​                    gc.set_threshold(700, 10, 5)<br>​                    垃圾回收器当中, 新增的对象个数-消亡的对象个数 , 达到一定的阈值时, 才会触发, 垃圾检测</p></li></ul></li></ul></li><li><p>垃圾回收时机(掌握&amp;简单)</p><pre><code>    1. 自动回收 - 触发条件                   开启垃圾回收机制                       gc.enable()                           开启垃圾回收机制(默认开启)                       gc.disable()                           关闭垃圾回收机制                       gc.isenabled()                           判定是否开启                   并且达到了垃圾回收的阈值                       垃圾回收器中, 新增的对象个数和释放的对象个数之差到达某个阈值                       涉及方法                           gc.get_threshold()                               获取自动回收阈值                           gc.set_threshold()                               设置自动回收阈值      2. 手动回收 - 触发条件               gc.collect()                    执行一次垃圾回收(开关状态无效)                </code></pre></li></ul></li><li><p>测量对象的引用个数<br>辅助工具</p><pre><code>    objgraph        http://mg.pov.lt/objgraph/        xdot        graphviz</code></pre></li></ol><h4 id="3-6-面向综合案例"><a href="#3-6-面向综合案例" class="headerlink" title="3.6  面向综合案例"></a>3.6  面向综合案例</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 私有装饰器</span></span><br><span class="line"><span class="keyword">import</span> win32com.client</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建播报器对象(window系统适用)</span></span><br><span class="line"><span class="comment"># speaker = win32com.client.Dispatch(&quot;SAPI.SpVoice&quot;)</span></span><br><span class="line"><span class="comment"># 通过播报器对象，播报语音字符串</span></span><br><span class="line"><span class="comment"># speaker.Speak(&quot;你好,小谢&quot;)</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Calc</span>:</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 注意这里需要有self参数</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__say_decorator</span>(<span class="params">self, word</span>):</span><br><span class="line">        <span class="comment"># 创建播报器对象(window系统适用)</span></span><br><span class="line">        speaker = win32com.client.Dispatch(<span class="string">&quot;SAPI.SpVoice&quot;</span>)</span><br><span class="line">        <span class="comment"># 通过播报器对象，播报语音字符串</span></span><br><span class="line">        speaker.Speak(word)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__create_say_decorator</span>(<span class="params">operator_sign=<span class="string">&quot;&quot;</span></span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">say_decorator</span>(<span class="params">func</span>):</span><br><span class="line">            <span class="keyword">def</span> <span class="title function_">inner</span>(<span class="params">self, num</span>):</span><br><span class="line">                self.__say_decorator(operator_sign + <span class="built_in">str</span>(num))</span><br><span class="line">                <span class="keyword">return</span> func(self, num)</span><br><span class="line"></span><br><span class="line">            <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> say_decorator</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__check_num_decorator</span>(<span class="params">func</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">inner</span>(<span class="params">self, num</span>):</span><br><span class="line">            <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">isinstance</span>(num, <span class="built_in">int</span>):</span><br><span class="line">                <span class="keyword">raise</span> TypeError(<span class="string">&quot;类型错误，应该是一个整型数据&quot;</span>)</span><br><span class="line">            <span class="keyword">return</span> func(self, num)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="meta">    @__check_num_decorator</span></span><br><span class="line"><span class="meta">    @__create_say_decorator()</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, num</span>):</span><br><span class="line">        self.__res = num</span><br><span class="line"></span><br><span class="line"><span class="meta">    @__check_num_decorator</span></span><br><span class="line"><span class="meta">    @__create_say_decorator(<span class="params"><span class="string">&quot;加上&quot;</span></span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">add_method</span>(<span class="params">self, value</span>):</span><br><span class="line">        self.__res += value</span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line"><span class="meta">    @__check_num_decorator</span></span><br><span class="line"><span class="meta">    @__create_say_decorator(<span class="params"><span class="string">&quot;减去&quot;</span></span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">sub_method</span>(<span class="params">self, value</span>):</span><br><span class="line">        self.__res -= value</span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line"><span class="meta">    @__check_num_decorator</span></span><br><span class="line"><span class="meta">    @__create_say_decorator(<span class="params"><span class="string">&quot;乘以&quot;</span></span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">mut_method</span>(<span class="params">self, value</span>):</span><br><span class="line">        self.__res *= value</span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line"><span class="meta">    @__check_num_decorator</span></span><br><span class="line"><span class="meta">    @__create_say_decorator(<span class="params"><span class="string">&quot;除以&quot;</span></span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">div_method</span>(<span class="params">self, value</span>):</span><br><span class="line">        self.__res //= value</span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line">    <span class="comment"># @__say_decorator</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">show_value</span>(<span class="params">self</span>):</span><br><span class="line">        str1 = <span class="string">f&quot;计算结果是<span class="subst">&#123;self.__res&#125;</span>&quot;</span></span><br><span class="line">        self.__say_decorator(str1)</span><br><span class="line">        <span class="built_in">print</span>(str1)</span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">clear</span>(<span class="params">self</span>):</span><br><span class="line">        self.__res = <span class="number">0</span></span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">result</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> self.__res</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">calc = Calc(<span class="number">100</span>)</span><br><span class="line">calc.add_method(<span class="number">56</span>).sub_method(<span class="number">30</span>).mut_method(<span class="number">3</span>).div_method(<span class="number">120</span>).show_value().clear().sub_method(<span class="number">200</span>).show_value()</span><br><span class="line"><span class="built_in">print</span>(calc.result)</span><br></pre></td></tr></table></figure><h3 id="4-面向对象三大特性"><a href="#4-面向对象三大特性" class="headerlink" title="4.面向对象三大特性"></a>4.面向对象三大特性</h3><h4 id="4-1-封装"><a href="#4-1-封装" class="headerlink" title="4.1  封装"></a>4.1  封装</h4><ul><li>封装概念：将一些属性和相关方法封装在一个对象中对外隐藏内部具体实现细节内部实现, 外界不需要关心，外界只需要根据”内部提供的接口”去使用就可以</li><li>好处：<pre><code>1. 使用起来更加方便- 因为已经把很多相关的功能, 封装成一个整体- 类似于像外界提供一个工具箱- 针对于不同的场景, 使用不同的工具箱就可以2. 保证数据的安全- 针对于安全级别高的数据, 可以设置成&quot;私有&quot;;- 可以控制数据为只读，外界无法修改- 也可以拦截数据的写操作，进行数据校验和过滤3. 利于代码维护- 如果后期, 功能代码需要维护, 则直接修改这个类内部代码即可; - 只要保证接口名称不变; 外界不需要做任何代码修改</code></pre></li><li><strong><a href="#3.6  面向综合案例">案例</a></strong></li></ul><h4 id="4-2-继承"><a href="#4-2-继承" class="headerlink" title="4.2  继承"></a>4.2  继承</h4><p>概念：</p><ul><li>现实中的”继承：”子女继承父母的”财产资源”</li><li>编程中的”继承”：一个类”拥有”另外一个类的”资源”的方式之一<ul><li>“拥有”：并不是资源的复制, 变成双份资源，而是, 资源的”使用权”</li><li>“资源”：指”非私有的”属性和方法</li></ul></li><li>例子：Dog类继承自Animal类<pre><code>Dog：**子类、派生类**Animal：**父类、基类、超类**        </code></pre></li><li>目的：方便资源重用</li></ul><h5 id="4-2-1-继承的分类"><a href="#4-2-1-继承的分类" class="headerlink" title="4.2.1  继承的分类"></a>4.2.1  继承的分类</h5><ol><li><p>单继承</p><ul><li><p>概念：仅仅继承了一个父类</p></li><li><p>语法：</p></li></ul></li></ol><pre><code> <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Dog</span>(<span class="title class_ inherited__">Animal</span>):</span><br><span class="line"><span class="keyword">pass</span></span><br></pre></td></tr></table></figure></code></pre><ol><li><p>多继承</p><ul><li><p>概念：继承了多个父类</p></li><li><p>语法</p></li></ul></li></ol><pre><code> <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">child</span>(Father, Mather):</span><br><span class="line"><span class="keyword">pass</span></span><br></pre></td></tr></table></figure></code></pre><h5 id="4-2-2-type与object区分"><a href="#4-2-2-type与object区分" class="headerlink" title="4.2.2  type与object区分"></a>4.2.2  type与object区分</h5><ul><li><p>type和object：</p><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221006142501585.png" alt="type类与object类关系"></p></li><li><p>新式类：直接或者间接继承自object的类(python3.x没有显式继承object，但实际继承了object)</p></li><li>经典类：没有直接或者间接继承自object的类(python2.x没有显式继承object，需要手动继承了object)</li></ul><h5 id="4-2-3-继承的影响"><a href="#4-2-3-继承的影响" class="headerlink" title="4.2.3  继承的影响"></a>4.2.3  继承的影响</h5><ol><li><p>资源的继承</p><ul><li>明确：<pre><code>在Python中, 继承是指, 资源的使用权；所以, 测试某个资源能否被继承, 其实就是测试在子类当中, 能不能访问到父类当中的这个资源</code></pre></li><li>结论：<pre><code>除下私有的属性和私有的方法, 其他的基本都能继承    公有属性/方法    受保护属性/方法    内置方法</code></pre></li></ul></li><li><p>资源的使</p><ul><li><p>继承的几种形态</p><ul><li><p>单继承链：一个子类只有一个父类</p></li><li><p>无重叠的多继承链：继承链无交叉, 无公共父类</p></li><li><p>有重叠的多继承链：继承链有交叉, 有公共父类</p><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221006150741811.png" alt="image-20221006150741811"></p></li></ul></li><li><p>几种形态应该遵循的标准原则</p><ul><li><p>单继承：遵循”从下到上的原则”，自己身上没有这个资源, 就到父类里面去找, 父类里面没有再往上找</p></li><li><p>无重叠的多继承：遵循”单调原则”，按照继承的先后顺序, 优先调用左侧继承链上的资源</p></li><li><p>有重叠的多继承：遵循”从下到上的原则”，简单理解就是A继承B继承C，B重写了C类的方法, 那么A优先使用B类的方法</p><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221006151628533.png" alt="image-20221006151628533"></p></li></ul></li><li><p>针对于几种标准原则的方案演化</p><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221006171854397.png" alt=""></p><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221006164328361.png" alt="image-20221006164328361"></p></li><li><p>查看顺序：</p></li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> inspect</span><br><span class="line"><span class="comment"># 查看资源顺序三种方式</span></span><br><span class="line"><span class="built_in">print</span>(inspect.getmro(A))</span><br><span class="line"><span class="built_in">print</span>(A.mro())</span><br><span class="line"><span class="built_in">print</span>(A.__mro__)</span><br></pre></td></tr></table></figure></li></ol><ol><li><p>资源的覆盖（<strong>属性覆盖，方法重写</strong>）</p><ul><li><p>原理：</p><p>在MRO的资源检索链当中，优先级比较高的类写了一个和优先级比较低的类一样的一个资源(属性或方法)，到时候, 再去获取相关资源, 就会优先选择优先级比较高的资源;，而摒弃优先级比较低的资源; 造成”覆盖”的假象。</p></li><li><p>注意事项：当调用优先级比较高的资源时, 注意self的变化</p></li></ul></li><li><p>资源的累加：在一个类的基础之上, 增加一些额外的资源</p><p>子类相比于父类, 多一些自己特有的资源，直接添加</p><p>在被覆盖的方法基础之上, 新增内容：</p><ul><li><p>方案一：在高优先级类的方法中, 通过”类名”调用低优先级类的方法，弊端是代码维护性差、容易产生重复调用；</p></li><li><p>方案二：在低优先级类的方法中, 通过”super”调用高优先级类的方法</p><ul><li><p>概念：一个类，在新式类中有效</p></li><li><p>作用：</p><ul><li>起着代理的作用, 帮我们完成以下任务</li><li>沿着MRO链条, 找到下一级节点, 去调用对应的方法</li></ul></li><li><p>问题：沿着谁的MRO链条? 找谁的下一个节点? 如何应对类方法, 静态方法以及实例方法的传参问题?</p></li><li><p>语法原理：</p><ul><li><p>super(参数1[, 参数2])      参数1：当前类，参数2为当前类获实例</p></li><li><p>工作原理：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">super</span>(<span class="params">cls, inst</span>):</span><br><span class="line">    mro = inst.__class__.mro()</span><br><span class="line">    <span class="keyword">return</span> mro[mro.index(cls) + <span class="number">1</span>]</span><br></pre></td></tr></table></figure></li><li><p>问题解决：</p><ul><li>沿着参数2的MRO链条；</li><li>找参数1的下一个节点；</li><li>如何应对类方法, 静态方法以及实例方法的传参问题，使用参数2调用</li></ul></li></ul></li><li><p>常用具体语法形式：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"># python2.2+</span><br><span class="line">super(type, obj) -&gt; bound super object; </span><br><span class="line"># 需要链条的类与实例</span><br><span class="line">requires isinstance(obj, type)</span><br><span class="line"></span><br><span class="line">super(type, type2) -&gt; bound super object;</span><br><span class="line"># 需要链条的类</span><br><span class="line">requires issubclass(type2, type)</span><br><span class="line"></span><br><span class="line"># python3+</span><br><span class="line">super()</span><br></pre></td></tr></table></figure></li><li><p>注意：</p><ul><li>super 和父类(超类)没有实质性的关联，仅仅是沿着MRO链条, 找到下一级节点；</li><li>保证调用形式的统一：要是类名调用, 全是类名调用；要是super调用, 全是super调用</li><li>参数不要使用self.<strong>class</strong>，可能会死循环</li></ul></li></ul></li></ul></li></ol><h4 id="4-3-多态"><a href="#4-3-多态" class="headerlink" title="4.3  多态"></a>4.3  多态</h4><ul><li>一个类, 所延伸的多种形态</li><li>在继承的前提下; 使用不同的子类, 调用父类的同一个方法, 产生不同的功能 </li><li>调用时的多种形态</li><li>多态在Python中的体现：关注点在于对象的”行为和属性”; 而非对象的”类型”，与其他语言不同的是python的动态类型语言，只要对象有该方法，就可以调用，所以python没有真正意义上多态。</li></ul><h4 id="4-4-抽象类、抽象方法"><a href="#4-4-抽象类、抽象方法" class="headerlink" title="4.4  抽象类、抽象方法"></a>4.4  抽象类、抽象方法</h4><ul><li>抽象类：抽象出来的类，没有具体的实现，不能创建实例，否则会报错</li><li>抽象方法：抽象出来的方法，没有具体实现，不能直接被调用，需要子类实现（子类不实现会报错）</li><li><p>python中实现抽象：</p><ul><li>无法直接实现，需要导入模块 <strong>import abc</strong></li><li>设置类的元类为 <strong>abc.ABCMeta</strong></li><li>使用装饰器修饰抽象方法 <strong>@abc.abstractmethod</strong></li><li>抽象类方法@classmethod + @abc.abstractmethod等等</li></ul></li><li><p><a href="https://docs.python.org/zh-cn/3.9/library/abc.html">具体抽象方法和属性实现查看官方文档</a></p></li></ul><h4 id="4-5-面向对象三大特性综合案例"><a href="#4-5-面向对象三大特性综合案例" class="headerlink" title="4.5   面向对象三大特性综合案例"></a>4.5   面向对象三大特性综合案例</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, age=<span class="number">1</span></span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">eat</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self&#125;</span>吃饭&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">play</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self&#125;</span>玩&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">sleep</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self&#125;</span>睡觉&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Dog</span>(<span class="title class_ inherited__">Animal</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">self</span>):</span><br><span class="line">        self.__see_home()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__see_home</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self&#125;</span>在看家&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&quot;名字是<span class="subst">&#123;self.name&#125;</span>, 年龄<span class="subst">&#123;self.age&#125;</span>岁的小狗在&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Cat</span>(<span class="title class_ inherited__">Animal</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">work</span>(<span class="params">self</span>):</span><br><span class="line">        self.__catch_mouse()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__catch_mouse</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self&#125;</span>捉老鼠&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&quot;名字是<span class="subst">&#123;self.name&#125;</span>, 年龄<span class="subst">&#123;self.age&#125;</span>岁的小猫&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>(<span class="title class_ inherited__">Animal</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, pets, age=<span class="number">1</span></span>):</span><br><span class="line">        <span class="built_in">super</span>(Person, self).__init__(name, age)</span><br><span class="line">        self.pets = pets</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">keep_pets</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">for</span> pet <span class="keyword">in</span> self.pets:</span><br><span class="line">            pet.eat()</span><br><span class="line">            pet.play()</span><br><span class="line">            pet.sleep()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">make_pets_work</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">for</span> pet <span class="keyword">in</span> self.pets:</span><br><span class="line">            pet.work()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&quot;名字是<span class="subst">&#123;self.name&#125;</span>, 年龄<span class="subst">&#123;self.age&#125;</span>岁的天才&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">dog = Dog(<span class="string">&quot;旺财&quot;</span>, <span class="number">12</span>)</span><br><span class="line"><span class="comment"># dog.eat()</span></span><br><span class="line"><span class="comment"># dog.sleep()</span></span><br><span class="line">cat = Cat(<span class="string">&quot;小花&quot;</span>)</span><br><span class="line">person = Person(<span class="string">&quot;xie&quot;</span>, [dog, cat], <span class="number">15</span>)</span><br><span class="line"><span class="built_in">print</span>(person)</span><br><span class="line">person.keep_pets()</span><br><span class="line">person.make_pets_work()</span><br></pre></td></tr></table></figure><h3 id="5-py异常处理"><a href="#5-py异常处理" class="headerlink" title="5.py异常处理"></a>5.py异常处理</h3><h4 id="5-1-异常和错误的概念"><a href="#5-1-异常和错误的概念" class="headerlink" title="5.1  异常和错误的概念"></a>5.1  异常和错误的概念</h4><ul><li><p>错误：没法通过其他的代码进行处理的问题</p><ol><li><p>语法错误</p><ul><li>比如定义函数写成了 dfe xxx()</li><li>这种错误, 可以直接通过IDE或者解释器给出的提示进行修改</li></ul></li><li><p>逻辑错误</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">语法层面没有问题, 但是自己设计的逻辑出现问题</span><br><span class="line">例如</span><br><span class="line">用户输入年龄, 判定是否成年</span><br><span class="line"><span class="keyword">if</span> age &lt; <span class="number">18</span>:</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;已经成年&quot;</span>)</span><br><span class="line">这种错误, IDE或者解释器无法帮我们检测出, 只有我们通过代码测试进行排查</span><br></pre></td></tr></table></figure></li></ol></li><li><p>异常：多指程序在执行的过程中, 出现的未知错误; 语法和逻辑都是正确的; 可以通过其他代码进行处理修复</p><ul><li>接收输入整型但输入了字符串，还强制转换，抛异常</li><li>0作为除数，抛异常</li><li>列表或字典，索引或键的异常等等</li></ul></li></ul><h4 id="5-2-常见的系统异常"><a href="#5-2-常见的系统异常" class="headerlink" title="5.2  常见的系统异常"></a>5.2  常见的系统异常</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">除零异常</span></span><br><span class="line"><span class="string">    示例代码</span></span><br><span class="line"><span class="string">        1 / 0</span></span><br><span class="line"><span class="string">    异常名称</span></span><br><span class="line"><span class="string">        ZeroDivisionError</span></span><br><span class="line"><span class="string">名称异常</span></span><br><span class="line"><span class="string">    示例代码</span></span><br><span class="line"><span class="string">        sz</span></span><br><span class="line"><span class="string">    异常名称</span></span><br><span class="line"><span class="string">        NameError</span></span><br><span class="line"><span class="string">类型异常</span></span><br><span class="line"><span class="string">    示例代码</span></span><br><span class="line"><span class="string">        &quot;1&quot; + 2</span></span><br><span class="line"><span class="string">    异常名称</span></span><br><span class="line"><span class="string">        TypeError</span></span><br><span class="line"><span class="string">索引异常</span></span><br><span class="line"><span class="string">    示例代码</span></span><br><span class="line"><span class="string">        l = [1, 2]</span></span><br><span class="line"><span class="string">l[3]</span></span><br><span class="line"><span class="string">    异常名称</span></span><br><span class="line"><span class="string">        IndexError</span></span><br><span class="line"><span class="string">键异常</span></span><br><span class="line"><span class="string">    示例代码</span></span><br><span class="line"><span class="string">        dic = &#123;&quot;name&quot;: &quot;sz&quot;, &quot;age&quot;: 18&#125;</span></span><br><span class="line"><span class="string">dic[&quot;add&quot;]</span></span><br><span class="line"><span class="string">    异常名称</span></span><br><span class="line"><span class="string">        KeyError</span></span><br><span class="line"><span class="string">值异常</span></span><br><span class="line"><span class="string">    示例代码</span></span><br><span class="line"><span class="string">        int(&quot;abc&quot;)</span></span><br><span class="line"><span class="string">    异常名称</span></span><br><span class="line"><span class="string">        ValueError</span></span><br><span class="line"><span class="string">属性异常</span></span><br><span class="line"><span class="string">    示例代码</span></span><br><span class="line"><span class="string">        name = &quot;sz&quot;</span></span><br><span class="line"><span class="string">print(name.xx)</span></span><br><span class="line"><span class="string">    异常名称</span></span><br><span class="line"><span class="string">        AttributeError</span></span><br><span class="line"><span class="string">迭代器异常</span></span><br><span class="line"><span class="string">    示例代码</span></span><br><span class="line"><span class="string">        it = iter([1, 2])</span></span><br><span class="line"><span class="string">print(next(it))</span></span><br><span class="line"><span class="string">print(next(it))</span></span><br><span class="line"><span class="string">print(next(it))</span></span><br><span class="line"><span class="string">    异常名称</span></span><br><span class="line"><span class="string">        StopIteration</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><ul><li><p>系统异常类继承树:</p><p>BaseException 所有内建的异常的基类:</p><ul><li>SystemExit:由sys.exit()函数引发。当它不处理时，Python 解释器退出</li><li>KeyboardInterrupt: 当用户点击中断键 （通常ctrl + C） 时引发</li><li>GeneratorExit: 当调用一种generator的close()方法时引发。</li><li>Exception:所有内置的、 非系统退出异常是从该类派生的。应该从该类派生所有用户定义的异常。</li></ul></li></ul><h4 id="5-3-解决异常"><a href="#5-3-解决异常" class="headerlink" title="5.3  解决异常"></a>5.3  解决异常</h4><p>系统一开始已经内置了一些特定的应用场景; 当我们写代码的过程当中, 一旦触发了这个场景, 系统内部就会自动的向外界抛出这个问题, 也就是我们所谓的异常；不做处理，程序被终止执行; 软件的崩溃。</p><h5 id="5-3-1-预防异常：添加容错代码"><a href="#5-3-1-预防异常：添加容错代码" class="headerlink" title="5.3.1  预防异常：添加容错代码"></a>5.3.1  预防异常：添加容错代码</h5><p>弊端：容错代码不属于我们主要的业务逻辑; 如果容错代码过多, 会造成代码混乱, 主业务不清晰</p><h5 id="5-3-2-解决异常"><a href="#5-3-2-解决异常" class="headerlink" title="5.3.2  解决异常"></a>5.3.2  解决异常</h5><ol><li>方式一处理异常</li></ol><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">方式一处理异常</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="comment"># 这里不管以后会抛出多少个异常, 只会从上往下检测, 检测到一个后, 就立即往下去匹配, 不会多次检测</span></span><br><span class="line">    可能会出现异常的代码</span><br><span class="line"><span class="keyword">except</span> 你要捕捉的异常类别 <span class="keyword">as</span>(Python3使用<span class="keyword">as</span>, python使用英文逗号) 接收异常的形参:</span><br><span class="line">    <span class="comment"># 这一块可以有多个重复, 用于捕捉可能的其他异常; 如果针对于多个不同的异常有相同的处理方式, 那么可以将多个异常合并,通过写出元组合并</span></span><br><span class="line">    对于这个异常的处理</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="comment"># 这一块必须放在上一块except结束后(可以省略)</span></span><br><span class="line">    没出现异常时做的处理</span><br><span class="line"><span class="keyword">finally</span>:</span><br><span class="line">    <span class="comment"># 这一块必须放最后(可以省略)</span></span><br><span class="line">    不管有没有出现异常, 都会执行的代码</span><br><span class="line">    </span><br><span class="line">注意：</span><br><span class="line">    <span class="keyword">try</span>语句没有捕获到异常，先执行<span class="keyword">try</span>代码段后，在执行<span class="keyword">else</span>，最后执行<span class="keyword">finally</span></span><br><span class="line">    如果<span class="keyword">try</span>捕获异常，首先执行<span class="keyword">except</span>处理错误，然后执行<span class="keyword">finally</span></span><br><span class="line">    如果异常名称不确定, 而又想捕捉, 可以直接写Exception</span><br></pre></td></tr></table></figure><ol><li><p>方式二处理异常</p><ul><li><p>作用：适用于执行某一段代码A之前, 进行预处理, 执行代码A结束后, 进行清理操作；不管出现了什么异常, 最终都要执行一些清理操作</p></li><li><p>语法：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">with</span> context_expression [<span class="keyword">as</span> target(s)]:</span><br><span class="line"><span class="keyword">with</span>-body</span><br></pre></td></tr></table></figure></li></ul></li></ol><ul><li><p>语法图解：</p><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221006225941194.png" alt="语法土家"></p></li><li><p>示例：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    f = <span class="built_in">open</span>(<span class="string">&quot;m5.jpg&quot;</span>, <span class="string">&quot;r&quot;</span>)</span><br><span class="line">    f.readlines()</span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br><span class="line"><span class="keyword">finally</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;ccc&quot;</span>)</span><br><span class="line">    f.close()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 但是以上写法过于繁琐, 于是有了这个方案</span></span><br><span class="line"><span class="comment"># 但是如果产生了异常, 依然会报错; 并没有进行异常处理操作</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&quot;m5.jpg&quot;</span>, <span class="string">&quot;r&quot;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    f.readlines()</span><br></pre></td></tr></table></figure><p>3.自定义上下文管理器</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> traceback</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Test</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__enter__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;enter&quot;</span>)</span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__exit__</span>(<span class="params">self, exc_type, exc_val, exc_tb</span>):</span><br><span class="line">        <span class="built_in">print</span>(self, exc_type, exc_val, exc_tb)</span><br><span class="line">        <span class="built_in">print</span>(traceback.extract_tb(exc_tb))</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;exit&quot;</span>)</span><br><span class="line">        <span class="comment"># True 不显示异常信息， False:显示异常信息</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> Test() <span class="keyword">as</span> x:</span><br><span class="line">    <span class="comment"># print(&quot;body&quot;, x)</span></span><br><span class="line">    <span class="number">1</span> / <span class="number">0</span></span><br><span class="line">    </span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">定义的类, 实现&quot;上下文管理协议&quot;</span></span><br><span class="line"><span class="string">    __enter__</span></span><br><span class="line"><span class="string">        做一些预处理操作</span></span><br><span class="line"><span class="string">    __exit__</span></span><br><span class="line"><span class="string">        做一些清理操作</span></span><br><span class="line"><span class="string">        接收抛出的异常</span></span><br><span class="line"><span class="string">        如果返回True, 则忽略异常; 如果返回的False, 则再次抛出异常</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li></ul><ol><li><p>contextlib 模块</p></li><li><p>```python<br>import contextlib</p></li></ol><h1 id="contextlib-contextmanager"><a href="#contextlib-contextmanager" class="headerlink" title="@contextlib.contextmanager"></a>@contextlib.contextmanager</h1><h1 id="def-test"><a href="#def-test" class="headerlink" title="def test():"></a>def test():</h1><h1 id="enter方法的具体实现"><a href="#enter方法的具体实现" class="headerlink" title="# enter方法的具体实现"></a># <strong>enter</strong>方法的具体实现</h1><h1 id="print-1"><a href="#print-1" class="headerlink" title="print(1)"></a>print(1)</h1><h1 id="exit方法的具体实现"><a href="#exit方法的具体实现" class="headerlink" title="# exit方法的具体实现"></a># <strong>exit</strong>方法的具体实现</h1><h1 id="yield-“kkkk”"><a href="#yield-“kkkk”" class="headerlink" title="yield “kkkk”"></a>yield “kkkk”</h1><h1 id="print-2"><a href="#print-2" class="headerlink" title="print(2)"></a>print(2)</h1><p>   #<br>   #</p><h1 id="with-test-as-x"><a href="#with-test-as-x" class="headerlink" title="with test() as x:"></a>with test() as x:</h1><h1 id="print-3-x"><a href="#print-3-x" class="headerlink" title="print(3, x)"></a>print(3, x)</h1><p>   @contextlib.contextmanager<br>   def ze():<br>       try:<br>           yield<br>       except Exception as e:<br>           print(“error”, e)</p><p>   num1 = 1<br>   num2 = 0</p><p>   with ze():<br>       num1 /num2</p><h1 id="try"><a href="#try" class="headerlink" title="try:"></a>try:</h1><h1 id="num1-num2"><a href="#num1-num2" class="headerlink" title="num1 / num2"></a>num1 / num2</h1><h1 id="except-Exception-as-e"><a href="#except-Exception-as-e" class="headerlink" title="except Exception as e:"></a>except Exception as e:</h1><h1 id="print-“666”"><a href="#print-“666”" class="headerlink" title="print(“666”)"></a>print(“666”)</h1><p>   a = 10<br>   b = 0<br>   with ze():<br>       a / b</p><p>   class Test:<br>       def t(self):<br>           print(“tttt”)</p><pre><code>   # 必须写   def close(self):       print(&quot;资源释放&quot;)   # 使用contextlib.closing取代   # def __enter__(self):   #     return self   #   # def __exit__(self, exc_type, exc_val, exc_tb):   #     self.close()</code></pre><p>   with contextlib.closing(Test()) as test:<br>       test.t()</p><h1 id="python2-7"><a href="#python2-7" class="headerlink" title="python2.7"></a>python2.7</h1><h1 id="with-open-“m5-jpg”-“rb”-as-from-file"><a href="#with-open-“m5-jpg”-“rb”-as-from-file" class="headerlink" title="with open(“m5.jpg”, “rb”) as from_file:"></a>with open(“m5.jpg”, “rb”) as from_file:</h1><h1 id="with-open-“m52-jpg”-“wb”-as-to-file"><a href="#with-open-“m52-jpg”-“wb”-as-to-file" class="headerlink" title="with open(“m52.jpg”, “wb”) as to_file:"></a>with open(“m52.jpg”, “wb”) as to_file:</h1><h1 id="contents-from-file-read"><a href="#contents-from-file-read" class="headerlink" title="contents = from_file.read()"></a>contents = from_file.read()</h1><h1 id="to-file-write-contents"><a href="#to-file-write-contents" class="headerlink" title="to_file.write(contents)"></a>to_file.write(contents)</h1><h1 id="python3-x-以后写法"><a href="#python3-x-以后写法" class="headerlink" title="python3.x, 以后写法"></a>python3.x, 以后写法</h1><p>   with open(“m5.jpg”, “rb”) as from_file, open(“m52.jpg”, “wb”) as to_file:<br>           contents = from_file.read()<br>           to_file.write(contents)</p><h1 id="python2-7之前"><a href="#python2-7之前" class="headerlink" title="python2.7之前"></a>python2.7之前</h1><h1 id="with-contextlib-nested-open-“m5-jpg”-“rb”-open-“m52-jpg”-“wb”-as-from-file-to-file"><a href="#with-contextlib-nested-open-“m5-jpg”-“rb”-open-“m52-jpg”-“wb”-as-from-file-to-file" class="headerlink" title="with contextlib.nested(open(“m5.jpg”, “rb”), open(“m52.jpg”, “wb”)) as (from_file, to_file):"></a>with contextlib.nested(open(“m5.jpg”, “rb”), open(“m52.jpg”, “wb”)) as (from_file, to_file):</h1><h1 id="contents-from-file-read-1"><a href="#contents-from-file-read-1" class="headerlink" title="contents = from_file.read()"></a>contents = from_file.read()</h1><h1 id="to-file-write-contents-1"><a href="#to-file-write-contents-1" class="headerlink" title="to_file.write(contents)"></a>to_file.write(contents)</h1><p>   ‘’’<br>   @contextlib.contextmanager<br>       使用装饰器, 让一个生成器变成一个”上下文管理器”<br>   contextlib.closing<br>       这个函数, 让一个拥有close方法但不是上下文管理器的对象变成”上下文管理器”<br>   contextlib.nested<br>       python2.7之前: 完成多个上下文管理器的嵌套<br>   ‘’’<br>   <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line">#### 5.4  抛出异常</span><br><span class="line"></span><br><span class="line">根据严重程度是抛出异常还是处理解决异常，通过 raise 语句直接抛出相关类型的异常</span><br><span class="line"></span><br><span class="line">```python</span><br><span class="line">def setAge(age):</span><br><span class="line">    if age &lt;= 0 or age &gt; 200:</span><br><span class="line">        raise ValueError(&quot;值错误&quot;)</span><br><span class="line">    else:</span><br><span class="line">        print(age)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">try:</span><br><span class="line">    setAge(-2)</span><br><span class="line">except Exception as e:</span><br><span class="line">    print(e)</span><br></pre></td></tr></table></figure></p><h4 id="5-5-自定义异常-继承Exception-或者BaseException"><a href="#5-5-自定义异常-继承Exception-或者BaseException" class="headerlink" title="5.5  自定义异常(继承Exception, 或者BaseException)"></a>5.5  自定义异常(继承Exception, 或者BaseException)</h4><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyException</span>(<span class="title class_ inherited__">Exception</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, msg, error_code=<span class="number">200</span></span>):</span><br><span class="line">        self.msg = msg</span><br><span class="line">        self.error_code = error_code</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> self.msg + <span class="string">&quot;:&quot;</span> + <span class="built_in">str</span>(self.error_code)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">setAge</span>(<span class="params">age</span>):</span><br><span class="line">    <span class="keyword">if</span> age &lt;= <span class="number">0</span> <span class="keyword">or</span> age &gt; <span class="number">200</span>:</span><br><span class="line">        <span class="keyword">raise</span> MyException(<span class="string">&quot;年龄不符合，值错误&quot;</span>, <span class="number">404</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(age)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    setAge(-<span class="number">2</span>)</span><br><span class="line"><span class="keyword">except</span> MyException <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(e)</span><br></pre></td></tr></table></figure><h3 id="6-包和模块"><a href="#6-包和模块" class="headerlink" title="6.包和模块"></a>6.包和模块</h3><ul><li>模块：将某一组相关功能的代码写入一个单独的.py文件中，这个.py文件就称为一个模块。</li><li>包：包是一个有层次的目录结构，它定义了由n个模块和n个子包（目录下含有<strong>init</strong>.py文件的，还有模块和其他子包）</li><li>库：具有一定功能的集合，可以是包或模块</li><li>框架：从库的角度来看，解决一个开放性问题而设计的具有一定约束性的支撑结构</li><li>作用：有效的对程序分解，方便维护和管理，供给他人使用；防止同一模块下重名的问题</li></ul><h4 id="6-1-包和模块的分类"><a href="#6-1-包和模块的分类" class="headerlink" title="6.1  包和模块的分类"></a>6.1  包和模块的分类</h4><h5 id="6-1-2-标准包-模块"><a href="#6-1-2-标准包-模块" class="headerlink" title="6.1.2  标准包/模块"></a>6.1.2  标准包/模块</h5><ol><li>安装python后自动安装好一些模块，可以直接导入使用</li><li>特殊：内建包/模块，python自动帮我们导入导入的模块 <strong>builtins</strong>，当我们使用模块的内容时不需要手动导入模块，直接使用就行</li></ol><h5 id="6-1-3-三方包-模块"><a href="#6-1-3-三方包-模块" class="headerlink" title="6.1.3  三方包/模块"></a>6.1.3  三方包/模块</h5><p>一些开发人员直接写的包，供给其他人下载使用</p><h5 id="6-1-4-自定义包-模块"><a href="#6-1-4-自定义包-模块" class="headerlink" title="6.1.4  自定义包/模块"></a>6.1.4  自定义包/模块</h5><p>自己写的包/模块，发布出去就是第三方包/模块</p><h4 id="6-2-包-模块的操作"><a href="#6-2-包-模块的操作" class="headerlink" title="6.2  包/模块的操作"></a>6.2  包/模块的操作</h4><h5 id="6-2-1-包-模块的创建"><a href="#6-2-1-包-模块的创建" class="headerlink" title="6.2.1  包/模块的创建"></a>6.2.1  包/模块的创建</h5><ol><li>创建模块：直接写一个.py文件就行</li><li>创建包：创建一个文件夹，含有<strong>init</strong>.py文件，该文件在python3.3后不用创建也可以，一般版本兼容都创建（第一次导入包是，自动执行<strong>init</strong>.py文件）</li><li>创建多级包：嵌套就行</li></ol><h5 id="6-2-2-包-模块的基本信息"><a href="#6-2-2-包-模块的基本信息" class="headerlink" title="6.2.2  包/模块的基本信息"></a>6.2.2  包/模块的基本信息</h5><ol><li><p>包/模块的名称：模块名称为去掉.py的文件名，包名为文件夹名</p></li><li><p>包和模块存放的位置：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="comment"># 打印当前文件路径</span></span><br><span class="line"><span class="built_in">print</span>(os.path)</span><br><span class="line"><span class="comment"># 打印os模块存放位置路径</span></span><br><span class="line"><span class="built_in">print</span>(os.__file__)</span><br></pre></td></tr></table></figure></li><li><p>查看包/模块的里面的内容</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="built_in">dir</span>(包名/模块名))</span><br></pre></td></tr></table></figure></li></ol><h5 id="6-2-3-导入包-模块"><a href="#6-2-3-导入包-模块" class="headerlink" title="6.2.3  导入包/模块"></a>6.2.3  导入包/模块</h5><ol><li><p>常规导入(import语句导入)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">以下的包模块可以使用点语法定位</span></span><br><span class="line"><span class="string">1.导入单个模块</span></span><br><span class="line"><span class="string">import 同级目录的模块名/包名.模块名(注意包名可以嵌套,但是自己定义的模块与包使用这种方式导入只能导入当前py文件目录下的，不然报错找不到)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">2.导入多个模块 </span></span><br><span class="line"><span class="string">import 同级目录的模块名/包名.模块名, 同级目录的模块名/包名.模块名...</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">3.导入单个/多个模块并起别名(使用as关键字，与sql语法不同的是as不能省略)</span></span><br><span class="line"><span class="string">import 同级目录的模块名/包名.模块名 as 别名, 同级目录的模块名/包名.模块名 as 别名 ... </span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">注意：</span></span><br><span class="line"><span class="string">1.使用时，需要指定资源的模块名称，即写全，例如p1.tool_module.name</span></span><br><span class="line"><span class="string">2.如果仅仅导入一个包，在__init__.py再次导入相关模块，一般使用from... import...方式导入</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>2.from… import语句导入</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">语法：</span></span><br><span class="line"><span class="string">    from A import B[ as 别名]</span></span><br><span class="line"><span class="string">    A的资源必须包含B，即A顺序在前</span></span><br><span class="line"><span class="string">资源排序：</span></span><br><span class="line"><span class="string">    包 &gt; 模块 &gt; 模块资源</span></span><br><span class="line"><span class="string">注意面向关系：</span></span><br><span class="line"><span class="string">    包只能看到模块，看不到模块资源</span></span><br><span class="line"><span class="string">    模块只能看到模块资源</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">最终组合：</span></span><br><span class="line"><span class="string">    1.从包中导入导入模块（包是可能有层级关系，模块没有层级，但可以多个，可以起别名）</span></span><br><span class="line"><span class="string">    2.从模块中导入导入模块资源（模块是可能有层级关系(包有层级的)，模块资源没有层级，但可以多个，可以起别名）</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">注意：</span></span><br><span class="line"><span class="string">保持import后面最简化，即所有层级关系放在from后面；</span></span><br><span class="line"><span class="string">注意导入模块，模块是当前文件目录下的或文件目录的上级目录下的等等，需要写全包的路径名，即类似idea的全类名去掉类</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">特例：</span></span><br><span class="line"><span class="string">    1.from 模块 import *</span></span><br><span class="line"><span class="string">    &quot;*&quot;代表所有非下划线_开头资源导入到当前位置(定义__all__看列表的，这个规定需要看列表有没有写入来判断)</span></span><br><span class="line"><span class="string">    与在引入模块声明的__all__ = [&quot;资源1&quot;, &quot;资源2&quot;, ...]配合使用，代表&quot;*&quot;匹配到的资源，注意列表内都是字符串</span></span><br><span class="line"><span class="string">    注意：慎用，避免当前位置与导入资源的变量冲突</span></span><br><span class="line"><span class="string">    </span></span><br><span class="line"><span class="string">    2.from 包 import *</span></span><br><span class="line"><span class="string">    与在引入包的__init__.py中声明的__all__ = [&quot;资源1&quot;, &quot;资源2&quot;, ...]配合使用，代表&quot;*&quot;匹配到的模块，注意列表内都是字符串</span></span><br><span class="line"><span class="string">    必须写__all__,没有什么都不导入</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></figure></li><li><p>导入<strong>模块</strong>具体发生的事情：</p><ul><li>第一次导入：<ol><li>在自己当下的命名空间中执行所有代码</li><li>创建一个模块对象，并将模块内所有顶级变量以属性的形式绑定在模块对象上</li><li>在import的位置，引入import后面的变量名称到当前命名空间</li></ol></li><li>第二次导入：<ul><li>直接执行上述第3步</li></ul></li><li>结论：<ul><li>注意：上述两种导入方式都大致执行以上步骤</li><li>多次导入该模块，该模块不会执行多次</li><li>两种导入方式没有区别是否节省内存，而是区别在于哪一部分内容拿到当前位置来用</li></ul></li></ul></li><li><p>从什么位置找到需要导入的模块：</p><ul><li><p>第一从导入：</p><ul><li><p>第一级：内置模块</p></li><li><p>第二级：</p><ul><li><p>sys.path构成：</p><ul><li><p>当前目录：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="built_in">print</span>(os.getcwd())</span><br></pre></td></tr></table></figure></li><li><p>环境变量中PYTHONPATH（这个的路径是按照自己定义的）中指定的路径列表</p></li><li><p>特定路径下的.pth文件中的文件路径列表</p><ol><li><p>查看特定路径</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 查看特定路径</span></span><br><span class="line"><span class="keyword">import</span> site</span><br><span class="line"><span class="built_in">print</span>(site.getsitepackages())</span><br></pre></td></tr></table></figure></li><li><p>后缀名.pth，名字随意，一个路径占一行</p></li></ol></li><li><p>在python安装路径的lib库中搜索</p></li></ul></li><li><p>追加路径的方式：</p><ol><li><p>直接追加到sys.path列表，只作用本次</p></li><li><p>修改环境变量</p><ul><li>修改PYTHONPATH，把需要的模块路径定义到环境变量（不用添加到path），仅仅在shell起作用</li><li>在pycharm需要另外一种设置方式，设置里面的python Interpreter –&gt; show ALL –&gt;修改Interpreter path后点击ok，apply</li></ul></li><li>添加.pth文件（在特定路径下创建该文件，并且文件内容的路径不能为中文）</li></ol></li></ul></li></ul></li><li><p>第二次导入：</p><ul><li><p>从已经加载过的模块去找</p></li><li><p>查看已加载文件</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 查看已加载文件</span></span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(sys.modules)</span><br></pre></td></tr></table></figure></li></ul></li></ul></li><li><p>导入<strong>模块</strong>的常见场景：</p><ul><li>局部导入：<ul><li>在某个局部范围内导入模块，在其他范围无法使用</li><li>如果想要全局范围都能使用，在文件顶部导入相关模块</li><li>使用场景：该模块使用不频繁，而且导入时间过长时</li></ul></li><li>覆盖导入：<ul><li>场景一：<ul><li>自定义模块与非内置的标准模块重名，根据前者存储位置，有可能会覆盖后者</li><li>结论是自定义模块命名不要与后者重名</li></ul></li><li>场景二：<ul><li>自定义模块与内置模块重名，内置肯定覆盖自定义</li><li>使用from 绝对路径 import…导入，覆盖内置，但还是不建议重名</li></ul></li></ul></li><li><p>循环导入：</p><ul><li>假设有两个模块A、B,A模块导入了B模块，B模块导入了A模块，执行A模块或B模块都会造成循环导入（尽量避免使用，容易出现问题）</li></ul></li><li><p>可选导入</p><ul><li>概念：两个功能相似的包，根据需求优先导入选择其中一个导入</li><li>场景：有两个A、B包，都可以实现相同功能，想优先使用A，而且需要做到没有A的情况下，B作为备选</li><li>实现：使用try:… except …:…实现</li></ul></li><li><p>包内导入：python相对导入与绝对导入是基于包内导入而言的，包内导入就是包内导入包内部的模块</p><ul><li><p>绝对导入：</p><ul><li><p>参照sys.path路径进行检索</p></li><li><p>例如指明包名或模块名</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> a</span><br><span class="line"><span class="keyword">from</span> a <span class="keyword">import</span> b</span><br></pre></td></tr></table></figure></li><li><p>注意：以上结论是基于python3.x以上</p></li></ul></li><li><p>相对导入：</p><ul><li><p>使用<strong>.</strong>来指明相对路径，<strong>.</strong>是根据模块名称获取的当前目录，<strong>..</strong>是根据模块名称所获取的上层目录</p></li><li><p>例如：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> . <span class="keyword">import</span> a</span><br><span class="line"><span class="keyword">from</span> .. <span class="keyword">import</span> a</span><br></pre></td></tr></table></figure></li><li><p>注意：解释器是根据模块名称而确定层级关系，而不是存放目录，通过下划线下划线<strong>name</strong>下划线下划线查看模块名称。</p></li></ul></li><li><p>结论：</p><ul><li>包内导入：使用相对导入</li><li>包外导入：使用绝对导入</li></ul><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># __name__</span></span><br><span class="line"><span class="comment"># 如果一个py文件直接以脚本形式执行 python file，它的名称就是__main__</span></span><br><span class="line"><span class="comment"># 如果一个py文件使用模块的形式，进行加载的，那么它的名称由加载路径决定的，包名(顶级名称).子包名.模块名</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># import tool2</span></span><br><span class="line"><span class="comment">#  import tool2 python2.x 隐式相对导入等同于 from . import tool2</span></span><br><span class="line"><span class="comment"># import tool2</span></span><br><span class="line"><span class="comment"># 使用from __future__ import absolute_import禁用隐式相对导入</span></span><br><span class="line"><span class="keyword">from</span> __future__ <span class="keyword">import</span> absolute_import</span><br><span class="line"><span class="keyword">import</span> tool2</span><br></pre></td></tr></table></figure></li></ul></li></ul></li></ol><h4 id="6-3-三方包的安装与升级"><a href="#6-3-三方包的安装与升级" class="headerlink" title="6.3   三方包的安装与升级"></a>6.3   <a href="https://blog.csdn.net/m0_64491740/article/details/127252665">三方包的安装与升级</a></h4><h3 id="7-虚拟环境"><a href="#7-虚拟环境" class="headerlink" title="7.虚拟环境"></a>7.<a href="https://blog.csdn.net/m0_64491740/article/details/127252681">虚拟环境</a></h3><h3 id="8-python反射"><a href="#8-python反射" class="headerlink" title="8.python反射"></a>8.python反射</h3><ul><li><p>具体含义看源码</p></li><li><p><strong>import</strong>(name, globals=None, locals=None, fromlist=(), level=0)：动态加载模块（import前后有双下划线）</p></li><li><p>hasattr(object, name, default=None)：判断实例obj是否存在字符串name对应的属性</p></li><li><p>getattr(object, name, default=None)：获取字符串name对应的属性</p></li><li><p>setattr(x, y, v)：设置属性到实例</p></li><li><p>delattr(x, y)：删除实例中字符串对应的属性，等同del x.y</p></li><li><p>反射案例：</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 案例一</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">User</span>(<span class="title class_ inherited__">object</span>):</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">add_user</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;添加用户&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">delete_user</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;删除用户&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">update_user</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;更新用户&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">select_user</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;查找用户&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">before_process</span>(<span class="params">self, method</span>):</span><br><span class="line">        <span class="keyword">if</span> method == <span class="string">&quot;add&quot;</span>:</span><br><span class="line">            self.add_user()</span><br><span class="line">        <span class="keyword">elif</span> method == <span class="string">&quot;delete&quot;</span>:</span><br><span class="line">            self.delete_user()</span><br><span class="line">        <span class="keyword">elif</span> method == <span class="string">&quot;update&quot;</span>:</span><br><span class="line">            self.update_user()</span><br><span class="line">        <span class="keyword">elif</span> method == <span class="string">&quot;select&quot;</span>:</span><br><span class="line">            self.select_user()</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;无效调用&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">after_process</span>(<span class="params">self, method</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">        去除ifelse的繁琐，类似理由转发</span></span><br><span class="line"><span class="string">        &quot;&quot;&quot;</span></span><br><span class="line">        <span class="comment"># p判断是否存在该方法</span></span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">hasattr</span>(self, method):</span><br><span class="line">            <span class="comment"># 获取方法</span></span><br><span class="line">            user_method = <span class="built_in">getattr</span>(self, method)</span><br><span class="line">            user_method()</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;无效调用&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span>:</span><br><span class="line">    <span class="comment"># 没有处理，好多if</span></span><br><span class="line">    User().before_process(<span class="string">&quot;delete&quot;</span>)</span><br><span class="line">    <span class="comment"># 处理后</span></span><br><span class="line">    User().after_process(<span class="string">&quot;delete_user&quot;</span>)</span><br><span class="line">    </span><br><span class="line"><span class="comment"># 案例二</span></span><br><span class="line"><span class="comment"># 保证按位置传参且只能传一个</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">new_method</span>(<span class="params">self, /</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;我是新来的，给我一个实例&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main</span>():</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    动态加载模块，创建类实例执行其中方法</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line">    <span class="comment"># 动态导入模块Func</span></span><br><span class="line">    func_module = <span class="built_in">__import__</span>(<span class="string">&quot;Func&quot;</span>, fromlist=<span class="literal">True</span>)</span><br><span class="line">    <span class="built_in">print</span>(func_module)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 判断是否找到对应类</span></span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">hasattr</span>(func_module, <span class="string">&quot;Func&quot;</span>):</span><br><span class="line">        <span class="comment"># 通过模块对象实例获取类对象实例</span></span><br><span class="line">        func_class = <span class="built_in">getattr</span>(func_module, <span class="string">&quot;Func&quot;</span>)</span><br><span class="line">        <span class="comment"># print(type(func_class))</span></span><br><span class="line">        <span class="built_in">print</span>(func_class)</span><br><span class="line"></span><br><span class="line">        <span class="comment"># 判断是否存在方法</span></span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">hasattr</span>(func_class, <span class="string">&quot;process&quot;</span>):</span><br><span class="line">            <span class="comment"># 通过类对象获取成员方法</span></span><br><span class="line">            process_method = <span class="built_in">getattr</span>(func_class, <span class="string">&quot;process&quot;</span>)</span><br><span class="line">            <span class="comment"># print(type(process_method))</span></span><br><span class="line">            <span class="built_in">print</span>(process_method)</span><br><span class="line">            <span class="comment"># 执行该方法</span></span><br><span class="line">            process_method(func_class)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;没有找到当前方法&quot;</span>)</span><br><span class="line"></span><br><span class="line">        <span class="comment"># 向类添加方法</span></span><br><span class="line">        <span class="built_in">setattr</span>(func_class, <span class="string">&quot;newFunc&quot;</span>, new_method)</span><br><span class="line">        <span class="comment"># 是否成功添加方法</span></span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">hasattr</span>(func_class, <span class="string">&quot;newFunc&quot;</span>):</span><br><span class="line">            <span class="comment"># 获取该方法</span></span><br><span class="line">            new_func = <span class="built_in">getattr</span>(func_class, <span class="string">&quot;newFunc&quot;</span>)</span><br><span class="line">            <span class="comment"># 执行方法</span></span><br><span class="line">            new_func(func_class)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;添加失败&quot;</span>)</span><br><span class="line"></span><br><span class="line">        <span class="comment"># 删除Func类中法</span></span><br><span class="line">        <span class="built_in">delattr</span>(func_class, <span class="string">&quot;newFunc&quot;</span>)</span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> <span class="built_in">hasattr</span>(func_class, <span class="string">&quot;newFunc&quot;</span>):</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;删除成功&quot;</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;没有找到该类&quot;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 测试代码</span></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span>:</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure></li></ul>]]></content>
    
    
    <summary type="html">记录Python的知识点</summary>
    
    
    
    <category term="Python" scheme="https://www.miraclerice.top/categories/Python/"/>
    
    
    <category term="Python" scheme="https://www.miraclerice.top/tags/Python/"/>
    
    <category term="面向对象" scheme="https://www.miraclerice.top/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/"/>
    
  </entry>
  
  <entry>
    <title>python三方包与模块</title>
    <link href="https://www.miraclerice.top/posts/1616afea/"/>
    <id>https://www.miraclerice.top/posts/1616afea/</id>
    <published>2023-11-16T02:40:22.000Z</published>
    <updated>2023-11-20T06:22:46.803Z</updated>
    
    <content type="html"><![CDATA[<h2 id="一、包管理项目历史"><a href="#一、包管理项目历史" class="headerlink" title="一、包管理项目历史"></a>一、包管理项目历史</h2><ol><li>distutlis<ul><li>标准库的一部分，能处理简单包的安装</li><li>通过setup.py进行安装</li></ul></li><li>setuptools<ul><li>包安装标准</li><li>自带一个easy_install安装脚本，后来被pip安装脚本代替</li><li>引入了.egg格式，后来出现更好的.whl格式代替它</li></ul></li></ol><h2 id="二、常见已发布三方包和模块形式"><a href="#二、常见已发布三方包和模块形式" class="headerlink" title="二、常见已发布三方包和模块形式"></a>二、常见已发布三方包和模块形式</h2><p><a href="https://packaging.python.org/en/latest/key_projects/">包管理项目</a>：<a href="https://packaging.python.org/en/latest/key_projects/">https://packaging.python.org/en/latest/key_projects/</a></p><ol><li><p>源码</p><ul><li>单文件模块</li><li>多文件模块（由包管理工具发布的项目）<ul><li>基于distutils发布的项目特点：包含setup.py文件</li><li>setuptool也是基于distutils</li></ul></li></ul></li><li><p><strong>.egg</strong></p><ul><li>setuptools引入的一种格式</li><li>setuptools可以识别安装它</li></ul></li><li><strong>.whl</strong><ul><li>本质是.zip</li><li>是为了替代<strong>.egg</strong></li></ul></li></ol><h2 id="三、安装方式概念"><a href="#三、安装方式概念" class="headerlink" title="三、安装方式概念"></a>三、安装方式概念</h2><ol><li><p>本地安装：</p><ul><li><p>单文件模块：直接拷贝到相关文件夹</p></li><li><p>对于带setup.py：通过setup.py脚本进行安装即可</p></li><li><p>.egg文件：使用setuptools的自带的安装脚本easy_install进行安装</p></li><li><p>.whl：使用pip进行安装</p></li></ul></li><li><p>远程安装：使用easy_install、pip、pycharm </p></li><li><p>安装源：</p></li></ol><ul><li><a href="https://pypi.org/sample">python官方</a>：<a href="https://pypi.org/sample">https://pypi.org/sample</a></li><li><a href="http://pypi.douban.com/simple/">豆瓣</a>：<a href="https://pypi.douban.com/simple/">https://pypi.douban.com/simple/</a></li><li><a href="http://mirrors.aliyun.com/pypi/simple/">阿里</a>：<a href="http://mirrors.aliyun.com/pypi/simple/">http://mirrors.aliyun.com/pypi/simple/</a></li><li><a href="https://pypi.mirrors.ustc.edu.cn/simple/">中国科技大学</a>：<a href="https://pypi.mirrors.ustc.edu.cn/simple/">https://pypi.mirrors.ustc.edu.cn/simple/</a></li><li><a href="https://pypi.tuna.tsinghua.edu.cn/simple/">清华</a>：<a href="https://pypi.tuna.tsinghua.edu.cn/simple/">https://pypi.tuna.tsinghua.edu.cn/simple/</a></li></ul><h2 id="四、本地安装（在本地下载好模块或者压缩包）"><a href="#四、本地安装（在本地下载好模块或者压缩包）" class="headerlink" title="四、本地安装（在本地下载好模块或者压缩包）"></a>四、本地安装（在本地下载好模块或者压缩包）</h2><ol><li><p>单文件模块</p><ul><li>直接拷贝到相关文件夹即可</li><li>存放位置：sys.path中所包含的路径都可以，一般存放在python的Lib/site-packages下</li></ul></li><li><p>带setup.py的文件</p><ul><li><p>打开命令行工具</p></li><li><p>切换到setup.py所在目录下</p></li><li><p>执行命令</p><figure class="highlight powershell"><table><tr><td class="code"><pre><span class="line">python setup.py build</span><br><span class="line"><span class="comment"># python 2.x</span></span><br><span class="line">python setup.py install</span><br><span class="line"><span class="comment"># python 3.x</span></span><br><span class="line">python3 setup.py install</span><br></pre></td></tr></table></figure></li><li><p>注意：</p><ul><li>如果项目是distutils打包的，上述命令直接使用，因为distutils是python自带模块，不需要安装</li><li>如果项目是setuptools打包的，上述命令可能报错，因为setuptools属于三方模块，不是标准模块，需要安装再使用</li><li>离线安装，可能依赖第三方包，还需要联网</li></ul></li></ul></li><li><p><strong>.egg</strong>(现在pypi官网基本上没有了，了解)</p><ul><li><p>使用setuptools自带的安装脚本easy_install进行安装，需要先安装setuptools</p></li><li><p>语法</p><figure class="highlight powershell"><table><tr><td class="code"><pre><span class="line">easy_install  xxx.egg</span><br></pre></td></tr></table></figure></li></ul></li><li><p><strong>.whl</strong></p><ul><li><p>使用easy_install 安装（过时了，新的setuptools已经没有easy_install.py文件）</p></li><li><p>pip安装</p><ul><li><p>安装pip</p><ul><li><p>远程：</p><figure class="highlight powershell"><table><tr><td class="code"><pre><span class="line">easy_install  pip</span><br></pre></td></tr></table></figure></li><li><p>本地：</p><figure class="highlight powershell"><table><tr><td class="code"><pre><span class="line"><span class="comment"># .egg .whl .tar.gz</span></span><br><span class="line"><span class="comment"># 不建议过时了</span></span><br><span class="line">easy_install  xxx</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用setuptools方式带有setup.py的pip</span></span><br><span class="line"><span class="comment"># python 2.x</span></span><br><span class="line">python setup.py install</span><br><span class="line"><span class="comment"># python 3.x</span></span><br><span class="line">python3 setup.py install</span><br></pre></td></tr></table></figure></li></ul></li><li><p>pip语法</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip install xxx.whl</span><br></pre></td></tr></table></figure></li></ul></li></ul></li></ol><h2 id="五、远程安装（自动从远程地址检索下载安装）"><a href="#五、远程安装（自动从远程地址检索下载安装）" class="headerlink" title="五、远程安装（自动从远程地址检索下载安装）"></a>五、远程安装（自动从远程地址检索下载安装）</h2><ol><li><p>使用easy_install安装</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">easy_install  xxx</span><br></pre></td></tr></table></figure></li><li><p>使用pip安装</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip install xxx</span><br></pre></td></tr></table></figure></li><li><p>从<a href="https://pypi.org/">远程地址</a>安装到本地python的Lib/site-packages下</p></li></ol><h2 id="六、pip其他操作"><a href="#六、pip其他操作" class="headerlink" title="六、pip其他操作"></a>六、pip其他操作</h2><ol><li><p><a href="https://pip.pypa.io/en/stable/">pip官方介绍文档</a>：<a href="https://pip.pypa.io/en/stable/">https://pip.pypa.io/en/stable/</a></p></li><li><p>切换安装源：</p><ul><li><p>一次性修改：</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">指定检索，只到指定地址检索</span></span><br><span class="line">pip install --index-url https://pypi.douban.com/simple/ 需要安装的包/模块名称</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">简化</span></span><br><span class="line">pip install -i https://pypi.douban.com/simple/ 需要安装的包/模块名称</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">扩展检索，先到https://pypi.org/sample/，没有检索到才会到扩展地址检索</span></span><br><span class="line">pip install --extra-index-url https://pypi.douban.com/simple/ 需要安装的包/模块名称</span><br></pre></td></tr></table></figure></li><li><p>永久修改：</p><ul><li><p>在C:\Users\用户名目录下创建pip文件夹</p></li><li><p>在pip文件夹创建pip.ini文件，写入一下内容</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">[global]</span><br><span class="line">index-url=https://pypi.douban.com/simple/</span><br><span class="line">[install]</span><br><span class="line">trusted-host=pypi.doubna.com</span><br></pre></td></tr></table></figure></li></ul></li></ul></li><li><p>安装在不同的python环境</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">方式一：</span></span><br><span class="line">python -m pip install 包或模块名</span><br><span class="line">python3 -m pip install 包或模块名</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">方式二：</span></span><br><span class="line">py -2 -m pip install 包或模块名</span><br><span class="line">py -3 -m pip install 包或模块名</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">理论依据是：</span></span><br><span class="line">python安装包实际在系统中安装了一个启动器py.exe   C:\Windows\py.exe</span><br><span class="line">启动器调用不同版本的python解释器去执行某些脚本</span><br></pre></td></tr></table></figure></li><li><p>查看包</p><ul><li><p>所有已经安装的：</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip list</span><br><span class="line">pip -v config list #查看配置文件位置</span><br></pre></td></tr></table></figure></li><li><p>不被依赖的包：</p>   <figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip list --not-required</span><br></pre></td></tr></table></figure></li><li><p>过期的包：</p>   <figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip list --outdated</span><br></pre></td></tr></table></figure></li><li><p>查看某个包的具体信息：</p>   <figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip show xxx</span><br></pre></td></tr></table></figure></li><li><p>http警告（永久修改安装源的修改为http，而不是https）：</p>   <figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">每个pip命令最后加上trusted-host=组织域名，不建议使用，直接https</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">例如：</span></span><br><span class="line">pip list --outdated --trusted-host=pypi.doubna.com</span><br></pre></td></tr></table></figure></li></ul></li><li><p>搜索包（官方已经停用，了解）</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip search xxx</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">默认是https://pypi.org/，-i修改检索地址</span></span><br><span class="line">pip search -i 检索地址 xxx</span><br></pre></td></tr></table></figure></li></ol><ol><li><p>安装其他版本包</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">pip install <span class="string">&quot;库名（包的名称） 限定符 版本号&quot;</span></span> </span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">限定符 为 == &gt; &lt; &gt;= &lt;= ，多个限定符与版本用，分隔</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">注意双引号的书写，例如</span></span><br><span class="line">pip install &quot;requests &gt;= 2.28.0, &lt;= 2.28.1&quot;</span><br></pre></td></tr></table></figure></li><li><p>升级包</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">pip install xxx  只有在本地库没有的时候才能下载最新不然不会下载更新，所以更新需要使用上式</span></span><br><span class="line">python -m pip install --upgrade pip</span><br></pre></td></tr></table></figure></li><li><p>删除包</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip uninstall xxx</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">删除对应的包</span></span><br></pre></td></tr></table></figure></li><li><p>生成冻结需求的文本</p><ul><li><p>可以将当前安装的三方包记录，存储到指定的文件中</p></li><li><p>以后可以根据该文件安装三方包</p></li><li><p>用法：用来将当前环境的下安装的第三方包输出到指定文件中，输出的文件中，方便别人使用pip安装，过滤掉了pip，setuptools，通过—all参数查看所有包</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip freeze &gt; requirements.txt</span><br></pre></td></tr></table></figure></li><li><p>根据冻结文本安装</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip install -r requirements.txt</span><br></pre></td></tr></table></figure></li></ul></li><li><p>三方包版本</p><p>三方包版本有n1+n2+n3组成，<strong>n1.n2.n3</strong></p><ul><li>版本bug修复：n3+1</li><li>新增某一个功能：n2+1</li><li>修改一个功能，或者修改原来api增加一个新的大功能：n1+1</li></ul></li></ol><h2 id="七、发布自己的三方包或模块"><a href="#七、发布自己的三方包或模块" class="headerlink" title="七、发布自己的三方包或模块"></a>七、发布自己的三方包或模块</h2><ol><li><p><a href="https://python-packaging.readthedocs.io/en/latest/minimal.html">文档</a>：<a href="https://python-packaging.readthedocs.io/en/latest/minimal.html">https://python-packaging.readthedocs.io/en/latest/minimal.html</a></p></li><li><p><a href="https://pypi.org/">pypi官网</a>进行账号注册</p></li><li><p>环境准备</p><ul><li><a href="#四、本地安装（在本地下载好模块或者压缩包）">setuptools安装</a></li><li><a href="#四、本地安装（在本地下载好模块或者压缩包）">pip安装</a></li><li>wheel安装：使用pip命令安装 pip install wheel</li><li>twine安装：帮助我们把包上传到pypi，使用pip命令安装 pip install twine</li><li>注意python版本环境问题</li></ul></li><li><p>发布前准备</p><ul><li><a href="#八、创建一个项目的项目结构">创建一个项目</a></li><li><a href="#九、编译生成发布包">编译生成发布包</a></li></ul></li><li><p><a href="#十、发布">发布过程</a></p></li><li><p>发布成功后使用</p><ul><li><p>手动下载</p></li><li><p>pip安装</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip install xxx</span><br></pre></td></tr></table></figure></li></ul></li></ol><h2 id="八、创建一个项目的项目结构"><a href="#八、创建一个项目的项目结构" class="headerlink" title="八、创建一个项目的项目结构"></a>八、创建一个项目的项目结构</h2><ol><li><p>项目名称</p></li><li><p>包</p><ul><li><p>模块(必须有)</p></li><li><p><strong>init.py</strong>(必须有)</p></li><li><p>setup.py(必须有)：</p><ul><li><p>作用：项目信息的配置文件，这个里面重要的是执行setup函数，通过这个函数指明信息，</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> distutils.core <span class="keyword">import</span> setup</span><br><span class="line">setup(形参<span class="number">1</span>=实参<span class="number">1</span>, 形参<span class="number">2</span>=实参<span class="number">2</span>, ...)</span><br><span class="line"><span class="comment"># 一般推荐使用</span></span><br><span class="line"><span class="keyword">from</span> setuptools <span class="keyword">import</span> setup</span><br><span class="line">setup(形参<span class="number">1</span>=实参<span class="number">1</span>, 形参<span class="number">2</span>=实参<span class="number">2</span>, ...)</span><br></pre></td></tr></table></figure></li><li><p><strong>名称</strong>：name</p></li><li><strong>版本</strong>：version</li><li><strong>描述信息</strong>：description</li><li><strong>需要处理的包列表</strong>：packages</li><li>需要处理的单文件模块列表：py_modules</li><li>作者：author</li><li>作者邮箱：author_email</li><li>长描述：long_description，可以从README.rst读取出来</li><li>依赖的其他包：install_requires</li><li>python版本控制：python_requires</li><li>项目主页地址：url</li><li>协议：license</li><li>…</li><li><a href="https://docs.python.org/zh-cn/3.9/distutils/setupscript.html">具有setup.py的脚本文档1</a>：<a href="https://docs.python.org/zh-cn/3.9/distutils/setupscript.html">https://docs.python.org/zh-cn/3.9/distutils/setupscript.html</a></li><li><a href="https://packaging.python.org/en/latest/tutorials/packaging-projects/">具有setup.py的脚本文档2</a>：<a href="https://packaging.python.org/en/latest/tutorials/packaging-projects/">https://packaging.python.org/en/latest/tutorials/packaging-projects/</a></li></ul></li></ul></li></ol><ul><li><p>README.rst</p><ul><li><a href="https://zh-sphinx-doc.readthedocs.io/en/latest/contents.html">文档语法</a>:<a href="https://zh-sphinx-doc.readthedocs.io/en/latest/contents.html">https://zh-sphinx-doc.readthedocs.io/en/latest/contents.html</a></li><li>与markdown语法非常相似，基本一样</li><li>语法检测<ul><li>在pypi无法正确显示原因：pypi对rst的解析问题，并不是sphinx，导致部分语法差异</li><li>解决：从本地对long_description进行验证，通过后再上传</li><li>步骤：<ul><li>安装库 pip install readme_renderer</li><li>执行 python3 setup.py check -r -s，running check检测成功</li><li>也可以使用pycharm验证，右键rst文件运行</li></ul></li></ul></li><li>注意：使用setuptools打包，自动包含这些文件，不需要在MANIFEST.in声明，使用distutils打包，不包含文件，需要声明</li></ul></li><li><p>LICENSE.txt</p><ul><li>声明库的使用责任等等</li><li><a href="https://choosealicense.com/">内容文档</a>：<a href="https://choosealicense.com/">https://choosealicense.com/</a></li><li>注意：使用setuptools打包，自动包含这些文件，不需要在MANIFEST.in声明，使用distutils打包，不包含文件，需要声明</li></ul></li><li><p>MANIFEST.in</p><ul><li>当我们打包项目时，并不是所有的文件都会被打包到目标包中，打包工具会所有已经打包的文件生成一个MANIFEST的列表清单，我们可以通过MANIFEST.in告诉打包工具新增一下指定文件</li><li>例如include LICENSE.txt、include README.rst</li><li><a href="https://docs.python.org/zh-cn/3.9/distutils/sourcedist.html#specifying-the-files-to-distribute">官方文档</a>：<a href="https://docs.python.org/zh-cn/3.9/distutils/sourcedist.html#specifying-the-files-to-distribute">https://docs.python.org/zh-cn/3.9/distutils/sourcedist.html#specifying-the-files-to-distribute</a></li><li>包含：include  *.txt</li><li>递归包含：recursive-include examples <em>.txt </em>.py</li><li>修剪：prune examples/sample/build</li></ul></li></ul><ol><li><p>注意：</p><ul><li>命名全部小写</li><li>多个单词使用中划线-进行分割，不要使用下划线，pip对下划线支持不是很好</li><li>不能与Pypi上的命名重复</li></ul></li></ol><h2 id="九、编译生成发布包"><a href="#九、编译生成发布包" class="headerlink" title="九、编译生成发布包"></a>九、编译生成发布包</h2><ol><li><p>进入setup.py同级目录（cd 目命令）</p></li><li><p>执行</p><ul><li><p>python3 setup.py sdist</p><ul><li>生成源码压缩包</li><li>包含setup.py，源码文件，数据文件等等</li><li>可以用在任何平台上重新编译使所有内容</li><li><p><a href="https://docs.python.org/zh-cn/3.9/distutils/sourcedist.html#manifest-related-options">官方文档</a>：<a href="https://docs.python.org/zh-cn/3.9/distutils/sourcedist.html#manifest-related-options">https://docs.python.org/zh-cn/3.9/distutils/sourcedist.html#manifest-related-options</a></p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">python setup.py sdist --formats=gztar,zip</span><br></pre></td></tr></table></figure><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221010113541263.png" alt="image-20221010113541263"></p></li></ul></li><li><p>python3 setup.py bdist</p><ul><li>生成二进制发行包</li><li>不包含setup.py</li><li>是某个特定平台和python版本的一个存档</li></ul></li><li>python3 setup.py bdist_egg<ul><li>生成egg包</li><li>需要安装setuptools</li></ul></li><li>python3 setup.py wheel<ul><li>生成wheel包</li><li>需要安装wheel</li></ul></li><li>python3 setup.py bdist_wininst（官方文件有，但是我没有这个命令）<ul><li>生成whindows下的安装文件</li></ul></li><li>更多命令：python3 setup.py —help-commands</li></ul></li><li><p>注意：</p><ul><li>以上生成的包可以在本地安装</li><li>二进制发行包：可以解压直接拷贝到指定目录</li><li>包含setup.py的源码压缩包，解压进入同级目录，执行python3 setup.py install</li><li>windows下的安装包，双击按步骤进行</li><li>包含setup.py的源码压缩包、<strong>.egg</strong>、<strong>.whl</strong>,使用pip install xxx</li><li>卸载 pip uninstall xxx</li></ul></li></ol><h2 id="十、发布"><a href="#十、发布" class="headerlink" title="十、发布"></a>十、发布</h2><ol><li><p>在命令行执行</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">twine upload 需要发布的目标包</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">需要输入用户名和密码</span></span><br></pre></td></tr></table></figure></li></ol><ol><li><p>成功后，pypi官网可以查看</p></li><li><p>不需要上传到镜像服务器，镜像服务器每隔一段时间自动同步，可能不会立即更新</p></li></ol><h2 id="十一、区分模块的测试和发布状态"><a href="#十一、区分模块的测试和发布状态" class="headerlink" title="十一、区分模块的测试和发布状态"></a>十一、区分模块的测试和发布状态</h2><ol><li><p>我们在发布前写的测试代码，上传到pypi时，别人下载使用，导入模块时，会执行测试代码</p></li><li><p>解决</p><ul><li><p>方式一：发布前删除测试代码，弊端是下次更新迭代需要把测试代码重新写</p></li><li><p>方式二：借助<strong>name</strong>来区分py文件是被执行模式（name前后有双下划线）</p><ul><li><p>自己模块内执行<strong>name</strong>为<strong>main</strong>(main、name前后均拥有双下划线)</p></li><li><p>被其他模块导入执行，<strong>name</strong>为模块名称</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span>:</span><br><span class="line">   <span class="comment">#测试代码才执行，到时候发布后别人就不会执行</span></span><br></pre></td></tr></table></figure></li></ul></li></ul></li></ol><h2 id="十二、项目打包生成可执行文件"><a href="#十二、项目打包生成可执行文件" class="headerlink" title="十二、项目打包生成可执行文件"></a>十二、项目打包生成可执行文件</h2><ol><li><p>安装三方库PyInstaller</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip install -i https://pypi.douban.com/simple PyInstaller</span><br></pre></td></tr></table></figure></li></ol><ol><li><p>将模块打包</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pyinstaller -F 模块名称</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">example：</span></span><br><span class="line">pyinstaller -F F:\code\python\python3Project\student-system\stusystem.py</span><br></pre></td></tr></table></figure></li></ol><ol><li><p>找到提示路径下的exe执行</p><p> 我的是C:\Users\16691\dist\stusystem.exe</p></li></ol>]]></content>
    
    
    <summary type="html">记录Python的知识点</summary>
    
    
    
    <category term="Python" scheme="https://www.miraclerice.top/categories/Python/"/>
    
    
    <category term="Python" scheme="https://www.miraclerice.top/tags/Python/"/>
    
    <category term="Python库" scheme="https://www.miraclerice.top/tags/Python%E5%BA%93/"/>
    
  </entry>
  
  <entry>
    <title>python版本冲突</title>
    <link href="https://www.miraclerice.top/posts/da18aacf/"/>
    <id>https://www.miraclerice.top/posts/da18aacf/</id>
    <published>2023-11-16T02:40:22.000Z</published>
    <updated>2023-11-18T13:39:38.239Z</updated>
    
    <content type="html"><![CDATA[<p>C:\msys64\mingw64\bin</p><p>python冲突</p><p>修改python.exe</p><p>将全部<strong>pythonxxx.exe</strong>改为<strong>pythonmsys64.exe</strong></p><p><img src="C:\Users\16691\AppData\Roaming\Typora\typora-user-images\image-20221007220600751.png" alt="image-20221007220600751"></p>]]></content>
    
    
    <summary type="html">记录Python的知识点</summary>
    
    
    
    <category term="Python" scheme="https://www.miraclerice.top/categories/Python/"/>
    
    
    <category term="Python" scheme="https://www.miraclerice.top/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>vscode运行c++出现的问题</title>
    <link href="https://www.miraclerice.top/posts/8a93ff5a/"/>
    <id>https://www.miraclerice.top/posts/8a93ff5a/</id>
    <published>2023-11-16T02:40:22.000Z</published>
    <updated>2023-11-18T13:39:38.240Z</updated>
    
    <content type="html"><![CDATA[<h3 id="1-中文名的c-可以通过code-runner-运行，不能通过c-c-的运行与调试"><a href="#1-中文名的c-可以通过code-runner-运行，不能通过c-c-的运行与调试" class="headerlink" title="1.中文名的c++可以通过code runner 运行，不能通过c/c++的运行与调试"></a>1.中文名的c++可以通过code runner 运行，不能通过c/c++的运行与调试</h3><h3 id="2-c-一个项目只有一个main函数"><a href="#2-c-一个项目只有一个main函数" class="headerlink" title="2.c++一个项目只有一个main函数"></a>2.c++一个项目只有一个main函数</h3><h3 id="3-中文名的cpp文件编译后会为乱码，执行文件名会乱码，无法找到执行文件"><a href="#3-中文名的cpp文件编译后会为乱码，执行文件名会乱码，无法找到执行文件" class="headerlink" title="3.中文名的cpp文件编译后会为乱码，执行文件名会乱码，无法找到执行文件"></a>3.中文名的cpp文件编译后会为乱码，执行文件名会乱码，无法找到执行文件</h3><h3 id="4-一般json文件用filedirname"><a href="#4-一般json文件用filedirname" class="headerlink" title="4.一般json文件用filedirname"></a>4.一般json文件用filedirname</h3>]]></content>
    
    
    <summary type="html">vscode运行c++出现的问题</summary>
    
    
    
    <category term="C++" scheme="https://www.miraclerice.top/categories/C/"/>
    
    
    <category term="C++" scheme="https://www.miraclerice.top/tags/C/"/>
    
    <category term="vscode" scheme="https://www.miraclerice.top/tags/vscode/"/>
    
  </entry>
  
  <entry>
    <title>代码命名规范</title>
    <link href="https://www.miraclerice.top/posts/cea46f3c/"/>
    <id>https://www.miraclerice.top/posts/cea46f3c/</id>
    <published>2023-11-16T02:40:22.000Z</published>
    <updated>2023-11-18T13:39:38.240Z</updated>
    
    <content type="html"><![CDATA[<p>1.<a href="https://developer.aliyun.com/article/577610"><strong>匈牙利命名法</strong></a></p><p>2.<strong>驼峰命名法</strong></p><ul><li><p>大驼峰命名法（<em>帕斯卡命名法</em>）</p></li><li><p>小驼峰命名法</p></li></ul><p>3.<strong>下划线命名法</strong></p><p><a href="https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/naming/">谷歌开源项目风格指南</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;1.&lt;a href=&quot;https://developer.aliyun.com/article/577610&quot;&gt;&lt;strong&gt;匈牙利命名法&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2.&lt;strong&gt;驼峰命名法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;大驼峰命名</summary>
      
    
    
    
    
  </entry>
  
  <entry>
    <title>安装jupyter notebook</title>
    <link href="https://www.miraclerice.top/posts/6e2ad0b6/"/>
    <id>https://www.miraclerice.top/posts/6e2ad0b6/</id>
    <published>2023-11-16T02:40:22.000Z</published>
    <updated>2023-11-18T13:39:38.241Z</updated>
    
    <content type="html"><![CDATA[<ol><li><p>更新pip版本，使用cmd的命令行</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">[python -m] pip install --upgrade pip</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">[]里面是-m是以脚本运行，可以省略，也可以使用-i添加检索地址</span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">使用国内镜像,不加http后面的s时不想看到warning可以加[]里面内容</span></span><br><span class="line">pip install -i https://pypi.douban.com/simple/ --upgrade pip [--trusted-host=pypi.doubna.com]</span><br></pre></td></tr></table></figure></li><li><p>jupyter notebook的全局配置文件的位置，有y提示输入y</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">jupyter notebook --generate-config</span><br></pre></td></tr></table></figure></li><li><p>我的是C:\Users\16691.jupyter\jupyter_notebook_config.py，你们找到这个文件，使用记事本或者pycharm，vim都可以打开</p></li><li><p>通过<strong>notebook_dir</strong>找到</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># c.NotebookApp.notebook_dir = &#x27;&#x27;</span></span><br></pre></td></tr></table></figure><p>添加路径E:\Jupyter notebook workspace，这个路径自己定义就可以，修改后为(注意把前面注释符#去掉，一般使用正斜杠/，反斜杠\有转义)</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">c.NotebookApp.notebook_dir = <span class="string">&#x27;E:/Jupyter notebook workspace&#x27;</span></span><br></pre></td></tr></table></figure></li><li><p>打开cmd命令行，输入jupyter notebook就可以等待浏览器打开了</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">jupyter notebook</span><br></pre></td></tr></table></figure></li></ol><ol><li><p>通过token登录</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">在命令行输入</span></span><br><span class="line">jupyter notebook list</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">此时显示token，复制即可登录</span></span><br></pre></td></tr></table></figure></li><li><p>自动密码设置</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">在命令行输入</span></span><br><span class="line">jupyter notebook password</span><br><span class="line">Enter password:(此处输入你的密码)</span><br><span class="line">Verify password:(确认重新输入你的密码)</span><br><span class="line">[NotebookPasswordApp] Wrote hashed password to C:\Users\16691\.jupyter\jupyter_notebook_config.json</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">jupyter_notebook_config.json中的散列密码，登录是输入你之前输入的密码(注意重新启动jupyter notebook)</span></span><br></pre></td></tr></table></figure><p>8.准备散列密码</p><p>In [1]:</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> notebook.auth <span class="keyword">import</span> passwd</span><br></pre></td></tr></table></figure><p>In [2]:</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 此处输入你的密码并确认</span></span><br><span class="line">passwd()</span><br><span class="line">Enter password: ········</span><br><span class="line">Verify password: ········</span><br></pre></td></tr></table></figure><p>Out[2]:</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="string">&#x27;argon2:$argon2id$v=19$m=10240,t=10,p=8$Pk0tv4Im9BO2fNz7OXdnsA$gTXU6rSI7T0V5+6RI77vNoVjigb4UWmpufuK4Bd0QgY&#x27;</span></span><br></pre></td></tr></table></figure></li></ol><ul><li>把上面的输出复制到jupyter_notebook_config.json，可以修改密码</li><li><p>或者在jupyter_notebook_config.py文件中修改c.NotebookApp.password = ‘’“的值，粘贴进去，但是优先级比前面的json文件低</p></li><li><p>获取更多查看<a href="https://jupyter-notebook.readthedocs.io/en/stable/public_server.html">官方文档</a>：<a href="https://jupyter-notebook.readthedocs.io/en/stable/public_server.html">https://jupyter-notebook.readthedocs.io/en/stable/public_server.html</a></p></li></ul>]]></content>
    
    
    <summary type="html">jupyter notebook</summary>
    
    
    
    <category term="Python" scheme="https://www.miraclerice.top/categories/Python/"/>
    
    
    <category term="jupyter notebook" scheme="https://www.miraclerice.top/tags/jupyter-notebook/"/>
    
  </entry>
  
  <entry>
    <title>虚拟环境</title>
    <link href="https://www.miraclerice.top/posts/48543190/"/>
    <id>https://www.miraclerice.top/posts/48543190/</id>
    <published>2023-11-16T02:40:22.000Z</published>
    <updated>2023-11-18T13:39:38.242Z</updated>
    
    <content type="html"><![CDATA[<h3 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h3><ol><li>场景：两个或多个项目需要某一个库的版本不一样，默认情况下，使用都是全局python环境，不能在一个库安装多个版本的库，使得运行一个项目后，需要安装其他版本的库再运行另外一个项目</li><li>解决：创建<strong>虚拟环境</strong>，一个独立的python局部环境，一个项目对应一个虚拟环境，下载对应版本的库</li></ol><h2 id="一、概念"><a href="#一、概念" class="headerlink" title="一、概念"></a>一、概念</h2><p>局部的、独立的python环境就是<strong>虚拟环境</strong>，拥有与全局python环境一样卸载安装等等的操作</p><h2 id="二、virtualenv"><a href="#二、virtualenv" class="headerlink" title="二、virtualenv"></a>二、virtualenv</h2><ol><li><p>安装</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pip install virtualenv</span><br></pre></td></tr></table></figure></li><li><p><a href="https://virtualenv.pypa.io/en/latest/user_guide.html">文档说明</a>：<a href="https://virtualenv.pypa.io/en/latest/user_guide.html">https://virtualenv.pypa.io/en/latest/user_guide.html</a></p></li><li><p>使用</p><ul><li><p>创建一个局部的隔离的虚拟环境（进入需要创建虚拟环境的目录）</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">virtualenv 虚拟环境名称</span><br></pre></td></tr></table></figure></li><li><p>可选参数-p</p><ul><li><p>到时候使用该参数指定的版本的python解释器执行代码，默认是你创建虚拟环境时用的python版本</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">virtualenv -p 指定版本的python.exe路径 虚拟环境名称</span><br></pre></td></tr></table></figure></li></ul><p>可选参数—system-site-packages</p><ul><li><p>到时候虚拟环境没有会到系统的第三方库查找，没有指定只能在自己虚拟环境库里面查找</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">virtualenv --system-site-packages 虚拟环境名称</span><br></pre></td></tr></table></figure></li></ul></li></ul></li><li><p>激活</p><ul><li>进入虚拟环境目录/scripts文件夹，执行<strong>deactivate.bat</strong></li><li>执行后，后续的操作如安装三方包与执行代码等等都基于这个虚拟环境（我测试是没有设置环境变量，没有进入进入虚拟环境目录/scripts文件夹还是系统的python解释器）</li></ul></li><li><p>可以安装三方库、执行代码等等操作（都基于这个虚拟环境）</p></li><li><p>退出虚拟环境</p><ul><li>进入虚拟环境目录/scripts文件夹，执行<strong>deactivate.bat</strong></li><li>执行后，后续的操作如安装三方包与执行代码等等都基于全局python环境</li></ul></li><li><p>删除虚拟环境</p><ul><li>直接删除当前文件夹即可</li></ul></li><li><p>注意：</p><ul><li>当别人需要你代码在他机器跑时<ul><li>方案一：连同虚拟环境文件夹和项目一起拷贝</li><li><strong>方案二</strong>：在虚拟环境中冻结依赖需求文本，把项目和依赖需求文本给别人，别人自己创建一个虚拟环境，根据冻结文本安装相关库</li></ul></li></ul></li></ol><h2 id="二、pycharm使用虚拟环境"><a href="#二、pycharm使用虚拟环境" class="headerlink" title="二、pycharm使用虚拟环境"></a>二、pycharm使用虚拟环境</h2><h2 id="三、virtualenvwrapper-win集中式虚拟环境管理"><a href="#三、virtualenvwrapper-win集中式虚拟环境管理" class="headerlink" title="三、virtualenvwrapper-win集中式虚拟环境管理"></a>三、virtualenvwrapper-win集中式虚拟环境管理</h2><ol><li><p><a href="https://pypi.org/project/virtualenvwrapper-win/">文档说明</a>：<a href="https://pypi.org/project/virtualenvwrapper-win/">https://pypi.org/project/virtualenvwrapper-win/</a></p></li><li><p>基于virtualenv，更方便的管理virtualenv</p></li><li><p>使用</p><ul><li><p>创建一个虚拟环境（进入需要创建虚拟环境的目录）</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">mkvirtualenv 虚拟环境名称</span><br></pre></td></tr></table></figure><ul><li>会创建在特定文件夹中，windows一般在用户目录的Envs文件夹下</li><li>激活新的虚拟环境</li></ul></li></ul></li></ol><ol><li><p>查看所有的虚拟环境</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">lsvirtualenv</span><br><span class="line">workon</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">列出当下创建的所有虚拟环境</span></span><br></pre></td></tr></table></figure></li><li><p>切换激活虚拟环境</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">workon 切换虚拟环名称</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">激活指定1的虚拟环境</span></span><br></pre></td></tr></table></figure></li></ol><ol><li><p>退出虚拟环境</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">deactivate</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">关闭当下所在的虚拟环境</span></span><br></pre></td></tr></table></figure></li></ol><ol><li><p>删除虚拟环境</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">rmvirtualenv 虚拟环境名称</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">删除指定的虚拟环境，删除对应的文件夹，退出对应虚拟环境的状激活态</span></span><br></pre></td></tr></table></figure></li></ol><h2 id="四、更加基于项目的虚拟环境管理Pipenv"><a href="#四、更加基于项目的虚拟环境管理Pipenv" class="headerlink" title="四、更加基于项目的虚拟环境管理Pipenv"></a>四、更加基于项目的虚拟环境管理Pipenv</h2><ol><li><p>功能作用：pip + virtualenv，工具内部封装了以上两个功能</p></li><li><p>优势：</p><ul><li>不需要再分别使用pip和virtualenv，直接使用Pipenv即可，会自动创建虚拟环境，以及安装第三方库，会记录你的项目依赖的所有三方库</li><li>使用Pipfile和Pipfile.lock取代了requirement.txt</li></ul></li><li><p><a href="https://docs.pipenv.org/">文档说明</a>：<a href="https://docs.pipenv.org/">https://docs.pipenv.org/</a></p></li><li><p>使用</p><ul><li><p>创建一个虚拟环境（进入需要创建虚拟环境的目录）</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pipenv --three 虚拟环境名称</span><br></pre></td></tr></table></figure></li><li><p>查看相关信息</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看项目位置</span></span><br><span class="line">pipenv --where</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看虚拟环境位置</span></span><br><span class="line">pipenv --venv</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看解释器信息</span></span><br><span class="line">pipenv --py</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看包依赖机构</span></span><br><span class="line">pipenv graph</span><br></pre></td></tr></table></figure></li></ul></li></ol><ol><li><p>激活虚拟环境</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pienv shell</span><br></pre></td></tr></table></figure></li><li><p>可以安装三方库、执行代码等等操作（都基于这个虚拟环境），不要使用pip，使用pipenv</p></li><li><p>退出虚拟环境</p><ul><li>exit</li><li>或者关闭shell</li></ul></li><li><p>删除虚拟环境</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">pipenv --rm</span><br></pre></td></tr></table></figure></li><li><p>注意：</p><ul><li>当别人需要你代码在他机器跑时<ul><li>连同使用Pipfile和Pipfile.lock和项目一起上传</li><li>执行pipenv install(不用加其他参数），pipenv shell 激活</li></ul></li></ul></li></ol>]]></content>
    
    
    <summary type="html">记录Python的知识点</summary>
    
    
    
    <category term="Python" scheme="https://www.miraclerice.top/categories/Python/"/>
    
    
    <category term="Python" scheme="https://www.miraclerice.top/tags/Python/"/>
    
    <category term="虚拟环境" scheme="https://www.miraclerice.top/tags/%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83/"/>
    
  </entry>
  
  <entry>
    <title>Xshell连接远程ubuntu服务器</title>
    <link href="https://www.miraclerice.top/posts/893901c2/"/>
    <id>https://www.miraclerice.top/posts/893901c2/</id>
    <published>2023-11-14T14:21:15.000Z</published>
    <updated>2023-11-18T12:29:21.443Z</updated>
    
    <content type="html"><![CDATA[<p>主要流程（加粗部分为必要，点击即可跳转到命令）：<a href="#1. 安装openssh-server服务:"> <strong>安装openssh-server</strong></a>—-<strong><a href="8. 启动 ssh-server 服务（两种方式）：">启动 ssh-server 服务</a>-</strong>-<strong>-<a href="#9. 验证是否成功开启：">验证是否成功开启</a></strong>—-<a href="#11. 检查一下系统上 SSH 服务的状态:">检查一下系统上 SSH 服务的状态</a>—-<a href="#12. 发出以下命令来检查 OpenSSH 服务器正在侦听哪个端口：">检查 OpenSSH 服务器正在侦听哪个端口</a>—-<a href="#5. 检查Ubuntu系统中的22端口是否开启：">检查Ubuntu系统中的22（根据前面检测的端口）端口是否开启：</a>—-<a href="#6. 安装ifconfig指令：">安装ifconfig指令（如果已经有不需要安装）</a>—-<a href="#7. 查看ip地址："><strong>查看ip地址</strong></a></p> <span id="more"></span><p>可以试一下客户端与服务端相互ping对方的ip，ping通了一般就能连上了</p><p>可能出现错误：xshell连接不成功，不要使用使用手机分享热点给服务器或者客户端，因为获取的是你手机的ip，所有连你手机热点的均为同一ip；</p><p>Ubuntu系统的端口曾经被修改过，不是默认的22了，需要在连接时修改；</p><p>如果不使用root用户是不需要修改/etc/ssh/sshd_config文件，即使用“sudo  vim /etc/ssh/sshd_config”命令将 PermitRootLogin改为yes，</p><p>然后按esc，“:wq”退出即可，最后重启ssh-server，”sudo /etc/init.d/ssh restart“如下所示：</p><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo  vim /etc/ssh/sshd_config</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">输入<span class="string">&quot;/Authentiation&quot;</span>,在其下面增加“PermitRootLogin <span class="built_in">yes</span><span class="string">&quot;,注意前面不要有#号</span></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash"><span class="string">按esc ，“:wq”退出即可</span></span></span><br><span class="line">sudo /etc/init.d/ssh restart</span><br></pre></td></tr></table></figure><h5 id="1-安装openssh-server服务"><a href="#1-安装openssh-server服务" class="headerlink" title="1. 安装openssh-server服务:"></a>1. 安装openssh-server服务:</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo apt-get install openssh-server</span><br></pre></td></tr></table></figure><h5 id="2-安装防火墙"><a href="#2-安装防火墙" class="headerlink" title="2. 安装防火墙:"></a>2. 安装防火墙:</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo apt-get install ufw</span><br></pre></td></tr></table></figure><h5 id="3-开户防火墙"><a href="#3-开户防火墙" class="headerlink" title="3. 开户防火墙:"></a>3. 开户防火墙:</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo ufw enable</span><br></pre></td></tr></table></figure><h5 id="4-防火墙充许22端口对外开放："><a href="#4-防火墙充许22端口对外开放：" class="headerlink" title="4. 防火墙充许22端口对外开放："></a>4. 防火墙充许22端口对外开放：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo ufw allow 22/tcp</span><br></pre></td></tr></table></figure><h5 id="5-检查Ubuntu系统中的22端口是否开启："><a href="#5-检查Ubuntu系统中的22端口是否开启：" class="headerlink" title="5. 检查Ubuntu系统中的22端口是否开启："></a>5. 检查Ubuntu系统中的22端口是否开启：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo netstat -tulnp | grep 22</span><br></pre></td></tr></table></figure><h5 id="6-安装ifconfig指令："><a href="#6-安装ifconfig指令：" class="headerlink" title="6. 安装ifconfig指令："></a>6. 安装ifconfig指令：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo apt install net-tools</span><br></pre></td></tr></table></figure><h5 id="7-查看ip地址："><a href="#7-查看ip地址：" class="headerlink" title="7. 查看ip地址："></a>7. 查看ip地址：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">ifconfig</span><br></pre></td></tr></table></figure><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">ifconfig -a</span><br></pre></td></tr></table></figure><h5 id="8-启动-ssh-server-服务（两种方式）："><a href="#8-启动-ssh-server-服务（两种方式）：" class="headerlink" title="8. 启动 ssh-server 服务（两种方式）："></a>8. 启动 ssh-server 服务（两种方式）：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">service ssh start</span><br><span class="line">/etc/init.d/ssh start</span><br></pre></td></tr></table></figure><h5 id="9-验证是否成功开启："><a href="#9-验证是否成功开启：" class="headerlink" title="9. 验证是否成功开启："></a>9. 验证是否成功开启：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">ps -e|grep ssh</span><br></pre></td></tr></table></figure><h5 id="10-查看是否安装openssh-server："><a href="#10-查看是否安装openssh-server：" class="headerlink" title="10. 查看是否安装openssh-server："></a>10. 查看是否安装openssh-server：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo apt list --installed | grep openssh-server</span><br></pre></td></tr></table></figure><h5 id="11-检查一下系统上-SSH-服务的状态"><a href="#11-检查一下系统上-SSH-服务的状态" class="headerlink" title="11. 检查一下系统上 SSH 服务的状态:"></a>11. 检查一下系统上 SSH 服务的状态:</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo service ssh status</span><br></pre></td></tr></table></figure><h5 id="12-发出以下命令来检查-OpenSSH-服务器正在侦听哪个端口："><a href="#12-发出以下命令来检查-OpenSSH-服务器正在侦听哪个端口：" class="headerlink" title="12. 发出以下命令来检查 OpenSSH 服务器正在侦听哪个端口："></a>12. 发出以下命令来检查 OpenSSH 服务器正在侦听哪个端口：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">sudo netstat -ltnp | grep sshd</span><br></pre></td></tr></table></figure><h5 id="13-在尝试连接之前，首先验证-SSH-服务器正在使用哪个端口来侦听新连接。如果服务器正在侦听默认端口-22，则可以使用以下命令语法来建立连接："><a href="#13-在尝试连接之前，首先验证-SSH-服务器正在使用哪个端口来侦听新连接。如果服务器正在侦听默认端口-22，则可以使用以下命令语法来建立连接：" class="headerlink" title="13. 在尝试连接之前，首先验证 SSH 服务器正在使用哪个端口来侦听新连接。如果服务器正在侦听默认端口 22，则可以使用以下命令语法来建立连接："></a>13. 在尝试连接之前，首先验证 SSH 服务器正在使用哪个端口来侦听新连接。如果服务器正在侦听默认端口 22，则可以使用以下命令语法来建立连接：</h5><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">ssh [username]@[remoteserver IP or hostname]</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">远程控制、深度学习服务器连接</summary>
    
    
    
    <category term="Ubuntu" scheme="https://www.miraclerice.top/categories/Ubuntu/"/>
    
    
    <category term="Ubuntu" scheme="https://www.miraclerice.top/tags/Ubuntu/"/>
    
    <category term="Xshell" scheme="https://www.miraclerice.top/tags/Xshell/"/>
    
  </entry>
  
  <entry>
    <title>Swin-VoxelMorph：使用 Swin Transformer 进行可变形医学图像配准的对称无监督学习模型</title>
    <link href="https://www.miraclerice.top/posts/d013157a/"/>
    <id>https://www.miraclerice.top/posts/d013157a/</id>
    <published>2023-10-01T02:55:22.000Z</published>
    <updated>2023-11-28T09:01:35.645Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">  <script id="hbeData" type="hbeData" data-hmacdigest="e1d5bc267d2291fb83774d48da638c757d53647acb59be77e705d810b2ce4e78">ddc360d448697775a77dd4fde850a2c0e2808ef0978c01a27c380987b2f2c8343e028686f7e714f552fc989480543765f400f3e46d07bd4391585eadbf570b88b38ed7079972ce569e5a64b7afed3d15973f6b330918c16a20714ba799a06e956b16120994c3cd6d0cea5daebcbd006730247efb20c24d83b40a04bc98ad614e50fda91417d206a72bd3b062f5214cc591ab82055afb754804d06f3864666d7af9dbbce6a9cdcb6e93ffe2af850bf4acfa45d0e98073af2c2707829d03cffd26f4c974ddda560ccecdf643e0d1b88567286f9870b732a34435787460a4364fe171828aaf62d8d8be6acee13f8cbd3de945650224c5a9c018377debea914972f783e233910a73c66bc79547cce1e8e48f8069f8297a5af1c7c6ffe5fc81813dad372dd917ad15768f3dccab86059e95b690da65c79e232e398136c7bb342eb19b08ceaba9c036ae06ac21682520b7b982615d6448eb4a69e80c7f772f20af927df22a93c2ac96f9e27d0163a42cdefc54b60f69ca577399c84c4a6827dfb4679601317e5bb24c7796de53d13f48d1e650c2dd696e62762363be073223e06cbbb0e3f8f2a9c747d37d5aeea725520c8253d380b436b2e28d07670ebc322761854dc6fa7f261cae4e243e56eadc4c3fad594135ba169977b5b6c8964216deca82ec58dccebb4a5cd042510dc305c5f259b6016e0ec004545eae24bdd4bc513afc6cf7ad8c49f474b3cc224ac1ae7ed267fa3bc1896bce7969411730c29215d40efada5da69dcf1d891316ce72afd3e618157b9bc6e66e59223ff1678cfe160cc35b4d767a5c98b5c8140fad971b5fed9eacf64eb06f3a625a4191d172bd8b6e7d9471be4ff076633dff1f219e7ea053f58997bd7eef23050de4c9fe1c4cb8b72138ee2f09b747b77f32e913468b78b2b68b18c983de1025e4f9b73d8989c71b1860b38cbeaae900eacd65a72842f029cade90104d204e003e6e8c2a681b4ea010956fd8ccd709ce2486570b5cbc74e64b4d2cbb2797bde62374d2d1e37cc1e9b398c07afc12c9fd48439aa185eed95c42fadd015bee247de90425a7333d70b10dd9ef7e6a50c37a7b8215bc508c267c0ead819e2daa10e1b9833f8cb219fa4241ca5b3364c8ab393e0bf53912f8e9a1c5ced9d199b9d5f1e11b49fcc48fc96a3f1638d0cd7cb9de4af5b751924adfbc200203debe9c117acfc62424895dc50d499ec196bcdbb835e27ce350911bebdf54ced7214312764e057524f23a29faf57eee7545b22b463806ba66365aacea82c0f695c53248ce4ec435b59e227dcbc169fce4a5e20b99eb50742be6e0fd95923d7ba4e670ed69659b6d656122c9164071725cfc155fbbd313b80b3ce69280a73f07562397ee02eddc1c69c6e1bd7a579070f6c1c8e1c0db684edbff448b8fb3a781d9875b7294ec3740d2de88539705c661a29b765ce61c4cc04ed823bc7c0d02308166fccb2b86ec2715cdd87a978e1e4170382567417954db87dad0d77f4a469fbc5a7d5251c8dc28f8374d10f7855103849c70c911ad958873f231c6962f368f3fe966f0c0a422c8cba730f04569983ff6c32330bf4eb1618983f557739d26c971e5a41e3bdde87b4d991124fac8aeb9820e01188db6bc2bb4b0caa66daff92007a87d230a386e4d34c600e9e346001306b0846b702510ea697b977253a02a049ff1ac45339a80e9b8923c247004dcdf37a3e676cfb824e90c5107183cba22b9703ae497fd03d3234db600c4ee7635239255f2e6b90670eb326e1cdf66039a893fa7e6b38ecc9a38f5cc5aded4e84b7f3586fe7cae4c131c6890938fd4d7fff89868b2dd12bf53b48cf267591ce7447e0f8064d7fa16ee56c8e9dc47af6216d4e8fd25a4522de9d4cfaba12f9dd6c4773aaab1d5d805b9e6f9cb6868096b0bed720ef9b60b14731f238bf4acdcb46d5f07402343f0b017cd9dc914f7ce64c5602fb7e4845f2634c4204d76f01e92a8a69ee7d5a4f83ed55b9a8c3a83db7a6e9e2234f7ec1e04bb7a0f2fae6c48226ac1356694e8306f63cab7895b73e1c7ee27e40cd381a8af9271e920a7da80ca545c1ebc04c51f21aa4567a2bcd7701e77086298e264838167a9af81cf6c9c8278c07e6b7a485f72d2e887e95ee7072e5615326a6b2db25b4cc42c180b247f59c486da8e284293ebb72b43eb3f89ad1da28aaa7f2ed604e8c1d389f443a3899e7f4d9b0f7b7ed238349e41ba5f4361df0b72c2d8b83be6cb10e9cbac55efcd4ef946e75f9d6f02212894968277e0d1049fe19c1a6416f1e9367c69eea6b4bc41f357a72e25f26c66202aeeeb6080f7741b3d7ede177261ebbdd04d0ca1b94379638ff3fffe1c13ed17129104e29defce29e1e32b1470c65e3d57f88639cd02c84f64edc9d6ae713fe3fe230eadda158ff6d8512edac53d981c97e3fbd09948fea47ff60f0e1035e82e1f9a21dca63d868f67e6a61b0272b99eb8fb25bc42e5f6a67206b9d4a50c0c2f5fe98220553b8e8ab55422188dbdbd99bc3468f4fd68cd251b611ace37d8bd972234d5765e2841fa3ad5de349fbc1cad445325fc42c9b715d726541e97f046db26f622c4cacf8b60b919be9ac57b4aed2e5454fa6ec5f0a2e078a2d27982a01e2fa225556524fcb983050e97e01372760c68c8d29689b5539eb89fcc27a05749e00da5a1466cc8e1d9aa1f77171dccdd5f308b10ca6b38424987b273cf39d7a7080938d314c08ad3695faa7658e6e8b66dfc711bbb2e576f7e604bec6417715e251f2466bba36dad2ca9a72a8ac79e08d5f29cb16ef81428036b9738594d9ec85180d1a912cdde88240e00f628bb716b010f978542585345683d985cc65aa9991538a6ab981c51b4f06ecc8b26e8f9a8a4470fb8514bc61f9d3b7a29b72ee73c88022e7ba6e6ae4de1b1819638b2d687d24207518501fc5d28ba79de1961e6b8dcf4845051a62c301ca985d5a26910f1b38f493dda40bbb69e92959e50d163b9c9adbec61a658e83112f38bf8a3ef25d1f15ad711f280113e13040be47ae45c75cb8343d76f4894e25ccae91ecaa9d0989714367bbd49a4ba035f5758b1d0a60940d13e19466973782c0277ffb6b8f158bd83a7049dc90b7bd6216ae3b3fd1ce433ef37833ecb3a03ff9e2b1029875ac46652c040f07fa150cf4594e7b2e70a08f6e8bb224e56492cc7ad0f036f889778c982d88f900a97151994d65ecf9140cdfddfb8cebe550eaa57138b3f5932542a6c1d09e1b23a8028d7d5ac8756fe2be3ec589a4b08f1b32863b71766cb3a3062c0003cb8cc99191ce2084ad9f48e212d9e21b98fd171529295e0691f94f0e6506eb6ff002284b3b24bdff0f52382380094cc20722db157d855ce60314124e77569dea42647b554a2ec2d4e43455cb2914947e3fd3f365a0beb4549307157c65ef1e27604fcc2c623e5ce411dcf285cb246631f3697d856bf3e61c332a1689a5890ff7d327b02a5345585f446650229a2a1656adf722b9037d7c132a1a7cbba38953786ea7e320c486c42186b4965759d2c4c043a22817c346dc96a3a4f8fcd1b76bdf92af43b4b839ea25adf96d9aa34ca865c27a46aeb0d39dd51574a8a265fd65a8d00ae6f48017b90719714b47ea23bf3189b248a6e3ff4053fa22df6eab35f28cd12872d79183f8605af044b52de7f59d22382b514e6e9b17ab7d65f4e4aef6601c05e6b9c235036b5e2632632841f074359729489acac362c232c6543f8f7209e7b929fe30021134205553c5c90b3a28b1886c3f0d4b2aaaa068a1af848db17bb097e74e34c1c71dc6725d64113cc3d67fa039a60b9b840b646ff7e171478474cb70c6e299670268d5bbda4a99d110a9561f3eb49d374411a4fd60a6493b84086c2165665f7e8be1a5abdce412ea93493b1fbdaabde1f8eedb46b5e057502cba41cd79006d311bb6e2d9502560367a78b59d43fe71dc16ddea8dce29c8a1d0f248198db52800b0666fc30ae2b6d8fba880b6e0ac242f60e80680abbd329d3e38d1fe01359167541008e1d88c314055686c3af8ee7c7e6c4ee30851aa05a9beea29dff7542c10677c2cd24131e7afa00dfe0ea154779037e2e39f606e79eca5e19d865584cf3fb167efb7de25d3083261dc233bbe8c37a6294d690901a797b95248d5b6b344c1e9b3afbf9deae602b4cdcfcb2a62ce8d031b3ca75941080cbcaa376c36a5c77fb54a21d906fd4ab04d2ca6843395be8a4cffee5218bc69c39375558084876ed18ec16b4b7ee84a90d0231b7f8713796791867dead2014b07dd947b16bba1b06fd15bec20200ddbd8f6e76d1903dc959c3c6932b7442c402a111e91f105ea5706a5c4a45f1ff6daff225ff9d11b2ce7c9bac8cec38a204cc16c8b366c0c89451723236f3783869a3dd6814e7a05d827658b82886b35e3bd0d3369d7a6c004c4ac1141b53a564b66c913de295383daa972f4ae346984161f205aae11b0ee712bf870d35ce5ed214eb81756131500cb4755e93284428abbd70122906a9ff0cec5ba1140204e5daf39eeb13356640503c6d00cad677d4f7b859e44572ab84b0bc6c085630021b42d3635943434d3f1506135bd8e323cbb1ba637ce40b2e3a716a6ba2a4d9098cbbb63416f97fc04b91dbed623b78d298c06d9915d7d9d6629af3f086a54c1f2112bf061c071aedbda89bd62feea9790770953a01a9cd1c02d031a61ee3387e191ad614712502bd7d4fdb1b25e06a84f386e18714459689c73c682f1bc4705f3ae20fe9e58243b700c4bb0170a58b62743ad616504c69425378aa81183768833d14ad84dc5789a6f6020a605a987d75657df5b9803990ce4b1e77a66ffff563cd2e83aef7919e161efdeafd6f1d9c122c68a8d7f34254da92de07ca4c64e19c60d08844f96f30c99d2f8ca38aaea9ebdda9990e61c771173cee5a1825de6e4c40442f986021410e4dc799c83c81dbc47c2027f5386646da823bbd56bf6f27a77ebfd35a6a671e0590f790a619a79ffa1434f763f72fdf08f55a22b307f84672fcde2cc0c20d0ee75b1fa26b17b5c6cc33fe3b410d6a3ed121f065fbbe8f7f315a1ee362fed00e5eeda1cf57752e421a106b851db4baccd7166310060a426f71a50d7eecb6daa61f1d9b28f51e611fa8493de714fc167f0a7f070a4b96ba38a505e802bf9bbab6af09aa7797f2f69567e7c2242425f78059260e8665f4bb5ecbe46a38b3b75fd2d70e5b84a8ebae116887cbf0d555bdcf8f7de83a0109caf2977547a91ba75872a40d3e76c13349910e60d5285c0125a18b767878db7542265fcf419636dfd705f0deb35bc39950b464b537aef532380ca1fea787213bda14df0a01ecbf6fc294fa99a4856f3265fb62c4332a2b8852a52cef5047858a3eaa20b5169d1e44a9ed08cba564c9b13d1d600d82360b858e3adbf3e7418ae451dd959ff3e27f5fc354da868144b48a8c39b11ffafc40dfe6573467c075ee2e438a147397c7a8799ce6112ba6308e28a1b9922f38222b68f94b10e13f9e06d0ed4aa8dba6cac5dcf96bfc2b0cc67fb1d9f77faa8799d12e7b73716a15770ad448837d08fe4921122c40d71bdac6e74862233d4e0932584661640251ea19887b19b4115a2157256fd7b465fa7cc9afd96c7ec5e46bed88f7c1075d8081293498bcf59cf6431fac6dfaf03fb3c299fca064ef975b13f5585e477e9bdf7a590234abee3c5b9a3cf6d929fb1aadd4cd2efbea49caf21f0027649383f3068bbf84037b790402c3dfcc3c30deb3dd4222db2c438931a6a52a545e2209523d99237b526aa062ed82bfbf75672099eb357456c399fbb92b6a869ea569252a714525603eb006720f04c196f3692c32728b569bf8e476ae5c2a5355172a6903c2789eb994dbb3f45af2351b35e8dcb2dadf6808322abfec706bec53213eb9b7b835ecd523fe80d4f2aa2d1cf4116e8c0e7dcd3be4deb47954f5b06ef382e01a2eb5b18c9f18ecfc27f7ddb5b8a90743ed391995808aca8a6bf18a97c2e12a9e7a300d719ddd32f60e26f2827c4c590e13e41ec5f95c6efa885be7d9674de6e11ec42ab2a299e0c4a1786b8164a20cac21ebc7db0284145353d1080754c1b4a40292a7f2862878982bbcb784216d4604d1b74f29841d3968d4cd36e16d4d8387739da76c65ea8323e8b1de86bdd40c05980aff7448fb8ed1241eb0e2b3b72ea9b012b15f36f50573f20ea2dbc84d0e1ae428082335b199e9a66a55d28a7d744d9072b5b013a1de06a6d019e7f3c4228053c19113997b733d4467a7ca7d879f6868d20d2300a84553cd25b41d359e8f7e62423dfdabacb3b783c29dd76dd504f9e740d42846bc7776ae2a0a1ae8b5f69e2a67bc2009b1e87335caef4047c4a085cba88e12ffa50ed32b072344e96d653960a434e79011a8a68ebfddd806e19ba3f1d08bb182ea1276ca3799a2a1f0a69d0595cbd13768836cdbb44dc4dc8e49400df7a828c89f4bbdde54b2b22f5417eaee5699d98ef0a99f8cf1d0d235a129fd6bf9fb5352c95dfe8efe0486e947802f67f4320c7170f57b2cc6c9e2b3c5128dc4410aba422a60208dd8b3bd0376292b4264b4212e9b756995137e54c76161fecf6adc19bc20ac31a2118d3ee44877c420ee506c06fd3ceda35b3a7023f41158b54591d92a164ba3874d3d277e018e6d4821e8605bbad8d287e3c39bee15c9db3e156c0a69d921feeedd3a22463410efa73287c27959b9dae004ef7489b7ba3ee9b440afd013bdf51434c712b5cb45e3f7bd862198f3bfb27aa7e9f6b84c59c6d19741b162bc6068686cbc1335456c32702e47019e26362d9ec119bc5ed08fbe8d31041c7a4d9c233c775f8ca19686e14708950da822fdbdb095e7257c580cc066e617ad8653d99ac6a2157851bd8b06b400fce034bdf6c857b26e769183d73e13fee1113aadbae807ecb875e05306ca45c05f0c07524fc9ec2f7f6364727b568d8b19ce5aff405b98c6a0ca52501994ae9ce65153eabd9a665f75e28e1c8f518ee1d0771a0de2d36704466a542aa5c576d30249c114703c9482cd6a2af87f26ca78f57a0b2486775292bd3e5f36081b50a808480bfcd83b82f5588020c7f27083d9d83fcc0daf189a24dca3b0eabcdb7e8faf6a5c89c96da9d46e5355204d370d615937f1361fdc04c097e22c121a0061b1e48fdaf1f7c472f8387170cc11093c262798e2903bb1bdff29fb90c6acf4e42fb1d466e2c3271deeaa7fc66ad39c7b8e7df4cc501840c65d4ef48c41bbfba39827c2367b382ff14f7e29b92ea28b2ec259a1aa1d5a78a039bb7b06d4d32bb31c0bb899a99a11f3757e4ed776afff501b79eb4e6edf27f8421415531a4cb9cdb14d65606f0cee9369c5a2c56099ce34b87ba8001a82b66bdadbf4f65829d5633bec0fe305d4cd8c5168469759877989945a942f245ccdecffead0e17394caedc1cbcd8a01ebe505e40e838eec658c8f5f115558c756830137cea2f67000b96c3ea2d747e626943bdd8ff82ed7fcf89ed407a58844c3c1c03872c6f927cba52ac9dcefe9b78366a5fbc8678e1bef40080c370d12b2a5b60268552763c641ca9ed5a04304e2e74ade4e9adf72a507c396971a85d5dc518a95e3fa5ba667e53d62df2c9fe10dc5c1c5527b7df6195e82b2028813906d45f2b6d9f7fdeca4da36b6dd4ea84805549785eae084db64ca2f13e41874880f563e313975d0fb16a00aa1a8efbbe3ec3fd19f5e585ee404d7fac12f2be26c5b46c05414a778b9da6b028f87936d541fa5a09775df9717258c0c9419fee825f3503379d6bc0a0ae6c0476c3003ce10ed9c0873fcedcfac40c67d59b661fc202e53fb34710a3ea3e7a3e94b709cbb407305143e366aa6a5e344b80400b4a34b8353bb353956cbceb719e8784df997b774d48ad75805cba0e912d6a0a6918d168ed86cec7e75fdf6032e5c053eac1bc15f8f4643beeee5ba852618f22e51dd92bd2327c189281bb06de070875b4d342c6615408e934e42549551d26c63c03b73f126c6d5daad129e5412340d9caf2ccab0bce8bc796f1d905bf065599e765edb6e66e33b8509674828fa7e564b93e204b01a8ff558e04a7b6d558fb6106177ce1781a1b1cc522d8e7be79380591b3f0ba8dfdf3fe50ea233184aa67c7b6eda2cb649925ffcd40d185ece199e2a3259bc43e09565bc9938745b0786786534907cd4f18c5d274b19185dcd5d875bfb048ef5ee0e44030c1e680b8f76fe0d06d3461303c5d0577bcf9e42a33e16fd917305c08184b643d72accd9826946d24b648abd4fb095c09f0b92c600fc04eed2527c317754d4f96d1ca4936c30c296e2c1fb91d5184240765d62dfad1b80c1875d99d2a141592faa57050584f3e87194e5c0fad3238b1ba996c7106396974c57d123dce7b4e5e0169da8d94b9d318cbd6be9a4a2b2b594dd30c6dfa7d5f36b68571492a72ea7d648944346ffffd6a90de7fe75a6c6e169acab200e0ed04c186d4b10111b14883103753152eb0b392060e4477925c244b2eb7df0f495ce15610a438fc01ec35291030c3c837ec7215cd64ba864bd09da9e7e89c04d73d7fea3e894cb379d2c668c7f45201df27d3a9594c7ec881a93d30e3c88410c724ab50b3d8effeaf34d7e7444c60cb7425e5dfefec354d9d62149da2dbf30f3debb2f3c45584393290e24e89cd51f1ce73c76a6bfc9e436d36a06b6fe1c884cb58457afb0d0776486976b606cfe5261a89c93cc0238c3ce8e1d8bba415cfc220ea1f0ad318f1e11d44bdf1e2084edc63d30b50386430b4395da8592790b0c98e3d900252faf71e9cb8d8b88a9867bfaee3bee9c7652ac291cc90fd1de36fcea810c8534a3c932d23b05d4f73b08beb9e6da83cf1c8ca52385f1d7dfee8c3d76b5ee838c539c3f3ad6724c678b7f1da6b75221cc7391a343d052a8532b6f23b2fde6003da979a8683c54b0f56388fcda13965fee9336daa77de87b3aac06954b52443c2f8659d7ef5858c3e4b53cfbb4e5b14313fcc7707f0d83f6b1a3c6bd8902032bdaa2be4b0801608919cab3e43b3ec8992310d94d32812b1fd61e93dabd58cb02b08c63333bd985558f45a9563e0ea825f605c12d73bb06ae17c1dac4edc852421ec6f63b9047c3729dfe42ab917a3131d88b0ea1bea3745155563d5ee44925aa71a891cf5133097e27248b1f614cd783e3d7a1b7ecbb39839d08902d6fbd8600086b3aa332f0845bcee97c3ad29c005583ddc589140d7c91c6d20e71d7791ff884861a2429409b2b5881992643d82b9e8a3d217f1bebede9510b7354267791b3d5ccc48ac58ebbd1b8058798b49225fba086d29be65f5ee5e361a6cc0bc4791c91bd4aa207e43a20ccbcd76db677572e3ed88016a3c56fbc3c24d4286acbe05372697201cac8d1df1651426abe62f4a4c845fdf4b539a37dff86d08a115d2580911a515a06d51b7c877020051faa23e190eb71cba9c9c787f9e6f152a959ae4521869a037e7b900a667e65d775444d267f12179ce0b9670137a5da37b9b0b85c9f229e203fb05b8572f8caa0504e7df53811b1ef90e50e878716d5f71404349b72681499e1f08b4bf520ff2a14a5a3ef99126a462b4a642c517feffee5e63621740f560e0e25f54e6da32a5643c0d7fd802de012b96e6eec05d7ed0b40b2415f9eca2ee30a5ce39a0ba6ad86463c33fcc827e79e85ba52a09a864c4245f9af98a02ea618c4304dd6b9058b78cb961827291860c5d7afc4475e75cf49657555d830720362184a1b8c8be306751917e34340ee95c9dbdcc5a6d3eb6415ccd1930bd2ddf8363d8786fc4398dc89530cf41bb287d534b7d56a47606104c030d6a4e41ebcce97ed8c2b9187b8b11a81c731c268073390ab029df86962e1e1703ad02f262e347e6a9e15754dc1b156bab35c1c9d540ae3619ee3efb0307fc4e4b59fc927f75df6aae55c136293da0b49842697f16452899b5e36b0310d4624eb8f434ce4bfa7ae44b8f02f17728fd6366322287e7ff93317013a24bf054025cccc17cfa73231d73fb9ceb46b923fd07068471da3232952c9720d68824371f9ccbcbdfd9d2527e4d24a030b480cb59965362105c82a4dbbcb311c2689d01b34e08c3ecc9710f724a720f668aff6ace4167419245f4bf6a5b751e97684d57ca53d41b0db3325210d31f773b2348afa8eaf79312f60c275d0d7a6658c1c23cacf48c1e529a121e72436fee10e71f6678152a8019468c9f50fb435bfcee78fb8316e43bed5d56b9e7c7f3ddd045375f33609c20766cde0c791481ecd17a7575f9406fbe2d900f9fff0d1c7d2b2dde9438766de5d03a1fa475638b6b300ac7039543c1e247d72e72ff776f0ea1b80c3d640b034d423221df81d18590a36cdf2446871bdb26b65d9f517eff4738c0d2936e55126feb30add8b8413942658cb5085bc279328ad089f25c638e42c44b0a139702b7c5787475036631073842d96167b7fccc5bd28c1b84dfb3f6254cab99bf2d78c22814e5940ff771d21f68b56284dd05f6c5369f9201ad1cfe0f09b7f86b7e4f4ec4c3f0060e1b7389d34244ea6c85ff513960379da3fc967ba99fc5a067d328aea9a0486da6e846da76e925cc596495c820ebd6fa39bf50e68bd9e20746fc7cd12621bbddc4651251352987e9e14221a75cb847eea5538251a63a45c84cfebccc50b211431c1ab99e197f2886891910490eaad0c7dae5a39e7168d9a1aa970af6602bf6ca77badad3e02ab3ace9694644c4dadf0b93cb05bb78c32757f5f85a472cece8f447e34f9771c5d8e4c7ad2ba8a3a294799c88e322ebd75bf0c934b1500183ed04b5160e6a23724ba3f1918752707653cf29e9d5b2f1af5d0516801b493e03618023e36f79cd0e61e38394c4549871aba1a97791aa29d8e209affecbabc630a467ee6d63c94afd0560cce166f4a334951e76b3500937310f7250025197b0eb88c43d37fa403602898858ec79be7b3ec3c8322f14d65e549820bb515775a293a568b44e86c8517ecfd25609bbcc12364baf842e2fc861c4214aa636af34bbd0a3c680106abb71d82c82dd50b9fb82fa0f54689f4e601e74e1c83ec4d61da8802762072d82470dfec09fb5702b793cde962729f7c0b7df45276c04dd8904fcf98e9d30f7e801b90290a8dc6a30a19817601cab4d29a73cdaa5110b732dc61fd2fefb90084b95108ae9fab2c83180852a75690d58efc2c5ec4a33b6d33a3877150f0af2b4d66dbad8a39d27b5f4a918289c172224b41e3f74c5a31f577befdf96771d76247d0002b06bb04d216edab9d1dc7a9298755778af3a529979f08d1964c646d1a6a67c815392344be1a4be34b52a905a558398f43d8e6f61b23e6bb6ac6970f65d5ee20eb0add614dc378a2b409e0df35cedef17e885793fc88ee4cca4f3fd0f4f22a4fb331a63947f25cc80b7b89ee3df87934162931aa311084446c25f24829f7a0ba3f4b4ac9be2191ddad6e6ff9c6bb9b38e05e9d7e4e9816a14f28b09ba9ca1e5bfd37dceda63e24bfaf59069c50d1b8b21df7fdc3d616c0682d67a8688e4f620d6ea1c1a3da6a9c5aba747708205deb468b28fa8c388c25eb7eca6278569ebb532ef9b3c68c4bf5e62e1358ac7fee8b62731fca7e1e56abc042cf86f8771d14d8a8a19cac0b3d7d3dfeff6663744119e243e6a867f3558ba3d527fbb01d814ab15fa517707a20087ef534e9f7f728f58bc53747edc22c3457d4a78bd8a5c8077a7fd53bdd4b3c310bc24a21f961857a4c3a7db99d817549192770494ac540ed9b5b280d34a147c87032704e584b28fccf6a59122a33a8650d52bd53727a21a261d79c27e42a414c68bb57a97107deaed6b7797960e7a706d87523953ade62e1779756ef2c093e0c32af4064e36cb5912759cfedf24137babdfcec6a16cbc32f2adcd43881a05e5daeb6932f2c58f1a6030705ee8e6f8b4e17c5137bdcf4b9439bd60d79fcefd2ced5f2effdc38b1c3a45d8468135c10cf67919531ac850b59b1175c05ef7a8c2555119106d32fa48ca633425bb4d3956084eceb7dbbd47442b81e3b95d9d0ceaea972ab3dc68c2c7f68c46afc66c418c8a2fe3483b7f5e35105e9d0b21bc4a5364b8616fd45086bdd0aac0f0c0d56b76c0ce6bd1773357c474cfef1ed70b15c8dde90dfb95113edc773b8aa0c96fe400ab0b44c009801d88b237d4d0908fee67b12b99bfd62a4995c0e252454cd66f3ee62db3935149c2063c6d7a8df957de61c553d96fa46e9708588378831fde39a7705c0cf953b600612614a6a9c6dcf6166d48a8263ada9d39b9cbcfbc7b08177703be81456b352102e36b81a7420f678d1dfa34648100c56bf3945f18924ddc0bef304e7f69cc7d8b5444dc1a98791805077fc231fd075a318908f208d297aada9f6f4e5698a2dcef9fe6591a892810d45eabbc1d35176950b6f90f60b87d8ebbabfd6b66bab220e7ec57e86e18e22bb694d333940e8c1231569ac24f96821385a7c0786e79760af80de6b8e4e8f1a0633fbb624c8e758fe321c3964ce55db2d06e5fa49ba6a0e35d5760e46414bb8c10a9d8352714ee59ad8b30c5085a88b53ea6fee32e3cc1688da0243347edbde647e5133de2e46e2f6202a11570d81a2c79ddb9cdb94a1d89664574e77cb9ea1283383fa5ea8b2c53f8245a9b3d04ec9f5ed55327011a70417ca27d7578f7fee828b041f4dc892cc17b3fd5949086d2a21f3f3317c67e08b74d927792660f1bf69f4d5b38247c12ae634b889925ec276b8fd74e3bd89b4bd79fbc688cb6e339ea6ebd6ff2b41fd132d23bfa9944cdef045fc0915131933a4876311316417cbf8e24684ecb1045d5c5a771bf59403b1f012410381be63d4320712b418043e3d6d6d6bea15990ad6f2b1f44fd821f7f429d3dcff31bd8c5db63a6fe4af4e2a0b7282fdf2be2df2a825597ede570167dcd53789acb4e88f2c138af788084501b6e601f25f6157b52a0d7ab6ed09eff2f3bb3ab554c081ce7ef92ffac342a022e4b56e32826fe8f206d77b4753484c7a121a5798704dec448fd65e9c8e369b84c13ac4fc7f73eaf983f98192cd09cbb0f4ee3d4f277fe8dd1d0e9e25202510e1bcb66dda18a6832fa1e1842fc6531a1effc5ca7615c04ca133a815d3067b2f01f474f3ca425224d3295ad3b4524b5ad18fed048294f979cc1fa9aa8deefc34ab7de4d723e502c9fcaf54591aa5f51eb171dd22fe38b202580422e5cbaec59b186c39395a07c744453aa83d4fb8bd8278381226044f4dcd5ae13fc65e85ad575d19220aa501e2a11625c60bcd88ab5f3497e8655df7b656e5c081f600c4019d8fa3edc9808a05c20163c2a5330f475fd6f79b313ba9e6a07d7041c3d09d91fcff1600acc70406c7202d5b149bf13ca5d6d92c3811a28a8b33dfd6da3e3caec8f0eb7aa45fc716fa71487c94cc2d4ee79af97c2576f6421f862a334c952e1abf5011f4ed01c42e997c1224669a1909604497e80909274b8a41a41b91f9cbf8e12d1991f38937c61e568ba8de518f0a903fc485b0057cf869fd3e169c4ac0f2ce6423345a38155ede0d88175adc6097adf133e30a3021aa150b005787302ef1c44e4d175d67798fb6a8e9fa35846cd401c6b85e7fe28d40e1bcdf8e6505441b35520e3d7350439e6730ce07ccf1ca3c4a016012f33ccaec5476f6283e1418123f3ae2055ab63669f985303368b65e44a95cd74cf59d1f0478d5c8bab78c0c40a073944fdcf9ed9b59f1166bdd792b8b8a2e97fce3b280cc693e63cbbb44e26a3eb3551a8ef188de2fee36e88112bb751f8b1bead153fcd7c834cb8071e3a74ae42a37505149e97544fa0dfeb02c73289fb1294d567a8a990306f073dbd731dea759fa05620b60ec7d505ac288872affcfb5b476f200d12f1a06d6410bacd41a7c54da39eedcab4fd7b93dde5f57cee9765274ff2e082ea4a0960415d3825cedab2f82fd2728196e9d189753bc4ac4e2cd7d07ca5a052680f88bcc6b7229490b4a7455b385a0190de3268c549c3234f13cede04f21ba55f46519979af0e57472a1d2bc32adb157cd7fc5681ad081f44389598c1f0e98390714bb130894699aebb7fb2fcdbcf988f7409ddf112f12fb890ad4c1df552163be6096abba202f6614d02779ecb5f530591ee1e15ca1261e1b19b1a29965671b346c8330537c47cefef86007d0568aca5c3d95b4211f431ce5550ff38100f10b00169fe34b9bad4b8c9a00b696562c664182bfd1ae1ad0062dbf62b938f0f50c51d144e352ddee894811e8eaa70b31dca14182fee0959a9c574a0122fdc6a9cd2644285167f77e35f616a6f69447b942c72ae59187b794e9731f2095ab4f25ad71f120e3f444b748001206776aa5fd1475ffa7cf49637770f9e77cd9b5dd53890baeb9f7cdb352ba4312c749d0aae4b42e4ad32b11f05b306c43391fe05be11288e99e48f0883b4ee67fdff8d9c3a4e4feb145de6bb3d78ed1fb27e5aa9ef0c130af5d2ba05e14d3967a30fc80b6387867eeb5705cd5d85cb7972eb87525b1c24eabde8d0f79074d489d3d8e5b9e557ad666c0a30783f924a40fd2d609e4770ab8dc838b8821dac27b4f802b9faf20cd316072ff456d892077cd4c06b5171329bffd064d26093dcffabbb68f04524ce840eaeabc605db7364c156b90fbafe4abddd11fe1ecdfe40c8f4584a9522d96c87d07bb471343c916558e8b2f699313c708a31670e0a5cb76f05ed37fad7a695b40b25e63b96efd0793f725ccf1e57b98eba04527d1db5f249d7159f932f5cda82b7d443f8e6aa8755f4e3b1f10d9bb0a59a03262a2cf0372a8a5f81bc1f27ee05a230ef44014bca0d33c791f928fa70783ed64b0c1717d678f9c76f0c87a48906e235174a27ce7f1ffa2f05d32503a5b47e51112151ca541f2d7abc1b613d3264f4bf589e83b551a780478b141132f981a2233a1a4775107e759a8bc706c604ec165de94fbed2ee569885542fdefdc798522bd807534cd95dff9cbbb3a013fdc37e35135f319380ebd46711910bff1ef30afaa2267997b985890bb796d66172721b86ccfa17690865d85249fc412e0c556c24ed2e63637fb11e479c4e6d95dd455d9c81fa24494b5e7472716a5f778fd0f7ebe20e37986a57907485a9b3cb742ed844190a7bb59c279de68261849822426b364a2a9e5cfeecd3e2b9e9e284b50613432df116256b0341e8593c329e541463d14ee0f368a24d9a371128c5e83740a3610f2a83015519d399e1a71f42c73623e99fcade5904e4f877ca72cf4ec1c40ab693c19f2cc6c39c9239d96c8ff3daf00d38db43f0534596d53f7930b44f3ea1b7c8ffe58a37bbc1c52e0d4272510976cbfc58954d61b0a3b8a3da3284b35933564ea27252fe2349aac64d197b2d6bd74126c8ae9b2b213ffbe600f303ef2266aa907ad232d4d6847d35490263c7abb15920a0ba4342fb067bb3b99e420740a8039153a5ad01fcc8c096d76bb91bc047ebe75284f3310bb063b072e97a6ffe749a78fc73acff37ba5ab39f5c3c71c06cccf0ca7433ad74d6b67a6a130d99c025c99810bf8bffc606a4a983d7f28e94bda1eba1bc9ae8dccfcfad3eb869b1b5e4ca70181452538215dabafb34d005af8ba4118c0fd7873f9dd9a1c3115a1e04da3bd0cc270a714d66a4c10d9cb98e0f6bf0784365b9e9158b7c7edce32f18424839e3d54acf05c3e49e2efed930a3207ce3e15edc8ae60f885bc06c6f0c65fb3ec5949d4db49d961df45dfe2b6e065cea5613f5cfd87459c9bd757e0e5057c7182ead7fdc8ff20e8b7e8dae63282d335397de80ac6fcce405461be9b7837791061c9690946ccd40689b864cb1c4eba8fa53ea64f57e5a9a00bb53a20c7273a478e51434f84127ea6b951e7a820e6c05056019fcd5d4fe1484741d6a17c905036e44e7cec0473c38f41e82071df32461f3a23ac3a1f7ebe7b5a10a99600469ffc7677d233e864527f019de94be66147cf6bc34e9fd83562d7aaf844f96378390b5b047e9422b151cbfbc25382b9e5a674ed26eaf63e0c45ef750f2aefcf4e0d4a6557f137e393be05039f5bd6b3def29d84a4be74bb439ff5ff6d2fe0d904e8de506688de220a30f4d4a1e612b2740e216fe6745da32930e54d2e6deadd56ab5582b91265761bfbe313f6b72c1d9a83f07f94e849e4ef097c48dff6a103d0647f03d67437b8d01c4a0ceebb58322c3c7fb6a7a998be29b2ce89f0b259029e9aaeb1e8d7fa9f43aff3a70d349c9f9cb227650d680cd7214086313e00f2bcad0af0991cb690063a41bcce9b50d8154f8f9144df696904dd6d90512b86fa44ecddbcc2514a82fd38e239d81f6e583de1ca957ee3177ad6f11c0341416ad185b8ce981a992e93519d7ec4eed383057174e90d185f1fd612254a05a4456761906bfe7c6239692bda4cf25464bb07ebe9d5cbbaee52ffe0e1ff72f7cfa9f34f2a00e3ee8bd623dbc902eb4e6c79c14dd12a821fe45e504262163ebc4f700dd6edc450136d850327d6febd3e5655b1d68251ef1f3cd64befd0718f3f8050298507d719449fca0e042af0b107fd8dda31007b079bb03a7cd96216256eeea6efb6908db16671504263a424b1aaa549636077295fab4bf12bb64da38ff7c17d452dc895e19235f8185b32b2e4e85de648fd3a036797c94f0424c8952b483c74e7f0da983932cc61088e6dc72352b66dd158f5e894b0e2eb63c761b8ac5c3b34b84723da23a747e942117cade33a3b4246ae699dde13133e80e643f8b87c3dfe63f427bdff2b6ccaad14268c1219c24f9fd5a7794e6e9740e80721efbba120518b8f03a6e27bbbd8cd59ef31c48e241d3ecf65f3f44b0941c7a6db1c374f73f1812d33df3acc9f0e2c5a89862fc52ab17516d5aaaf5cd6251fde032bd923c50134304744cbd1d88cb04c81f9affb46d434048c7c73c04a92c6483a9d0abd61d079b300f265b4f69e4651f24c18f1603bcadaeda5566c16314d3381ada2a6bf7864e9b3d5d8de62e97a4c8aa6ea830f41df8e41e9147c3b06358d4eea240a3d1b7e3347f6d0ba5b8efce17627052b7bd054d7f904309aebee5a05f58a4cfb0fcf539cbe101c6c792d994f0d005eb2c5cc14d7e25c94ec5fdeea9ca1fcac945dd5f07b2c739a0b16174d6fa9d22881773975f3f617b808ab5b8d7618215ee038ca23bbf0370051991e044a3b3468c70d2e0e5d8204340d5b04d61de4df6a45f46d6da11ebbd7ee6c28f01bb58989dd77efdbf707bd276ec0a8f62a14e857e55176f8f09ae1a59df981df707d0c1b77fd05e36d099abe4c05e118e6a3352a9018c6507f7f636135fccea4b07c91fbb0400112eb81dedcf5035bf66b243144ed156c413d2c12b48a259b336565a3a8b79ea1cc08f7cf3781fe5d078cfc45aaaa4a56dce9e275228c5ba51ea1df088d0f216f68da6c92cf7277e4c9ad2c82e8de8ac54c36ef139085ee0261a2566fb8c5ac20b9344cd935ee10377900db234a7aca5e5ff49a00fa55d561e680dad06970548429a1b55d3ef78274505e3477efcc89ef946c6d735833c957a7070f21b119152c2d3e820d4f863dad419ef83c43187e2d20e500b3a180d5158ab8290d89628a954a41b07cb7fd33855e80965acc7cac97744a2b9918e55bc64e833d7e422878c1813b40d33279605cc7996243bf615db76a369be95b1eb80dbda757e124453ae30bffac304d4e39b5acbef6abab290074fc13d300a92f3e9b1565a92a9c8c219cc727acc17c31f0e8348c7eac6da35cdc8ac66e756eb71a70c9e7582bee982ba578ccc9fc918335c318e6e559dbaedbd304ff3a9690a237d57c95ee887c15b7a7fdedc2de40888d87d9ab8494d5e59c000698b15116a685e52042175e696ef97ece1586bacd5acc889ea575c668546b74f76a2021fcf84c18dc8646cf42e0976be130d8fa4a3531aab8941339d534ffb010184903b7e3f74ed027ebfa2e1b4e93266f13974f5bb0bbe30b285ae40e32bc1c8b75c64186354bb3cf50cdcfb67224bed51b0d13544fce4345570f50966352c3b65a72478b0a2bdb5f053c979dbea10d01eaa7d5739a2ec29252e0c4ae6d8cf6988c3f23247e79a474b562dde1cb55a672706f08660c4465db9aeae212d2eff61cddf842b388f7fa99ea9016f7e4ce31e71d6aa5fcf755fcef81c81590dca2b389c883761a39b6f414b573e56bd00de110ea1a43e85dd4c2e1daca086858c1a195de1e5bdfec3840d6f238de14518b1c2f7fd81f79b25ce62c02a5c36fac65abf45704587bce5663db7bbb12e2b721170fd153ac3817c569539267915ea822730b0f2c90dd1f0176cca5f14c7e188d5ead8eb9f432c135ab00c151cc21b2868346a0ea2a2155a7a3bde1f044868f42d6cd9d06b5c480e68e7fac8297370ce88d0e2f73b572b57a423ac2ed4b4515ae1abab4f6c8641ff51082cdba6211ca8d4fc71509acfc46db7e6d70b75591e5174c8898fa72b60412c7d2acc56e0f04b90cea0953d3b8e8a166cd98ee2d99de20ce6303faa871ed9a1e04fa8b3d09fee04b47b2214cc5062050ef1e655b351d72ac5a3b59f3f362f077ca37dd4a82b85bbc66702541919272fe4dd891bd052ec16f04e4b44e15dc35b186ca2c37db655e962041e1e87d999009c8f3d5b670b90e84c6ca5da547191b017005a301e4a95175b6ae7056433f7c51ec13d7c40e4fb04829182f97640f3c808a84cd1de8020b6749315f551e648367800190a4d9cb72ca2ba52833627b292d862afcf7470636be1f181f0ce5c7393e62108bcb35b16d06e50f5b6b45e617a8117631b25ad10944696e2094866d4c6cfa8f95422b8d83ac0b239dd2e411c359ba98a2d628d4a270f6f1a2ec2a155a7e58b6a14286494b2c55a4c2ca1b8569a99a072b6646df6a86683ea37f65db5080a79c8ee69ec4911a48d13b06a828274e99b9a05e67e03f6a3a942e98a1de7791de18c28cd478cb8e1b8a442666b3ab1c7d413fb55e922fe7da1d9b9ba32aa743bcae8671c0793e7916dc2e1491286810e1b8cb1c488c6d0fed38e978cf2f93c6053f690142bf45293b5a297b7b9afea6622468c57f9dc1dad487a49defef82c3496bda05e7c5438b9d3ed9b523e7af2bf4ef2aee85ac6a7327b1f46aa49de300be64d8524b80b9c6351bfa2e54a177845f75e7635ea77f64af2224b03f45e35db39465cd28483aabc9afe142e93f674a013fdf797648bcb004f345e593a11f2000467385700d51a8ed8aba0765275eb2129101b8ce6d1aac4ef971e2629317a21152dae0bb8f4d33bd3443f248a757c98b4042e740450b86622333dac4ee007553d0a68a64b8abd5d422a31054152280af6778a4bb0b5470c8406f649e28e7fa17d7125cddc214062d9cebd2a686e80e0d23d7ab612273f4691f151ff45d82b40cd7915731023ee1961ab2bc856ff8b51e016cca77fd80df2662ae6c77d1312f9a8cf073eaa3e1757703ceb31bba8a3ffa64d72a787924d96627a76bfd85352da4b3875a1fd2ebbeaf0b24202cf9ac056a6b851470bd242ded82a729a89191cc14d598e9e2126a260a41f69a13e0a823379ac9a23cc4027db7b5dab46296fc5ddd1baeaf19102c155f46a20fc267fd40cf16c02c8995317b87e401ea4f0713ef4a6f059ea9b94da542b123f9be624d3389dec45bdc696303ef93f51a9d9a12e8f1203b0429f0f51911685cffc8305f4ce813a7c246c994fa864a1daa0f2eebda17f38256f2254261382fcd60c368e8847bbdf2df5c96e13d1073598ae59a44e38cb4e05a8f4b49b3e1e5e642bf5f758b7a990f5014f15595934c00a896af81b52b59c7794e074b824bbc38d3418ad07494eaac02b2c5d8e2a9854a0648e10d777a88ab73f55a04586cf7a40a5df275856ef8c621638a451059a20739d8a18b64cddd78a559052cda6113b12e910186cc8f434b276080e1d8ebbdb3427dc420ae0676922040af1094b61123d95720f6db6e92312d7d2e14c9391b27d7026dc027e6578475900acea2e8df7aef8dbbcdf246bcf325b2453971a42a16d0bc39697d4c24f215f9fa31cde87cfd89d7fbf0007570caf38147aff68c8f2490216c7a4afb4ae4f400c67b391df6c40529ae22094e99c5fcc1311baa37d56e1b1e6e29e16f5d405d6fff94d98ddb4c6bfc3d9e79f16bf247162953002e9a13926adff202010590935115eae1bc1bfefc20cb9f77b31c19b9e65a76b5d9093280a4653f173100cf12ad64e52958c37ba862681c8bc2e4d76a7fee685651fe55dd14783d4daf701c24492da4185a808d69e11bbe934ae9eb11016f8d967b3ea675cf9d609386d04e7b1abe015251256414ef285875d68da0af1e2b5558a6d901d930b3add6d2a6fa47ad32d4bb640d7b3fcff61420671c66503c6b25335f9a517800ee2525bf93b2dc7805469b048b7517f042fae75d0e99d835da893f4b2ff9b3e0c05523199c47d758715b85166accf13891e8f24d708a9818737dc61ad01299e5cbd959cd5db862b20e30d548d0be393cc1e78878aa8ad204c28102aac355138fe15f62aa389d0e5762dea77a2b420a1b3d6b8a2c2fae4e0a89ea3988b0f53d0fd6e74bf41c73050839b95f01b1dc266e13f77da602da34ff5f39beb21c03d431d1e9f8419810a3bd5c40a4a3b806aa82b7a068b67ab540d1dfd5d986d8bad1384dab187e80d21e1994ab71dddaf2f2f7a8ae47a1d3e05955d9e44263e12cf87c9c969cf9a0941fdf4331af3bc87993ca1ad4b4938a14e529f1479a13759313880f5c8d6b31835ebd987fc4cd0057b072bddd36fc2b7b0c3cb956399693c4cc2a7f447c703fc52246f0c978fcee33c8d94f7bf3a305d910d2fa8514058850e76092d46488b96de0b6be2e046a972b640246bf59dc7b1b5962da400733c2f78d47ba0bd1bade2dc60c1cb8c10890499c7ad1b411f68ff275004e74048dbb43c5cdc63172c9cb40c4162e4d1c8c90434f2f2dfc89e50cd765afd129697b415ab347780db31f6404a0cc21a74ffed0807c5801ccd1730200be44c3e46d5011678e7839f52e735c58f958cce28150676aa65644d7ce6e3ae0614fbebfb834daf765f501c8c6780ea37a6c4e17cb967fe361f7b15b77a253a5a946b78ce9e7c6af1e505ca5573c13cf6d775399662a7a67ed0b7bbdad5e41cece515e3fb6234840b327baab7c5cff81b530d77dad6220cdbf6ba651b684a5e6b7a5c9a33f95d7d4c0627c9924bfd0ad1a6e661e907e872495ff53f8d07bb3274682dc8394284dec53986985b7cb1df27e454627c12b7467889259514fc7de6d544b116da60752d56316b428f6623b6ab8be5e6abff9e1dba0aed5bc8619a54a4ae6ecf894388a1a763f4b9eed9b271785864a7f12ffbaeeffa98a4d74a3ed8d1e4f1df5b8ae031b39e75ebd9b4760a0b5a262275a38ad3a5b655b2532705d5c3dccbc15ef095a7938651bc063209ef41073fd79326301bd4ccc80a42a0efc7ca0d1beefbfad0d10ffcfda5b75afd429fe058561f973e1a8f97790a10ff0585245e50a631df9a433b0a1790a06ae1abf6d3d6c6b59da75b7a14c35ac095033c107b79e76d4c6cfa936a99673644596a35dbd2b99792bb31e59e103c196fec92aaa53c3588e97259bd3333598ce0646690d49a91bdfa03fe853269aaa798d8693f759fa7d916aa2159b57e51e666f041ac64c21cad18759c390e4f967bf6d72e7b1a3e0f79983f3174a9893239baeeab86bbbd45b608bd08f789138806eba38ccfbb91473d98f630f9f82d1e1cf2848377f0f67eb6a8b4ab59beec0bd235105d27d2e9ab4c51245cb046e073fd9bc6a71a9209c6885cbfcbb3270c5fb5f222ca6ecb8a6070f0bf5e7f2bb457044bad4e254447d32714a74a9750d2631c31739afbe17450cb2ee0397fb32867fd25993fb8f2f8860dbf9c9d6c60741024f4f6d68dd9cdfb74981afbdf276b81ee52e35d6d94b950fc1524e7543415f64c26fe634ca50c86b990b38e37b1c85b26f65e2b10be289d10a4f9b8613eb940560a4cc6a076815a262318e87ba529ecd78769438c77626522d55dc603093e72f37adbc449eb5143780d273682aec1d08314e7046e6e943e046dd78fda18245095c7c12f456fa0ba1d73c9afc5474855ba61b7fef691739f3f4f286c39711394aa1c0fd91576380e94c4b1d3d08fe1a260af0b13cd3c1e4d32b14033506866bffab7b0983399d7a65cbcf84519ee41dd0c9db2165f6610594976bb6c282107461f3f1acc7945929c6d420a63ed2340db4f55d6318976896e26d7f10568a3d90616a1d4c7b15526dd94a15b18036c8b7d1fce3d0459cf8cef7dcf274aac84a3d456bc616ce04f10a148386c372b717de1848b785b6dac23e20f9fc8140ea13f406c7b1b8f2b08ec44de24b8ecc769f06bc3c38448dfe3ba2d1d3fd5be7993c8cd501e008a01b0e4609bde1bda6748402d81899fc2c34217ff90f36795841b7a3df24897c08eb5bba89a5976850c6b16c1a0bd791f787383ecd8b3d40c1d9a05d2f7bc66e0e2ef4a92caa1a4ed3a4bee57ba002643686b27ef0ef09f0395b05adc510d20bdedc530f9f9cdc7a8e57b082b2e14eadbaf0d33d0fbdbab0d784a09d15ba609c069d4b3663e72ad9bc7583901a2f3a0911dc8fe120c3c4448cfa755121273c97625a181608ef564500c2d6ff7493655c82c4860e409822bf66ccb526d1e516d70551e33d331c719e15978bcacc0296fc2c061428b2ba98137eb594d4d1a4bafa91b3e4491d2f8ff720f213ead7bc03b8fb9f847530290f5d2b44d2500de48bc7dceafe086612c3ed90fa7fb23b7a01dfa59fb607a565fe65ac0e3ee414e1c78789b29a05755d7ff7cdafa9f37fa6ce29faf0f77b88ef31861f72b163f0269311952c76571ba44d2bbe3b3e8c4e8b57475fece76132b8eed648c60ce9b98d72ef4b71504388e2b19a21b070e09bbcdd38525898cb2b32fa7f5eda3a56af3a022f71a2d64a43b56f471636fe6d1808ecab5571803aa0f2d6b630b2d660f9cf7339fe498b6da687037d0f4aaba3bab4467225fd6092ae77764b3a5f2666c862915f87758a64018db2926c352d58941a01f05db6ff830b46ae4da1980293ec2e212859a03f0ad3c0d60f491c0a58f4881c47f3ed634ff6af076d096b99453801077f8377ab902a540d432b84098cfee8744e5111de5e81af2ba04a81276b1ca3b1f65256babff24d198542f7f6d0050c1a4c33de9a390228dd37232045076e1e41dd642da142a5fdb9e46f01bfffaa879af3d0f4a8363e8913142126aad9aca80d07e55410cd692c7fb00bd6640fe930b09cfb433d28e13f9ad76985ed5dd05f7fd73d6a64c4bd60e22674c7be359ecf016ef25c427497db29806fb4d3ec5a6a59eadde95501361bc1ea04a700481a3156105b39aa1808c32f2c16d77bc36bf208255c5455daa2b6a78b42ff543d07021de84219174231b2f1e542b37437d98c70a6248a4c5e49b45ce7acb725c1dea596de2107f985f9914f5cbe5e45103bf15629441cf012b0904fb6cf01a7833db369ab4120fb840a7e463b163c81e9ebed1d25028a13de26ebf3ac9295b183515173ce1dc0e023a4b52d3ecf54c8e10ba9175a8e0da64ec64255001aca8662cfb53c8e0c1169bcd9423497a71cc8fd4e806cd9fa3c4afa643569c699304e1bddf0c64ca0f9110abdf483851cb23120f3155452d333b45e2dd19d973e483c558a95ab2fe68c674326f598a33bb390dbc55857dafabe2cdb0b02f9e1e07603cc50762926c14d355ecad61c1f7b53a5fc48797121aa85bc1f74712ff31109cfc26d10f0eb3ffabbfefa990554daaa81935664a3e697657dc94a5b54e81056c57577bb0ea4db35c91edc80d1bbe8dd1e60686a86054eba63aab7ee0d6208cc623d46ebede6223d92eac21f404659c34bdd3b863fa4af03151ef063653126d851bbb8dce75a791808a27995bb5e2baba32ca879fdc535a3436c416e91f9db1158cc1f971b19bf7f4f7bb0f4e1a7f105137a7dd42b40ab4cba82c9e712e1b3fff578aa57344cca8de376187a470fcd2bb36203015d578368f848d9972e5409835bca1f762cc2f80e983fb53a45b5877d559a153e0b2b48cde10de51489e7a078b77e69f28fd7272a6eed35e8561b36ab339abd7f5152e69b1ad767931a839ec9f844a101e7bda80e153c4e09fc368acf568852ea805178c6ff6b92ccbbc98334a78ded925bda9e28191182ddf5fb14bf33716e64e5c47ec15e910788157662b83a37d92ea61a1b9e6a4613b58e4aa80ccfaa911edba0e67896f028bda96718f49ee3648710dc45e33cf2cadd9787bd69135e73ebe4b41b70997606e4b0d8f66ed73b77e97db083192d3ca58c03ccd663834ef2593cc22c7b226d1c2466986f59ee83f72d5126fbcc45bb1fb12d7ed7cd2ec7a8742df43dfb9dcbac8fb460f099cab47147eb00c40f6962bfb20fee98c52f2cac370c413c5736f9938cf9e6ef404d5e598b8f6b9f7219e670b85b49f57facd1be75e04418bf36c3036ca44b292ccea590ab50ab0b7825d6de390b1284b9ddf7783689080a421097d4233aa59e66247ff08317d8924dd052ee838a39b3cce7a8190abc3684e6476c27563f41accd726494a08eba36f5243491b4f22b46c0d24e15fa0bfdbc45f9c4b4046cb33aef000319b147a6ecf3de89407ee1167148cdc7c56e07dd6a82923da76cec4ecca30b2f65b8b116e02f2f69c7e5ecafc7e6e822de9e3f312fbdefb712455377dec9e3b243b6846a8a580648442681fa42f6c520ecb6f9d64640bf80172e5c87c1af56f4bd73475979a971603db721620a7edbb4b6bbc9f51f0104f02c96237425debc120762b72dd7bc9239afcba64a539f88fa4792d8c4869ec1c4c4ef7defb8954b2f467ed77318c6112512537e6cd1667db5fe9020af8a6d1d7429a1e4eb1c25758a7c8fae675144844b473beadf4394f98a05ddea35a849f65446f81d0f332425948dfc05c52ad8650e35adbe375561d8eea2ba6a8a1e3d91807bd03a29b8c754fc08e9a73c4125b4176cfe5669580c0be78b765925fee4bd84bbee34e16a5587aee3ee93090c5213b260d875f08110baabc539f85378214958b80f9d6934a1f64eacc9e5c36aebb47202dd828867cb86e0d6a7ebbc58d0a779efaed6b2310c959f18c5999646d6cdfcaf41a311093fdba578c5aac1fcaecd8d642e43fbb06f5d2ccafc25ce48f991ecd0fefb27d31b05dc63557aae9da59c907bffcf1dd8cfeab65515cda34e9e61506b1a510e862e91961ed86561269bdd0697c9f75d763c523db4b31bc68db3e2e684a55d7513505b01907ac93ec4893095c08d13b13ac5d9dddd54e85e6a4dc693bc90d5253bc4daf0bb517979c9b8d863ec06b79ceb8ee1737badadf62086cb894ed38c9cb2463b389511d543d019ecd9802df59d8c315f5d879cef1d132e701c3375aaef254b95791c4fb3b9e56342b2458aa8aa1e4c533d2abd5d42f8dc5b9d1220e87b271ba122547e24e03fa06ba6e9acdca67cc8400a40aefddc32d5affb471e169984aee4bb463dd5df136e264747a931dc1e9a7ecb0437efe235700249c52b00a67e0dc26edde5e829e33744457e489dc08e133cdd16cf92f6aee04a0ffc43e98467e49b2528fc301c293207620bbfac70225534349e61f53aec61c5622a3ca41ed92275942b0c85429bc272442697408c86534359b46e6664106253694d4ebd05c5b4efd1b722e8493bb39ad5eb812afd7b8d6dda1b7a1f8aa694cf6a421e252f5ee9df26c4074513e6d62865c7ddcf1803de1fa4c79db95da2eb08e66102236e344ee6efb63e0b7d4fa2e0cb36a7c8672f6c22ec56605ffcdd8fe12146a721bdfc053565e1902d11ecdf6a61cff2a43ce102f2eba7899e74ae7d6a136c7a41b8323bcd916c120be9c8203b6c86e1b1ea88a89e4e47532f2ceceb1e00b991373dcb27bba9d99b047f8b1b656286132494c403acbd7e59610d1cd8f4c9b1ca8285b50d3ff1f2022768b7ab5c826162540e4b9a1b4ea7af21266231b91d93a861140253ded5ffc73372659ab9321b9d2d9eabef1829083dc94f45e6b198c25557e3356028d87299e86e416dd1c04c5d6d80f29d53d200ac03b7092e2b578d17f1bbc3805b66f3c4c4e38c1ff142e9e6ef092ad59cb7389f180960e025d66fab861052a833945d96364bbcafe84f9213db5bb63c536e5b0c895a63779468e0d3383ef9889391c972ed5ecae0285bd15a4babc70ffa01338cc02a603c9150b3c25709f7ee472b0b077194d81a45a940a3cb99e90c3c7e093de968e0e0c72748da31a230d3f721bcd97da429df5609258343bc25428036859701f9f2896c4ecbdc72767952922e93b8da7c070a8e5d0ba91caa42b192416d3d930a91c39ccde76021be1d697b06c5d5cda2ecfa5ea58c72801dca38048b6fd530affc451f1a5c6b52283a4dd9ab3a9ce6b1680d523916c1f458c7825374cafeae93114ee8faaf4f0eae5958ee1de573c4f4500bdbbaf2e5aa8f3535e80e6d2af177212b87ca12008b4fe421339f87523c92d9d65e0b2d5e853e1dd9213883e0fd76beec3715dc571c0662ac5bc2939db23f23c03f16999e276c903e3f37878e226370a73cca20a523962db3921bf9a1cb0fc4bb4e9403459bdeb6fdb7b364af029f9f4c368d9f971498c53b255b0a4c207b306b5778e6ebf0dedda518f35753994d2ef6386e0802d7687ccafa84291f1c97e83ac06536c73ed56fb8b553cfb8c832f50d6cdad4b30ffec3cefbac6a4d67198def6bfceaad007699ec0a943fd98fbffd3d6ce110306d84107c5863237481d6aebd8b604015d720a3cc8310fdc1be53d787ed653d0f57176474e030f3b75be5705c1406d0b2a6abce168371124992afd7bbb0cddb6269aadd66dccccd99b7f7183000712c77241147ec7b08a89478e358f20aa62fbf9d63a02a2e198a6b4c35152e716727af11ef3746c0f7f4d2aef5c553bf6bf3128a2564b556ccc0d439789914fa456d113c044b8e3839a392e8b73a0f7c179f8e07e5d270d7eaf91e19464c551f071be75faf6cbf91d7aa13585e7f06d6b7a8e3cba9fe655fb869baf1dc983f859d7c32673bf63833d5d2783899d915872389cadfc55b3e6794ec582e7d3067c4a2d0bd772e2e51d7b2afaec7dfedce6feac411a9c0cabeb67c00f989c142aa5b80ef042fd03dab7c07621c3449cfdc0b2912fe862f9310580fd6d5ba4105055b89e115188a8d8f38c2da1245f8f49f0cc8a9d01cfde6d2f36dc01d2fa82d8ca6daf82ea811c14157592f1cfd6873b12f31327a0c29f340b449154ae0bafb917fd7eeb4a5b051d262d7632c14ad4604183c51dba1740b204600caa5940e9f813e85b8605e29872d96b21ffeb6e4d2844bad8f6d72155cfcfdde534e94644aaef57ab154890387b225777a8d4872cc06da3d26bd492a756d2363a16f082a5c19cf5a70632712010b38d14fe2c5dfdcbc3128d7fc4967d7126caff183d89140adae3da3ac3fd4949b509b6d4c78cce9fc618fbba0b0b226c334fd0e010b7bbf063f4b3a732701771be760f43af84284023f18023937f9899a5cd61c396e932e341c587715736e3432a6452c832ad04cadba37a50e81f105e6aa1133dfad29376372df21c3550e7354b8ff38eb9852adda0d6d5de9402dbdf0de0d7fe52a7088d57ada97468e1e4ca0d3521d17f078a5f43125b6dd2634afa88c959ab149be72c2641d4636f49bfd16ec36ae32b48adbef8f504bbb3419cdd4c27c175e8df10a8ae0452ff39e9cb7076832eb7ef617850ac2760afd663617068e31fbf2bd5c91d2a445c351d40a2d27d0e540ad4eae46e042719ca32695b2d1d40078b067e4bf3ee23a2adf9a05b9bf6119bd6d35d65e5408cf85319864c59b3699d6efb0b6a0b1b0683be2ec0824e16ce34b5ac3398806195be9481a3aaf2983a44b1f127148945c443bb3455f3aa8c4c74e2d1f311d6bfa091a17692346f3e5ba390bfb07f51d51834ff764da6dcf9177e15ac04a5e4c45d5db9ab9ab024ad63abe2427e2abcaa3616f11e890ae9760634a9f9f133abd0b622c6bd335d85032190e1216062042048d3fbdae670099d300a12a8183ff0c2122266dd6220e1d6d3f2dc4424559fa84d8fc2c81803118c0fea36939f94f71e1542aff8933e6fe829cc75bd6f805af010928072194ea4463b9a1f750bb147ae126c3b5f908f197b404c784abd8fa398e8c143d971f593bae312b4641fbe4d5e6ea203c77d69bc53cfde4383a4087699cce8768b344b7b9de8d4b9ca40e002c0536cc042a8ac0748adcbb2481b29d0b37cc40bebb492d916f40f56ab2b184d26f86d58d7696c4df288deb9d1eec9b6c86e065a127aae99088c27bea24c431226469f77369c24190f110e95e40dc270eca3015eac05cb6ee750113e2ba7fbe700ca115c52340d905c6f8d74882db64b6d55ac14fcc31e663b6c936bb67c7cb1e8e42bf0a4c82aae339bf58b736f988b8fdb93c40013094433518106ef7b77ee55d9fc7599d49e78a727984affa2e75df357f254a9cd91f3309eaa88f6ff136828eea90fa149c9cf2d9d0a6e7b7706fc70c89c50a11bb79452669db2395adc9b19dd22337f60a5253a793ac9a3c19371276512904487a154447884a5ae4733ae77b64e4790cf1a38fe4356893dd288876f1a36b646388ffcb4cfe279f4553657dd1d64d3d594bc4a9a9e0fa738b2368ffa0ba631d58ecdbc1dd0edacaf89667c7d253953c9d37b3e1ab97d3a9cd734ece638ed499974741efffec2f9833d9ce820aff863d1090f623e3f2414c17d48e588632e76e76fae31c7866d3bc62638d220477ada95c8e6ebb97b941c500f000c34b2ffb27d8970f4bd363ae796187d0954473e6373e5ba967d71492fd5a604de125ea1d252b9357ac33fed4dfcc2b60a16210e0ae0345967ea8757f01e79139851755dc698bd5b2b054db1d421d660430e4556781741fa2f18ad19c98424742bccae448b9cc6271f19b8f971c7fedfaf6048fc371e7f2cf62b168b136f7cfb7a259b561c7c170db31dc369da5aabacffe17a2d9b6b6ada8c592ab59f360081f5cad7dcab9b2ae84e2e6ab01833e937dd48dd31f3e869bcc7fea69b23275014cfe0e5bc5d5372409bafe39523645f55e7b490ed1917931975266f543c01fe5254ec56d89ccd543896827e44886e9e49e5af7ecc0097c7635e06271a61347893f3211f14006ce262eacff46d77260ba4265967af0c8b5f68b160d1e88f40693a676dd4ff792a6d7646c4fe857cfb27f87d643eeb62b436c44fb71a6b4241812c794ab438c9e969d958a990e608c1704f434b8d2d590e6d8b232850703410bbf8f9260c315f707218b223fa62cdaad27e3fe55f6497f7b0b627801d2d8e8b12901c49c2888bb30b1bac0bc47177eae87f3e410cc29bfae35e7b99ef5240792be2d8af4f1a06219d72309e16e7db01bd9bca47a011c1d7b2365b98667b9fd936f667d2870edb7546029362d7579f0e3027804269feaba39660f9c7832f6b667d4065d9266558a9ba53b3ff0f12f3bd3c7912aeb982ba635a4cc1219930e5b0d147b23f8f5f4207dc33b082d93da1c096f627dd01eb377313ce31604c984ff51d7db4a206c87dab67bc5760062f7a491381182bc529a48866aa55a202464bd8d1e7ce6ce41288192652dafb4da413eb99ba67949ed78059a80203182167b6372c961716bdcccba1cfb1a107289225b94ef50d94146d686db69b24a0d5e7da1e2abf581ad1871916b6cfff13d00e9ca0c2394949f900bde5cf9ee560be87cede68d5ca489a3ae2acfaed8d7987448c54c76cedaceae30bd92a4d180412260256ba79e3ab7ad2931c893452e464e70f29d61ef48df3bfd027f274469e253786496f8a3177c84ab879259990ab10f4c0195839212ebb188dc4c01d37d386c4caf277331e71339448868e824f83daf7da61f9c5e32149617cb0fd4427566dc4c48b3abde01554587648d4b9e06cc931e7d940cd2c76eb7c2d881c0ab4aaf66a49e7bfae583c53da65a5cdfd88a34feb6a082d9ff7aefc595f624fd3dcf9e178e5186f216e4d90dbb9e2fa2d4c7c0d1d19799d08a1684c5a29d6e1e42a3d1fad192a02ab4af508c405d79068dae1a5b85eb715a33a4f39e1631a02075032c4fa1df2ba7e94ca02d9d953249d806e532c2f194a1</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-xray">      <input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>      </label>      <svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">        <path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>        <path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>      </svg>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">论文阅读记录</summary>
    
    
    
    <category term="Medical Image Registration" scheme="https://www.miraclerice.top/categories/Medical-Image-Registration/"/>
    
    
    <category term="Medical image registration" scheme="https://www.miraclerice.top/tags/Medical-image-registration/"/>
    
    <category term="Swin transformer" scheme="https://www.miraclerice.top/tags/Swin-transformer/"/>
    
    <category term="Swin-VoxelMorph" scheme="https://www.miraclerice.top/tags/Swin-VoxelMorph/"/>
    
    <category term="Diffeomorphic registration fields" scheme="https://www.miraclerice.top/tags/Diffeomorphic-registration-fields/"/>
    
  </entry>
  
  <entry>
    <title>心脏图像的特征和分数扩散引导的无监督可变形图像配准（FSDiffReg）</title>
    <link href="https://www.miraclerice.top/posts/be28ffed/"/>
    <id>https://www.miraclerice.top/posts/be28ffed/</id>
    <published>2023-10-01T02:55:22.000Z</published>
    <updated>2023-11-28T08:27:09.370Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.">  <script id="hbeData" type="hbeData" data-hmacdigest="919757518ebff9fec977994bf138b668cb49c1bc9096339be6079bb6dd75d3f6">ddc360d448697775a77dd4fde850a2c0e2808ef0978c01a27c380987b2f2c834543128916f59c0f780f60e4143b5eb08924f97d525173c852df5e246ce7094f8398d5f5581a2dc45b87b2de9700c13a04ca39ebeddf6cc5daaf1a3beb2912ea4f09dd86214ea0e8b18ffa8a59aa21b165f889dd24a3e0fd7c9edb1bd23cb1b7086941ed4919738a473dc88e4036caa6a284c20de2b9ef5c40858754a3c93b82b9a0461460bf5381dee066cbc2aa2f3e8a471cf5dde12ea8ca1d9f362c255ae7b9e641c91ac9ade4c0741ecfe71e018359b7067adedeaa4d7ef42cfa262888f97b13860a4d7b849d0f2fa9114a47827405d849f4e2c764be97ec60238f36affe9950239f814442bf499280881a322695bdf887ffe322d79e69193895a0e27afca986b43fcbd8167b4c2bcef8a2e3d2ede4df87fe5c4744fa0aab8dbf7eeafbe87f811c02daeac51ae368e18c2cb8b75a307da07ac440cbd99541203053bd916dba3232698db9444389e74b0fab61c365ad582ad3a6ab2bd1d84d6fcaf8360623c5a36d3441d8f6a895d23df2cab6a8ac4af2c0b1e922712338d98f8c498d513834741633390bc13659cbd290112e2d78fc490bb1f9ea407944975d26bbbf2462bd0deb42c5c1ccc3761aa796792b88e9210ccc7c4681418feca58be12f4e97dc8151b850b09d36fa089738e537b42ba4f4512e3e17bdf00b087d11c654570b9ed5a5197dfbf97b94f11ffdc90e3b6c24a23af23550756c6b45ab0a4d2aa4e87919af04407d04cd9690e4b60a18a32a22ca3a48fb8765a6b964ccf4969cf360e5475d69649851c6493fd396cd0e45c897ce2d138ae71920b6ce57937c8fb5638b91544095c7df8639bbba661a28945f8b82662a9304dd1dfd507809d2294f5e38a7807586a05098bedbcac42b0bb0511cae9c27c8ddc139321e1533a47fa5001b1174ae260c9fb056acd47c857eec42d6938b8b355e063678065a5445c46d884889e9be61366f215d51389be50e895829e2c9df28bc9d2278ba25a8184cf28cf77a5e6aa20d506fc96f0fb9c984cf3b54f33cd682a631a5cf079cb5458bbe10575af9ae84360f602410e9d729ae51b5c9fcec21392b149c773908ef88969017817dfdc456f65be9e866f5c048d6e6762fe406fc02e88d9f23bb3a1783fa9b1dc8eb6d4c4e5cc403a2d01b56ed5a445879347866d26014332a53f32daa4a3bfbfc72b963dd7c6c23de4232927c4d9770005d91be123ca84c6d3226c0cc39a8963526cf3cc28f90708fc306b46d065acad9470368b1679b2c8472b5214bbf9b6f0092a0ec2bbb2ede13f3619c66d41750adafe13ff787fd9f4dd91cf9b7a8402c95e2d885e213d9ce19897aaf268ff17423ed2bd47bb39b8fbc4ffbf94ba433992ed9140d5658b1e7047a4c094a122259024f28f549746450d2dc21348b4effdb540fb44ec11bdf0826b2f60674770b07d7cc21790ae5392ef678bdcb6c71bcae94927b500862a3404e247c5619bacb1b4c249d71bae0351c2fd23bf4b90b719a5f37de33b3244403c61b82991f3cdf4780d162625e3ec1bf6a54553495d6efaf0dc7e0c60b58c4165b54186df35c2b23373488afa18977916242b4813611fda283e488488cf64955282a13c1518fc72b3127c12f107cc8b306ac6665bf57a401279dc98ed949fa0d1192f7182277048a9b75e1a7213ddebeddbe1895965d3945fbae7e00e2fe178c1567b4ed9a5865980edbad3106df90533c83d38c418aa5760bf2de14cc53992379bb747262b5bdd8e0da49653d27579fb8178dc20b22320e9723fbbe37685fa8a091c476cb636108862859e990988bd556a26cf2a6858c7ced3396e77cc2998f1f8d4727de96faa98a2c28932bb419e473825c332b8e375f57cdfa874bf14cf3f0cab4e211b73c9f8ed5047604926d06eba1d86b5b12a613773a6a5f8690d3d97c6af8e801bb5449832e4c42f52af505c6cfbb794b7b23319ea2a4d6d248587f50e061ef17f1ce3c1da107ed016f0e2af695f966a0684954c54396c0ed57da3beb001b6077bd9fc174687a5a64baf0262f10273514990a7343b7a9d3472ab7072ff332148e640370475c348972173bfe97e6dc6f9b2d04a964cf6c9cc330017868b8ef7cfd819c64320d12b26d7b8f60f9967569c54b70b1a48f05f84436f8751eec417ada9ca6b3f6f6f7b37b7d9ee0b2b5557c598ce2a0036747d00f77a5911646050e5ff95807769bdeb024cc854671540c2391f8cd85a18086df1b1c2ff568c2d4f57b2c46b438baafc951f5f5b60d0a7ca8840f506164319b572ff9651b2417cf005ad864a63277f88d9a9017c8dfbc62ce508681b73fecf18d9f6612d20a7e8d117c224ec2047a9aa6b32db5c7417c6f0636585830e1d3c0d78a9d74fa80d63f109b3987b4e46cb4c4cb7727455f70e8d4ec2eaf41101dacd6b7b97b50e759cfd0cfefc4bbffb194795defeda0319997b3ff27ce6af048f5c45a9063f1e64806fe8e455fd0f4219c88af33918dc4ecabbec2352ca5ff19713d38fdff8965b4e7f406ecdb4aaedb4a082046dcd94ce750e244afa973d6f3d3f320c9219a7e17066691c02a09baa225a20499ed0ecfab6b75a4d5f583fbeae0e4cad57324f321de76021d99f4ce4765d85d78d0d3b53a19f47c56cf90da41ac5a46bb8904709c3acc367dc496755b7416d85c185448f29f4f7040366e1eb3f6af25194d69ac53fc8edf5a220b1d9d3a6b59f4218e96568a27e4339af4225c084a3dea44316140835c69dad13eb795acc255776495fcc21d17dfeace76352d84b2b8fa841b2976797d9a9115d91ee7da27f153d714df9cd746a7eb75aa8cb0706954796234fea1f5c8521f92a123b406aadf372dffe94360ce698a15e33e51c56de7d3ea172dbdc2cb1d9f827ea57813cc1ba2511f7068997654f47706e29dce1369bb25674c817f1ef4f6733315692aaefecae95ea16ed147ee8bdf714e351fc1e521062b147d95c5189b82cad661de9b13f6f9522a5807d5d9a5ea9ad2bd1842ce4e5346cd688348c8103b717d6efaca5e2e3e3850090cddb9bc4be276a8960ea463ee3d2ea32b9bcd02a09a919d034d694fdc7b600552ce51509567386511b6d5fdfc41f00ab3be21c09136bac7c99f37d37b581f5f8e214091b7de41d58e69df869beb8f5e49e4338415e071b3ba18811e2ddf1230ec86e695cd427367b69ccf3b6d201fb8a0cc3fd35936013d45a4ccc559cc726c7d582e6b4a4f150350dfe286e54e9501bd08df53d01bbc72ea07316fd5bae0580d485b197968e19b88527d76d7e4c286cfc232764bc1db8a617f53ea2e396472a835cd96236088bd3f5d532f3ee4fc0ccb873a663b70e0639c43a5d22952532edd4ef6d495228bc6d908d60255b644cf20b015adf093f711e03b9341274ecfa0cfef830aa96ae62080ca7fa0840898609c3613e54eff67434daf86aa84526182cffba39ce59bcbaa7ac9d4f9827a7afcff55a939104095371f41c226e850bcd861673c45de8cd2a430602a701457b3ba408ae549cdb12b3e2f07c246d35ae42bf0b5de55bf0ea61996019c1ebe82645c96333e1a7b03c6158441da4936f68b4ed590c329cbb796e90c9eca0cf20a4b72407a5b0b60c15ff69ae3eda88987cd3679c5f1ee2e705695b9eb2ab9f44efeeda2912a3e66f842fa365e081cbf9f1aedbf31957cbbb5ea71063309fde2bf5391a97533f80f705350120604b645ff3bf1ef585d3594fcced329a099cb0f246e59a390c96cd4f1deb29a1192eaccd014da1ca1d70b8111de517e0180c948a0208f829783ee1b9a02008b6f8ac9a59391c0479ffceb305b21aba649e5f03521770298ae7547edf26b4ced2c0e704534d9d99fc576bb5b02ad7b9a4c6e7b39dd216c55aba7ebf3154a6c2a1c320fea53d3ff7c6f45b7961b1dcee8dc9eea29c8ca8d43ca8a67088638cb4fafb2c9b9fca362a8c8c39209605c4a19e189848a5b7a4bc3721883d644a7b74e37fcc1ec85d0fb8c6afaf724688886756698f2a31b6ea779b2bfee5693e0d7fc43534e234e8feee28fb8a34e7705fad641af3d37e610a3d669b6a0d46b79ff9feb20ebbee97023db15c80bc9459478f354979695afeff38e1cbc0d0a4e9ba3cbecfde5d51fb8e30905aff316b91d457742d2d6a8f87500a822071891edd6b691c5f96f3c24aacc961f16bf399d0bce8d3c2afcca7ef6c314b9a590074e1e7a8a7225cd9f8cb88393abebdc2971f5a80456768100b816baa81e428a25baa633262bc4b9575ecfd723a8feaf8d3fbca97863c3fd293d631436e5f5fc4fd3abc91f80495dc098cfa5976cfc4e61a022d83459120be8f986b03e8664988c6794d9b728d57038fde49855fa9e70a166a8e15e13802dfc9011ff4cf1fe1cb278e11467069b9c0c94c1c1c70badc68e6d54ca6324f4ca4a1568ecfbe9db8ca85a8e665003d3520d91392bb4bb37e47766b2e48f9b522ca62bcd8116001724a646c03f28a722dc47d82838314bb60b3772c86dcc91b223aedc6572ca5e14197d7a649d2a127428c1a07c163f19b03f690c9bb4c8496286d492d724c2b0085888a89ddae18e3fc7f5469b702433af7a3930c836bece2a015c5c3af45bff95856e93a505c65cee8b38a144d656b914d553044b2d571390897b0f0a4f316d9621122f4d4840d87cba3cd9b35fd8ef1de648a6b610740da7bead9176ad27cff8b8939e37dc3122cbd4250f2bb8d818a2d911ee8bdc00f337add006711e611e8592765b758611fff58c404a843612e1834bb76acf49f82a80c3c4173a9b1895ef0c9823f98c5569f3ca43a2c0e12eb5cd54bc450904c8a733051f0dda92a537acf11d1ec7af5f28972dc88995441c337ba8f8394c6e66b39dbc4b17840ca6f0c009308f0fb068169cbb9823d86799e2e1530a81aaa3ad158da95ccc598eb8def6d04ea55b1b536eb061b88615f932bdc98e47e85914b267c0c91a7963bf1e72ac2e60a21f063922cff6bdb9ed6f2033ff69db8255a759240136017243d0bdaa192d5b54dcde09a3b7816f7cce8c096ad840da7f54b076b9f0be762a6a3f69d25b77f6c6d4b8baf401f2628bdc7c4788fd72b498b3d2b14a623bcdd41c7a819a74010ffbc59ae8a561e3e90bee225dd55e36c201de957a3bf3d82cd39d2ef944f57584ce312e451e53ccfad2e0594a2d3244e87f2d0d02d7b8e4dd3803f890f7a147cc5d6d36f2fcd368bdadd05e39d30c61c6fafbc337d9e4bdbe491b14e0c37d81233c4c6bd1ccc2dbcea3b61cde544092dfbc45780eaeb370c5b166a779c41e682487bfbd4c835cda1c9e07b7e7521648a1c11a272a5aa1507c005412f1ffe678c39a777e2b89f30acb61087fb206ede7172e84a4a2ecb807dec2cdc839301985799b34fb62edb89d204af8299499d0b134224af6453a705fb5008adc51157ed7958f0bdb809d567140b65d912ab2c91b969fe2e62163a5ae46534de6b2736d6625f4c0d02f9ab25514576850c5992f3e098a36ec01a2af3bab17808f7b25da793324b00e78f2dd7a955185d93d3e2a91b8ed78d08cfa78c3a5f5122fb67369a8a7917277082838aefdcb6a978f37f297debff88c29eaf1d4efc9956cf6dfe35cb93d80c390e6fd9d26146cf0119a86b8151a269f741e74b2f2e149948e4989a3d7454fc035c3cf407a5d432c1cf0b216a32f7269e8e64df0708f0830d4e0ba6d999e64af80f0a4203e21e5e0a3a33b722b5861b6c0c5b6e8a5a12e6a92e9e61de3f930dfc14c0279cba9e8e7bbfb0fa9667093d82691b2dd12d39833ea7973747bf1e319120b11d29ab2dff6443648870d7a96231570096a9ef44f30e03e646990b673c09c6625ed97a83b2b3c9bc0477533d0b28e2be079e077ed321681a67cad5263520c02d1543c84e66f4e1876336aacf142ba142bd938da131694615920f6cae8f7032829f0cfa245cddfa838142e52335ad815ecca5c3c97e8494bf4cfb914e7826b57c77d4ba8efa0537907d819b6383244e4a8659da1c04d5a87d8fa03373ea1ac894c5f4a12270eb702e9a866fbc1ae101841a6d60cd69b6173eed235eadbf10dabeda2c5aa477a8ec4dd3d8b3d3442cda6494f915bf678a6158562f09e11c7ed63b87622ccca89ba74ec0517e7e5e4d730689fb8b95f1b31126f5ca345b14c6275e360be2a107e65b776e736f92d528039585bdd3fe46d7e36d9c50ff40ae4ce4972055499c226b56be4e54519980e5a5e6208d4e4de3b95a85a269483c8656ca45602f3bdb67edcac13f60b8c34bd612429ac40b7b076a04cdb34b03c496a5d119675d64ed37771a251947c4c24a0c78bec2305ffe0f333f91750442d6e04c88f32b70c6efa4c47490f01022485c51b2f081c43ded41e20878ac82588390e76c09627f09bf102f25d9d680f8863f4cda51d408cc155b3d2a32ce6f5fd2777463799ef666ebcd593a47ef9f0146119cc4df2f76d8c22c1a0d567273cb0192e6777af466bf78a058ac79445120ddddc1250d0485f65b6402027a009f4e5edfdf94b42046b632c8141dc4a3357cac309137e75c4029bf36ec6ffcb0a1118a47b431647024bd1306eb1d3b3039a46f3df8e3be0064580d256b0c5397e61dead116b264451aa1e2b8af090e06c784022bbf873833958d4e9f06f87608261d164fed93d628bc844a2f10a6f143918315e2dddcbf9afb59c3ca4a045a1139f1083a357642ff43f73c47bca9b57b46f3916b06b2ba0f43f7fdac66e24f3c71ae3998fbad9483f505b924f93e401e77aac71280c762320e03ed3f70398cb0ba27fe80f2878f50034a90a1a9a00cdcb0561ec9e97bb6aa00063b1aedde3eb4afe657229343f1934a8eab7bc79bab56b5ec4781e9f3ee8a56e938a0bfec82fa8a2fa01398515011449ff1de88d84902016fcf913847b05613204b638172c235da1f2e391c5c66ed9cf46f7d60fa17e9f84e49d1f8309f24fd98e1cccd42eaddd3790fac672d50a5000d9880834605384a18bd2d1b2bc7028eae86d0a1d9a41de4b624d0b42d09e24bd71c955fb5668d2709eda78b60c926db5d6a4563bc0cffda9eaa8b75601d3e2709371185ac015dbd7c5e8dbee1ab0c94ab11575c302c5ee4a2f32f544b220bfb11eabf680cf7d713613645659c1af8633777f791931c60dd5bdb3353f9a1a7900b771f21ca11febfb731d2e0aca32923cf6ae7367bb2439255060242c2393d666c0840d9b2db4a9a76fcb8042532e4b251a96e2472d24392b35d542f2fab4305dbbea035425edfef450c5eb5c0b5d04bec01cec6467be08136ef5130f0e08e16d6c3c8268717b6e55df4ddaa585b33d755ab2096a1b9552c62e12489da83baf2690692f8465988fb322d3fa907d47f14155939bc3fadcac4f1635406c1cad84c6c18e2117815bb8561e7c4c29becb21e1fc3c3b823d6468434fc5102799dd84d036b9b967e3e776297cb9cb7514020ada58bf65bda358723f817aaca5ce0e1191667557263c299858c2d9c4bb9eaa0844ecdf38a9d3952528c812b409b90cd789d292cffad6dd18de7d56b5bee51e56abeb7b77dded63ba22f88aea64cc56e70082680b75ad64c03ece9740ffc184871f5ab229eaecc732559358c3bc67f37f7f0ddf4c263e4854e2b8523bf75af6cc3d80137a2690eda47ba259170c26de29c070b423681f4a295fc8ec0ebea1260806c97fbbbc3d1828423bb6993917833e97795072179f42b20e2c232cf93772106a4ae4c863daae5d039ecd8822acb51e193996bf78999fb9dfb297c1276eb200933a0e8f9bcc49946a2343c95e2167b54754861b6745e643d97c864596a3e92e1b6641afc81f5247537efd8da3401558ae8814fdf8c6b4dc0bb8eced79228cbe7539d94a4384fe33680c1739c720730fa4d518b779c6fcbaf1bdaf793ad2c2942a5c915694d650728672e6cc9ea31300218a1629209938da3942fb227fef7ad8e8813f69b6a44ea3e1d2742b1c8ab6b5f79d803dd7fa4c8c37b53b3f4389e2af40d5673730aff9ceb27d1cf96408ef38b40c40c7dd54bcab3adbbe4ee7e94821b742e7af38bdfcbaaa18dac17b281b54ba2f30d3d602decab88bff96e16470668554ed9ee1ff93f738a10b8d62392985cd8cf8123afef429447b97e00aa54a7c1247e01535d697acf7e7f005e9533afeb8d57025bc4bcc90870f7d309d6073be61be37fabf2b2043a8b0a911f9b15f4fab17bce8468359c59bad8548d4b7dc93150134fb165f4d687497018649820d81ec75d4e17eb80cd9b02ad9740da2c1a8f1e4c88f1980778a7ce39c8cb1185800454840aa3adc17ce6142296af35516dde0f663fd067e3b089593b4fcbc39181fdeda41e1291fb176f3c0491f853313e47fc47abeb2e088abc4fc88ea250f03980a8d64f982e37e3c10d75ed289e49a65181c9b7100bd88668359ea33b6ca5e755d1d610723e965c9ae0537f3f65642ad515b3e712dda5027c334de7884d1d0a609320da51a38b9005209945bf6b0e73327eb19800cc365073de65e4ae700aba796fb5bcef62e49616b90740c598e514de1d2ad28667584b738dcc492dad94dde2bd94e2abc244b1b5c8d7f0d91e3b69c7ce8a207bf1deb2f2cb7cd74564d333c6685a38da5b9f9484292f543be9dbedb232d5f3b25cfa48dcae1dbba17148c3b3d0655c3a53a7ddcad647800937d184006b8a7b1f82b5b5c265baf244bd7802e8cce9589920294bc0eb049556e96674ae6d0ff3e343ade6ed9f6621d1e7438b6a111175d25059ad4bb554daeaebb0b99f23dc1cf6d13e4cd99c3669fb72905459e16660bc588fd8b888efb284adc39f8366ccf06849e6c9d16f7269c63ecd1dbeb16ca7125b62781ab7b1716e037f650d093e3bb129ba8d4caf70b6660fc955e4ddd6fa47cb6ca3bad17feb40974a439b2838876fa2bd6bbacd51315b654ce065b0f044deb0f25aebf2b56988034558183faf82b13eb9de1dae5b33177554ec85199888fd9e2eab8a15983fd63580949b823e1ca0c78ee58b16647e638795ce65105c14a035258dcb0629d7395fee5e802fff3157456ad6a7a297005a701986fd04ac8e27d3c70704be3534871519217e939830bb766c826e006db9acde2e4ed3cba6a8c3a1656a978c941828d79635ab47543d6126c973d59c160b50ffe6f08e170a9a628d3d312d1f67083e6540c05008853f149588a08358f3fa577350d9d18eb4d9a32b90ec4e4ea5444c6e3fba546ce2389ae472a59a331421ba42942b29e7029661e21606c9c8e5038dea645b3719a1d239dc200904060b031b2d1fd3ca729943861268456c39b9f06687685d0bbc291128808dc78a61c70463c75fadb05dcbdb7d750c292df3facc2c96c2b9a241a7b1165d9e6f186ccd1bb0289a76c23c5831fd212a0d547b66ee0bd04ef6c09edc379c843e49cc65aebb5b211f36cc7050496d28c9120774b7a92319acfc29c65b2b3a1098dfdace04eccbf18450a81bbbec7d6eaf18dd104fe4f0a1ddcfa7393c48100eb81b3ba78a6e9df15557dd92f600363fe312ef08b5cfe5d93db1588172fde6a502aa9c3eeab9f970ccdc6dea174587047a96c522fa2849c01e94ae1e300f8c9763f099ea040f42673b6e0d7e7d2a56e304fba74b870ecfdc6f32e8186d45ef8e2f1324190b72b6aed3143889cc5d9a762f466a1fd978284423c9137437437aec197f22457a9e97d9d042587532e8673a253bc7c28d5b675be20df66cb5efb2e0f6fbac75071cf5876288569b15ca68bca32fd56bb14da72125955731a11935064c2c125e903182dfa8a2365dd7c18c1b8fff0d3875b678a001e771c7509ac207f32cd6472ae16a7b3dbae900dde8cc98f1f41ea77870a071ef459e59bcf936c833cbc4e604678cd3f58dd85bcdd5b1bfebe05f40d515d5753bf43877ac7c849c093dbed84b05ea84356da909deaa4f5cb130e9b8aca1fd3d7ef330b398ffcc8558c9b3c53e5629e7782f275118d92c6dbe18d68d2736004e611407f4154ed738c1f2e4e9d743a0ea04fb25a3446b8eda7d0e0897f4153d7aef9667661c11222237992a890265746e930f60c91b5c25b361111de5bd7fd349eaa53029a6ca9118e89f1dd78e7defd5769e0ceb0c6f5a3f832983bb2b47fba3f0ac6203be2580a4b2ad021d5f10c240800e3526578e0b6b74f047e64751dddee9219701618e228266ed4b6c8a637b9522afab53a59748806d6a288bd2a49176794b68566516e53dbaa801aaaee8d31f2755405e26183f19cd9659544ca00fd7323ea1e3df8b3e566dee8f2e0dbcaef6789805422805d538b21a606a515843ffe7c285f05bc2d42d5cb5afbb1f50bfd3dcfa71f267688cb9d761cd3e1c5c274d1ebc119880e3ec9f06c606ddf7d5ceab3454875cea019f9db699d784af0a2642c26eb922586d1bee09a7853771801f4fdad4c4a0b8bca237ec4ebfe9b4c52294089a9b224e2eadd6b7df8b9211ac9e2faff9cafc9178a6b62ccd67d3bdf28997b63b6229e6526a123f6c3cf988417be28e1bca869b04375d631b52d0c6d550f83326c2dee511c7fa0a8bf3e49568e062474c98f28021ff6be303529ce94beff27da5ec6f0735506722a66aa4624149d380e96988b8b4d870633423dc7a050a2489291f735cf7d52413a62f7f344fb7d07c0e03643dd6c59ddcfdbeb9e1a318acad6d8bf2f8fd0983d4ff3bc86eb0bfe6cb8701af93c783fa0a9d0ac5cb2abf4dd2f5ad3bbd852e06c92931191ddf6474d2766e3dfe1f3e05e96e071948d6d780a7dd5b2fe9b3488bfca882de1b71a48413d44064256014c3eb2384f5ded00a6223e2f1c9dae3c812416f2bb21de4c0c218fdeecfa3da5ac562c44b9676b8c55d890e00a5a2e63978b6eb3417e1321ea58439c6476ed008f24260fd846ee9cdf18eebc363b3604c1dbe0dc7dff38a989e0cb9c3124693d4992dc6950c0a858d48fb3b4e068eb0a91e30f0a206310e7d5f19427b506c79dad73523ba50e8740f9a184f9d1855147f72e86778784b0d46448f272b084781d2c7edaab2688b97d3d5545692f159d368198203d75475c33da299654abcf3390c09884701f67e7c43cb3a63476a3fc428be2304e5caa7a8e5d43e1dafa3b1c16f99cfc0c96489538c34b716175bf14e0c0b50d51970ffff7400f4f8c8406112298579a3d1a37a410afcb832ded171bd63c9421038d6b80030a066c7cbe77a6229b751dc3cd45f6f82b88b916c9d0073b1af341c3bdf2a6cbf94c0f77ce9d0ad2247ad5d45ad7817ad0d62b44590e2668b053e368663620858c73f5c1ea731a1bc5a6aff4071a4e9a32d95879786a60451c08932414abd62850ab7d4fcbc19e8577f08820d30e4a7f675dd97092d7dcbb27de042907340a7551c74dc8946c801395073d4e3805d775b9b43a2c8023dc0f0a363dea6f8cba06e8b9a7181d570f7a1dd75e7269dcd00930d9dbacce95834e7a4477fa4a3ff5197d00c4fcdac039308760c3ec130005603ff20b51f00edf4b36fa952b341647156154d81c28ae30ba00167959be4713814209542b8e22a6910f8ad1482aedff3fc1cbac48514631e4b4729a0154f8349c7d7dfe1cc17fb9ef8f14c5449e09f17229c9eb4ebccd14b6455ea481d1c1d2edb075fba1bbb4edb9dbf99756cb42491bdc21fe711795d0a4e70232097c4d84c694738068cf483926559a4bf77e5696ea2e86129a79db37b9c5a920eebb3debcea38197e7330ac502bba420fc5f26d2ae4d84939cdb0820d381c8c2b28f7ca128574d3e270009d9ce661e2df86e45dc9d52ed9cf30e50166bccd12eb16a9aba0e811640da62c73d992ff4b7424b5bfa83809e0d2d0966d7c1403587ab691fd8aa1cf87a70c93b1b443152a66479b9804510a68665b23dacd0002e61bace048916741fa5361d71753ad793172c2eb6133910ee1abfb48263c76a11741ac77beb64e8c104ec70bfe6ac802391a206dae63676b5d9a3cb3adc7ef92d0afd47e9c31a11ad2939f2f5bacbd9c43c4ad676f0b077b0a5e3bf5e0493312d36dafdafc7850ba2d4d7317427e6db3344d652a7373fbd00c5228b24a3ff8df720bf5b880ac5da97515d858dfbed9d9c3bbc317f842eb047f2e76c33c30a5c7c97a2128e9dc9eeaf70bd74123f35540e584b685bc534d38a89fb31b3fb2a59a7b042b32b66a025af19ae5789f8095d41ae93f1f3ce4e97a330355d7e48f9de77e80f8191e35e825d3c9d06dc974d888da431b2153f041160d44197faae4c845ec2f33b43a1c02cc1666b6ec5fdb49130273ba1a55e7b111960a58493f02d71cac45aac50fb2a1853996132554f92575b3f6492f66b7c04bb55fe77739b08910d170c0456073fded0540ed4adfad2ef6ed15118558dd29c391f1683c33068aaf3cbec6870c83dc4d8f270c51b7a5101094c40290a5f64670dcb93aae5e6a0f0d313dbfce9b781aff3f289e08828d7261def598521561a674d53434337fbd9ef1c73064c7624e9cc95f6ec8e0b905dfb5836b056c33d383ea4f79c127adebeae9dad1f05b8619c4f6c3f82b58942227357224e0dca3c7fa8ddba896a76eab97e62e91dacbe99c6e25378891f03c3a50a69be5ba96d296285feeef858558ff2a4300de0461623c754ba10d5edce3eb09bacd74c6ce96f4ea17231e1dcc4910faac1e5de4ad90276d489ff184d7ff56531e82d4992ddf03a8a6467684de68e0396284dd4dfcb04479b7ce0e9a946ef2e92225a361dbd1ae16ec772a44de1581c45791ec07ad2d0bd864d72bb4697ac5fe4e284bf5a32d3403f7fd9ff3d84a5911e2dc9899b68c385c88f2ba1a3570da699c9df887b819ec526268c2f907dfb357c455f9c7bb488258bcf41c0d0b61f93074ffdc70deb4dfac97a164a55e1fde18f5688ce5c8057f5484d779a2f27c2a216dfa1bf08c82ece8b7721bd8b13e89c0295221d05402f9a79ea3b91fa25fa2318f9f2b9aa93da87e3d3116f1bef98d0497092548937d31bce5f843d085b40bba03a9668efa1d4336b849ebcad1f3aded7e7efbca384319664fc5b8c9c640d3acaa4923fa5eaeeb7469fccbc61335206c5141fb11a81a285a89e93c184a55700a7c5a34220c2aca9e91c9a9965f8fefa71b6a2eee3ba4d68744dd6e366af01145efba0f49cc110b96133cfc18a5bf2defd7df90676c37754940b6a09ed3d2f1225de82f397f06af84dbc33d079eab505022df259158a9d984ffe696b6fd0ae5d85aab1d41da8949514c1decefe4f2101e6fcaf366ed47b3f4b36d384a067236fc84c9cebf5565bbf4d42888c6cdbbe443812ac60e9419bb5851cfb047c24a07c36e2820a2315949526ab55ae6b11c34877b0451e35af6f8ce01ec90eec046d166b98926daaa42c4cbe0b399f764a13b68c1275a456d266e2097117b2c979c5233f0f5d6225334e2b1d9ce9d093fd04b224faf05f91795ec3a05a9d389fafc31d109d5e445c8eb0bf16d8fbff38394a913d77ce7ba80e7f14c27c7b500f2e908e9229775d629d0eb9103f422ce793ebe7978a284abec1d06a9b60e36cbb0339f87dd64fe0b01b7a14780be02068a84d84feb680f7b3ddb4446650caf393b4a930b7c1840c0d313bb4c3db6b8be07e86be9082b6dd506bce49f319103c34baa58bce174bfdea1f6340a306845428ee6e4e529d2ade3b05d1bd03184c99e2f194eae492ecaf27bef43839b3c865dd68ea9e9910040ebda6df0dda09a4b8ab166fbfd8f7248a6a699b34b7f20facb97620272c158b3a00350b34d90d34650555c15a02cb2362c1c099ae73b142fd600335fa1f4f503ea48ec04192016a617728793567435316e8030a4549beb3743da3afa9ce739af88e144c5de38aca2d8d63fa84df9577efe4c0957a562316289ed5a40251863737645050273091325189a6775a8335802405f9190971fb85e2f47f19ba825f3901d1d8f828add4f84732b31ed877528e09d5a4ee8624ce349c1e869448d350a9577bd8dcb7f39b141eb9bc267b9305e5fd145a741af269a7f2a3f4affe74dca0dfa908ced15d49b3ae9e4838539b122d64da8a3f5833fba5ea96b81b7ec65fdef39107ff6340f6f532564a13a2f3093e0a0683f325950dcf344592f69f9858f2e740e91ce4efa6b5b607b341f8e445e73dcea4ed7fbe583e47db989ad78e45e9310b7e455e27e3b315b156541a0f12474ff163d6f7de85267db92a304d271172fafbe6690ef423b0e38b4cd7e795c374f60d6ea42f7e147c595072593050e635f5edb9effb171ae169e1011447d557bc4344cf7487f8255fe3f307f9349ad28cd40ea56c8e87b2286670115bdfe10ef150b22b151cef4240a1eafa5c1b65641047aaa77f3ab5b7c33db8615176b6822b96d099c3487cc769c772fa511091f3dfc3326320c51024570fdbfa93c49aaf46fbd0926107880df256dccf5ba9005d01cb9b0d4db0345bf8635a4dceaf6f06a2a706c70912b017b44cfc43e34e5ed16c271aa6ebea1b7548fff67f39e6d26ad19bcc1929eb9b1a56f1cadee39d43dba85f1082d2452b2b12ce3c127c58ccd21839d81c29a3870bd1469deb58b8eaa854a97cf4210c4028fff825b43d5192324660b0aec0ca67f99e273e49fe4d5d6e4517c80711864992014c1dc27f0bd9bfd4e44f69e3fbcbd43871cead61d49f377f53ef75a7c1f9abdb8a7356d1ed1442ca15f0061c19c4489a21b30ec3bdf5cbc1564b3cc02298f408d37f0888ee1614b2e015bce8e3959fc45252c87e97b61790320d67501a64bd7ff514244f91f9a01be32c1eaf2303c36247d2d44245a475d3d3b73f37d7ab2681c5ab01b463944f86046b3e92c203579efbf56789852081689c60d99007cf50b7cce149d99f76b4caa3cd93dc52017abc7ccac5f8a3efa686464f3a3d9b1ef3905b22ef980d86c51d521ea455aaed0c9c857a539b2868b47c633966d4f137a5d59dd57925c3dd5d41a72d2ad4ccab1b0ceff1e30f4fe8663af14f967dc2d6ca3bd728825264fd203ba3d7cb92a2d31f409fec52685ddaacd7f850f5266448601917c6f016b5e2c16f4c440ee87dc2d460497bc1e17de4260c0e8c3b5b7284bc3aa374ad792ea42ef8fc8820a21512c576e1dd46b3d83563548a686530f5fbdbefa746d36e2b2e16abfe8c9daf13b9192f0aa17ad88f2fc8a2ebc4dc1b438f6623d1064be090b8184c4341104a51f908ecef1e263b57147ece6fcd74b3b28dcbc7cb12ae18992d041a5a5ffae8f96cbde4ee5bce4f684f0ae1e70f8de4d71d62bf66a6db995fa0e476ebe48c24daea37bfb65ca2e7613e659a8eca05d8704ab3016bba4847221c9d7f6a71b9143188d352234dfaf41ed627ecdcb8d20cdf6c07d30dda92fcd6b9d11402fe09ce8d3581c8b60cccb9de928d7a3a3ae7af157bfbc5648ff2784412f95fbc3d2d65033c564ff5e12f5537915c0fda2ea8406361b682f4ed0ff0bc1e4aa179bc6226f9a6c482a2ba13f6ecb0fa25815bd9dcc4fc21e9ddcba5a7679330806d587fa198a00aaf972dbdc91e08d4b2a4ce65f12ac3546d2d2c3b517ef7941e8c4c41da4b395277f34eb94f89c1c32b958f6c02ffb4f95bf456c17192de4c5d2a39e330d01750d8b25eb0c4c28bfa2c8d9b7bcc3ff56993d2ef71fef5fcb18d7891fe4ba7bb6e722d5f74d74f192d369fc59172c9f98f79565c419a8862538c0371737194d0b328cd05105f379ceadbd7ec348dcb129054ffca393e7ae91abd9f30ce1c53f31629b350b672e642c4ab65a13a9ded74ae1a96c17cf3685bad05fb0abe3cb05314347514bd3d108ef43d6bba3cfeede0ebad779471c6169ef5a33887fa8523e945516186dc792762a10835e7c4866eb47ca6da30ac459aacd1b456b7560c0038ee3d14f90a02e9a6adb6aab9374b7c6078c8651ba1d7858d0e084c6cec962205689569b3b865a38cf875136fb311cc25d54dc167d319841c90f41d29a9f6c9806889277c914a754f2fe458a7c1d24b4bd11d87f572e50b8a2553b7b98d9856ec91e15d38a066f7b3c2484e9b37d4b5fdd0ac87a5bb07f1ef0fa6a336278e5045b92b22c7e60726154473da07328133bf249bd911c4cb18fbb8b91e46a8043cb12475e7229774d4f06a50a53f16a4b579dea48bc921dc7c7b8e1e62946e2e1f07ef6e7fb46c0ec7a6b1ad2eba4cf78c39382598879acf13a998d74f882beac8879adbbbb7c1e2c81e4744c22c52978b907b8f01103518e0d4b0ef7dee03152836c97d6129aed524a5b20d26de9d168c87afdb27a8585b1114edbba26c8d477de51eca0c4c616d7ce3997d067ee622b8510d153d142f48e7b8ad23363b2393a6fbbed1da2e1803877362a5f6651b5e794b0baff57ee0a37ea75a04db0b6f64b2102f6bd8619eaed424b6d960941853b64193a1df14605cae9109a0da24d81b6626b2dc682817bfd309dae68bdfb35c47ea0aefc5bd28a1612157cff4460a12ccb90cafba7f120175549626059966a948a68177a62139221fa4977cc184ce72fb71df6812f305f830f33d336c48a71e169dd8dfa2fbcbb575a97a4be66253d559f2c2364a44ccb837bb77c3c502cbafee98e8c360c5b3c0333b6b1af7b67295804a307b997200802fcf3aa602b74b63f2817724fb863c1e6066563e28c0628127e781eb2e6b8b5c0ec6fcb9fbaadaae5fbc32b9e74dcb02a9e37721ef1193c6b40b66918a1da03d2e45dfc78dcae9f9a527717374e130affe204f3091fe9e426786221f1902ff888d3a451c8577ccef76245c89a0eb04c6321e9eaf1ad7c4837d5394cd88b4bc0ef394de84fabdee320152457580fa667a46e88c534d6cf6ae8f908803e3bd66f4f15d0d952dfa31e4ff1d422e0e7514e68a8f48da77c95be535b6065e73464aacd66c720e84a78efdaa744a33a1fe06fe4e182140907bfd0c35c36834ce44f8f53d62a949327d5ec25a6d7da6f69ff58165e5385f9d90d00b10613cfd056610a66450396ac623763763605c44a89f530862f5a66dfc132a1c7905d3ebca65136375957bc2a1044bbb69f0c207a3f8ba8ddf411aed01a79651721c21ed547aa848d6f070158ee86d04f3170ad95b985fc85d24df6336aa5ede6823a8b852984985edf9e77e3ddfd22dead949485a00bfa47e42a24019c0ab37841acf299bce211409bc162c4c6f27d38c4be321db21d05b27465261d3b216a228de752b221f42af9f31c38d52e9164334f6fdf98bebc9bcd55b62cbb66a53fae0816248d03ecf8855a23df22c1ac4864cf19d01ead2fde90720c75016a4d2cecf3374e0138b1dd84bea89073860740ff08ff6b85143505b480fdb7c57b10466ae590219ca53fd837e76d073030d2ee9e3da6e7d0ac313afa3ff7bea0db188c1b570fe66aad0d97332186223be886663eeb1974dded13912d6445a807df59345cb484e4e2d6a140f97fc13924c05e6760f985540eb6cf0bf03adc1e737659af015fb613b540b0216f74576acde4ce74fbc340f48cd59ac7c6ddd7664b71ea3b384a98c4ae437d1f3c0f6607fe841210d4844c3cc3aff66fb67a02cb2645dd26c8c279dbe2dc228f7e55aa0836ec42d0a36bf48ad824eba51843456215f59a449107e5260a3cb7bc81a34ef099ac7cf77585331b3beecb6c18e6cdfc4c28c01a124441afcf950059407fe55e42d1790a8baff857dae3c0d854397ee231e0da330279234d728c86f35950dbbb8e0e2c8314244ec691514e34d0c8f2b77a98e8c8fa4e762df319828ac4f1d9c298140da2e3d6a5d06705b967eed9288530d7ab39ee2453ee771c8e7ed76b481da425491c57e5a2b94607d7d6a59632f5cc732f361657a429f0078f68f1e69fad9cfa6c27c88551ec756fb8c4ecd2af8b705d15860aa41404f387e59c34a26268f053130e7feaa1c8a4e94a22134bfd89e068e29524944850162205bc309808c3fb4e0174987ea5b07b4823f691acb45dfb89cf1f9bdcfc5b810b47225ca83b2adf8c3792c4252c1431fbbc31600c14645f603d03cc5a127ab310c96522274c1f01b8ac4bcdfa61521d14ddd9f5eba4562ddd51c7a969191f119c62ceb4be0b8b6c795ca2f07df462a8f34a0755198cbe73e3a7a443c00f270b63143911218cac510cc216e7356c76772bbeeff87f7796fb1dc9415e79914167c010299d6b52b96b5ed276b858c04d987cf4cf54f725fda52654741a2f7c373756a7aafd5e0c2a20010d1d6530c95695e94234b15a28dddbb546206cf3a24e6cca8cafa4a92de32b0c0777dddda63da65ec380ccec0b1ffc8192847185065025a9690af20f9753e45ecbbc53628a7f02f8cdc2528fbef6f14a4e50f90003f3f9a6c52870eec5c7c49bb0ba4d671797d825cef69686eb209a288c9345bce7d8259fb233ba65116e1673cb90299e1358e513cf711cdaf35be11de46246d59d0dea3318a764f76f7029c0b29e3ad3761ee319d15ee375917a9f2eff792554638fa0e156713462566dabdc5afd2db1331d6ce9d99e699ded83507875b89f6f4ed1570039380e1cda18a0eae5760ffdb562d03a4f4b771fbf4328b699197522531380eb8f4b0bdf34b757c184faa439206a52d1e74a77a2b95098048fa6a2d870488ed9d50b312e460861ae84ab4b2facace7faa8dd6e60d83001106588e16ab9275521147e7a494a02bd3609d490e27491bce6f6f94233da224089eface8bdc95e8c5752bfb22684b1ea9f3cc902a42fb880e7095d359f294e6a1cd3ed1cb0b701235cd664152e564a610719ab6779a2488a9b0cbea66500916425d907f8187cd056d4a536e50377e483d13416e36617389ebe928f72894ce6d894ab8a64ec325ca1ee89d48ef002e9d04e47e4653663fa806c8513047a4e3b19236f439889b3bcb4f423dc6646b730d2a2037bbeb8c5f14f483a13cc0469cf08b46fbb55e388878915c9fce4c004499485252cea49ae481c4207beaffe938fc478e73150a9794f2d3db1993355733f0f9e43624d17a5fc10dc65c0192f5e92e05b5e87f3cebb68f1e5fb2b8b1d3bd8659964b7949851657411d58269854f70336f2202710cd5001e15d2efb29f5865c1b30705f70fc13a73be7b7c66d2e2405f7ed5baf97a07bb1af90f50d6fe1e0b0f17d7d523de00f4cb7528b9fae2433cc4b6501ffa13af0d84501330dd87174244f350e49f1202367829323dd13628f27ea5feb0acd1b536d9c7df960c92efa917742c826c1c3fb6002e98a64c9458acd0e856c8d86d80f4a1808f315bbd5c05f9fed1592033433628ebf7a1a30d8c3e4d4664745bd4bf1436436594e283bc7ee23c946c2141f30157a546706e7ac3f401fde4a96e46a824950ba614b5b434a98b69009c5550bc566c53400fbf3b0356cbc0d74e7736c6245bcec68c661522dba5d69abf77e7612d71f25ebfd445cd9892fb3532d0d3477ea327b1c3881c32ac029a87170d4bbc6d26c363df0384c772cd499e6db2d72fea74415ec80023e040da1db69b7c82361de6e0d9f7de76765ee951fac46eaec04592fae7a30c21b4644108b022bef8af2d1a93ba8e295f2220d81fe2e87661ddf8cb6d8b006fff9951f1c658f9b520570f94698115eff392930a4de38162455b8f8d16053570067db20b984b34e1201a359a847fee0dfd8c2e45e545bbd8c8e4697abb8bb55e4411ff3c8234db214566efb59c03904cc46a327933c17ce0ca8c70ceb1f310f440b56f81a2e502ddbfeafbe1978ac29738dd23d8012cba44d587268f244febb769705518a1589e2d34b5b1d455d2a46b7a4b3cd91e1eed936c6cb8fe1b7bc58b59cc9d5788dc3975350c49b0439f2e9276d597b5215b1af4169f035905ba53302a67b3c1d10fc99497a6b852d114cc65fac70bdeb73d4f5df5b710b49b0c131555cdb0cf9aebfa4d6ac4ae70d632329dbe16974b6a76cea1b5074d4b737cda7df0a66e410930c55402c5dcf8e3b976bba14890a7f3dc0b94d88b9bad74463d6c753a8c7e866bf45097d300fc381b15d0700c71e9da140fb32eb1425f54df5fc3e1dc7d777c6f37b8b6ceb968fe92d3c4e9a95637145f0f3d6b091926e0bf3f684d200f54d7799ab7e6c086433bbc8ca6ea2f3ac8de96a1af227ec9f5f8371f3b918539f5cd46060deb80904e9959a8a5bfb3e71a5441727afa7e2d39d0d70837e48e5d23390ad8d91e2ebb6312627820aea6300395abd4cd7118a03e2231cab52b35d3eb89271c201ba825e209228af017aabba72783443fb6bf43b2d4fe7b39d7769993e171d8897d0ea772943c03c3ed0fcf80f712caf5260c0f85207a75a1e9c05e9207dbceea3d2a8b22e0484d9f8e525401db658298748b2cd0694e0b92c0036f309a32695796069bbb2705b469d3faaa51a7a04ca3f791de27ce70a926c522ff7c36ecfdea5f78147ef96a86f6a945182a2af3ca0ec730de1d3f66cd948efa1700ec7fa0f0f5ba518cf61376e35252734b29f4bb27a089b1c49870358d72aec0099546130137b967c80c1ca48207eae345818648018b69716ddfe7b21080b61d99e8b9b9c8a34c8c2e19757cb3e9c190ad4004349ebdac00604c4f266d57863808045be92c54b3b8f65b3b5f00815390649dbebcc0e52b2a7364ef4de0b528a0a9277ab84df8173aff19318007ddac55ee53a03d1125dfad7af96e78ab61fc61eb4e3942440e95dfd671e53092c6302f878feb97f2438470a59b9068db3b66f516b5fa45a47292c419f0115b5c8809161a05759d20768028af1a72aeea0fa07a8ee5015b42495115aaa58c66c310b2ed4e5ff35e6cf19004da2cd9ba2d2c9cffb65b6909ca8ac626e8b7e91f59aea6ced12f0f2570c2b1592a9487d5b675101a69e4da7f7203a8265aee66e16bb7829e77a78684c7bb66f5c8552c4524a1bb72973ee9792a1f6a6bc6ac679d921f162e8eaad52866e056156be3679a0cf032603d7909ca3f816155747bd7ffb0a55c7f739360fb168d6a5b5d1b997ae59adb475e5e75f0db64f1c72b4149fb4192946cd66c2235a185a035005a4cd5f142c323466c774caf1e1d13c109b49f0c0c2390645965e3a1ab4d7d6c33c12a464d017187553a60665510e3aa5a294b1f56e21403207a96192507b24f01644454ad3cdaf4a37c66a2d85a5f7e4512fd58c3210cad36b46e6d42781859568fb1143688447a9ac2924fa1877fb0d4643048cbeddbd75699092af9f12717895d632f90931d2a019f809b0aaaa8c61d894fad69a76e7257f005b2a45b0dd40fd4d5336ba73446a83057dfbccaf14336504987369f3351ab6fe0e9fcdbe5066afbb82a1758133054122ea70be0816dd93d0d2f713cbdd8c4bd05bf2c879f1af441855b5c01fd306489bab79ef9ae1adac8e00f0407201712b52f69150c8e45e03186ffdb5934ab42b11214d1dcaca905710f405aa4c28e93a7994bd169525a4bc1999189f2be6f2c0df1fa61631c48f60b5d04efc1c628e842380c9ed692d9c0ecac0e3566894b090533136b211a4c8d74c59a6f3d041cd06ee36ae9917eb53014c48035dc61ec7ee2bbdc5ce5210c8a42967e1acaa2293461d358754723cd5960be97b38d4d0378c2c94d7b28a7f7da8bc30d4d47f80ceb9cf989da13060bf8f258e92c5b8cdca4a525674b016ba56b26de7c93dae98fd9dea73dec26b91232a61fb4d23841094ab734967f04d224140d2357b0593b4cc7bd7bcd90ad875ee5444bf176160d9ab2256d6f02b56dd2808da1ed8e66df7e5678baf222dabd1cbed296673350cc1894f074da81dbf6c8bfa7e225e06afafadb4e764c5e2df3afda52f097844c2e1fedcb2d068e4b462ae10252df2c7890efaed82719109aeb30009884d118692f3fde5817a2c58b6981b34639bb2f993ab1ae6120e51c544b62b147fcdeed2d451834f824521d0535baa020bb9291a12800134cea64b700c8cae1ad12f7adf837bfdaaa1da7f3872a7c6f2fc04d68a0689c83697a545fd93883b1310e5b86d554eef9d97d7075d1f285b870707617025c6f32a55bafaa12e49c108214c58f9965059143591e166e81cfdfeac3c09d71e70cd9a6dc9e9471de618878f1ca2eb9a181720911d12660a2b020d6cc9c3109f636e9c0e56e59012922ea6c3bacc23eba263c76f1830aab35f68406ec324d1f90ad31a53a11965367255a55fbec60288e7bcf4c48d8d404555a31e938344a8ec9679e67c6532b97277bf513bab9ac025ae594f4adf35a20fad81e3f14ec28594156c2080c4d20715bf9810de4192dcad5325847683ea38e0f268ad2e7e5dfd98e4b8b5223c855f1f706663b06c64a6448f56423048ffac1f4546a6b2621407f0cee7e186d5efc8b849a91ee0e3c7c423e22585b1c62158d7466d3b430cee06498001ee4a96c89a63d9e804e10321f5bce9c0ae5010b93717191ad09b1df8e853dc036ee4008cad903401a49e240e411f3560dba811f22b6fdff725bc284b28913dcab5a004d9779a3b2876e3f7058eacf0291342dfb213639c754abb1cfa44d21f2f37c44d0bb1d5d50ef5fa0abdbfa7fe460a82d90afe8fba8a1188d92df9d016b8cd0304b9b784abc77dea5626c2dfbee43cda005dcb8083703cb749995dca34f93ba0bd00ecb6f1c3bc15fb3d6db88901b9667abb2b64355c5ffa4b72f6c5b0cb47559a9f5c80060bcaf59196c0fd75cd6a475098a7fd3befa22b00c21d5a493ea96edf8391dea0a3c1e473ccff8c9876d27facf9a89f9a00a32fdac45332b92c55fb485c63d77712b1f11d67212c0d2490b1b10efc9c8b4bf768c7b6265a6276c56bfa51277c4f3bc19da54e7f2db9b184e2025c9f6262c28b214e7c048354e555f7ecc221701fd6826b4e5cd3c44802c109daeb5e039b59ced1597aed2f9211049696bedb1fc55075cfd74c10976110b7afa09e27a4b6c7d111ce5464d96bb6eab5aa0dac815d612751690b2e55f5f38136f99085ceb07e573239f842ac40f9cdbb05c2b7706c4c65e04f154e83f354304f34932d3c83ad73eb1ba89528e5d5baae848ff37ed6f4626da33d6bbc9c40b46e42d2ce7b313bf03c1fff487f4cde42fc966594eb99e817a7c107c9d8ce32be10955456facff0d05503570c83cb45404b0c0fd40c94a9644808b17f3041ebc343e749af5eaf138253741cbca8ec54cc9cb3bfa02232ece965d63aaef160190d924208ea5b5fbffff45d968e84fc65f336a6a5261154eea6e62c386c1e010f42d04a707e145908af60161379a6c99af4b08bca3a9ca31d5a33367552a3bd3514e0a22b01ab68b837fabd008b6c6c3beedad0f94144dd3597604766cc1caee0cff8dc01d091a6dc6c3b36785608b82f2eb1e7f8fdf527d945f867b342d29b3011f4b9f4b1a10e28f7d2ecdf3b5cb5580be1a8f3965e654f4f65b9ea30f423bd6ac2f70947e4d20f822a1bae5cf40a2cbe3f2773c9425e9d6360ff1c0628f7b23b82dc02c8120aa5e112aad6f8c4bfa7dbd3bc7b729d0682a72a089c702dd2e91f4e25d0679a9fd040ada03e271578cf8d8f086c5eeb6aed86ed246c84093e1cfa3efd02747712ec34d40669d2cb0ea030c4708cfe9200b184d84bcf9b76227cc0bd0b02bff3e40bba77c29066361caa4f67b16b8528aa7c812587e60dde23825099adf898f856c9792e74496a465c3286965386995975544c3ca25085ad8c522ae426da0c5dacdad2c4f7d57b57d2f536a34e10b0edb9c2089b5628932698653ddd91fe9311a5fe02c57d278f8ddad4374735f1e39f80cbda4de84f6ff070226eda73e293be382fd51706f7e3ce4657b4ecff5244541bd1d0e5f6afe8b411d863f52fb6da59c135a1669651f7bcfb7a89de63b58a8cde6291c720cd49715df9970e852ad29815ffafcecbd7a041bde92d4176f9dccabdb4cee26f0dad6b5bcdd9f0cfedb779b8474538240bef7fa08122f325fac69d678fae907c80e07d511a315116254969181a94e5a4ba54d0e140a21c11cf9692585cbe3fca118b334a650154103dc88b7b64e9be893479f15bff32255eaaf3ee80e421197a1ceda6626199e56341fa59bb5d297f1accc45259ed0521abc97323de38129f1a0c7080021cae1e1aaefbd81f53974ecf872077b3363f0c7f8d90add1791efebec7f0a4037ef60f70e451303919f73a457c1492b815cd401e7b7afdf390eb7485439a0ab71f9feeff1b3abbcfc610c27583119a7f89e3c10370783eae0b907e24b3c5f21359c6a5a6e15b0ae0645807d014b2e6aea466f10e1ef0bab013329de3b7588074173930b60af2e76262bc03aba381c7df995777a50127473ef630f3d0a2918745f2ed7fb93a747502b8d6b683f61d2941b975c9ab467ccb9ea62f9a038de668f9e481310d941d810550bb29904796afd26c0750b78afc4dfaf889e5b6b8404bf96437e0809393a233ccf83317d8eccf66d9265abdff4ab12141ca7299b8753a1d6b049da48731c6a7281710ca0d87049a56995ba9ae77584451377af7295b30786394d0839a9b54faac86a96400deb0336732e059fb3fb23fd331e8ed66e76074415e8c9cd723426b41207dd82899bcb7765bda916c278e5c9088c200c641a933d680813cbd4648c5bfb401a62b32a62868a684bb6d635ba82f5b23c262e48fa38174f2a0500011c37775cd62a1ea095053c006997c453599e766ad08e75be41fb47de6d721e05ac030ad238dc3ce0ce9ec75ea4768531d52e19854573f5697056bea8f6fef66a9f316fe4989610d76f761cc9fef90d7fe3552becd6047b66827f71d3d8f0a5ad242a28dcce235c5c0fe2ecc12f5348d0a0a672ad8d5ed26e092ea8323bbc24fc1419a0b2d6bfab5169a55c8ae1f255a2580cc480d203f55e5e76bdbbbf0409adeda4a8fc7f0c2c2c34b1e885dbc3deccedc83c742b9d43407e5b1ba7cad8794c1f62314f95b7f5351d89acd585763f28d2051b1f2aea47f1b23965961f274401f9c14ad84e5c1958aabc362b601dd64ad60a56e693a93893906328ce5abc83c0d0b9e9f5b37dd9494770f05475d1685120186802a8a0574ae75aa993e048dededa9b682b301989a57725837dc02f33793a856178dcb78da3b21d639350811cc425203bd4658d0d3638510b97bdcf5f3ba5782b1ebc44cce061cba48e0ff468b04e8d92e0cdff37d0897506fe25d12b0c338346c94c6dabd37898072d03002cdb4f5a080d97a0e57280010a46aca4e81826343fef28a939299f477943d4b4c91584fcf657777d0f791eaf5f655ff55b6f0caaa2553f5f9c44e6d6f41e89f5c54c33110e0ea68f106e69c4cba4cd400f07ccb389f97c8bdb1d1bc62679a46e2f16959fc4b30afa3c78d57b422ca4b25bac9f8446802e7ac5285733904b6305372297c3918c71364969d657add3bd20ccba2670726b109041f5462319ea2c851b68bf82d2781fdb783d96f4373119f2fd4d0491ce5fb653777b6c2ee7302cdf99a847de7f31b2536673015122b0cdc45a1c193be3eec7532f77aab32f1d29b4b8d5174d0901721b6bce2952f6c947bf49b06b0ac7c668e8480329e3ba79d16d839669f986c474ede9ca55b9216b240e82a8fc2f63fc01905bb853d88743fa4dca5ece9bbcb5de9515dd2cc4a149609f96e3920f1a59a39cd40a96b7bf4648a224ba0c01c5151b6e9cb70d90772b776d3a698adce8a97f9041288f014f9865d0dc804c5234b7c5b03257b4c1d7412795c26994f8b539a256f7819fb64be292375c3e73db9a2ee53e69d4b4cb4268285bc2ddee7446d44e952f237f7ed5d599a63b2acfe9e730e178e188889b7746eebc1931592b22360d3190e4bf3aa6aa98e26097c9fca077c5470e5ce4b4cf3464ed30f2b20bca7966accebf577b43563af82ce3add2c724c351df401bec12e0400899c718685deb0fbcb866f8ce7ff250b6c546471ee2c7654068a3d28fd54409dbeb97002c86b991fb822d243d1812b11790746b519c2929557c137eb68f39043a0d4757cd2f5b33926a2ac34880fa65c39aa1afa179fb06db9027065ce0a00381264bec8e8c84c8b6051095d0573cab0c402efeb38d716367f1cacce45680273191bf9eb967568cd17527dcd01dd0421e2bb6239383cad7f389681df55c449b7a8d928c390b6450892f38cafa99f9e73a2dfecd13ffb5efc2e58d2cd2b88ca4f37f7876ae0f86c2937244f3f65b0c6c144882f237047f3f2b72edde74f600da6016fe4fcc25dd96da5d24d9915c7ac10aa3a64cd86040319933784f208625a4a18c73b97aa391cb7001c189f0d80b783a6dc54c841dc744b7d68a20754b3d22e57e978e7f72f3c027f5932ef3bb1dd53545e5db63c4d1f4dbbf47e5936f2fc170cf58da92ed1d8425493ff5f9414e979669c4dda0c2173acd79ab2d7b0e9a79c13fec81cc57a81a87860faed6ea94c4747595b44436fef3189bbb852af59579250f5d72876c62b3e6ac9c4c3d2c2e0f9ba169466945cb96b6ebe59a4e1815eec4ad3784610d4eafa98f018107a9b54ccbce61b7b099c5711b222d2ac06bdcc461abd27a0e7fd7843d819b0d6c1f9af6ba82491b2fba052143ade0da5480c2ea2e4d005686956a1a728cb52eb12b13c32c2d9d15af10c79f3efa743a404d5610e5d2df4e915a5f067115feb5856ec75ed1490797e43c37787a9fdded86a33d6268c05abd4a78cc5289bab238f26d902d228b18f3a443c1c2c90a2dcae0e5b484871a6655c567efe72b586dc9d02b7fd701f657203207ad739cfb4ea562107494201552b8cc6404ea90fc6e3750897bca2bebfd48ec6bd49eaaf3dcd2da414f9acc5bdcd9844b7760d62bf72ebaca7db0e3966657be2de1f221c4c1825cf3c9eaad2181c1b9b335028bb81b7a92bfeba1eaf9439c84b652802c9927dafc9601edc0e649a5d862c1b21a409cd6e10e145770684fa17ab04d6ce5585809e1e53e0e9d7483d8eeb9161972b9b7596fed6a13d54d9a019e1b65debacfaed711da320863a70a639c1b4fec390bb2ea1a3719b8fa89267a25027f593d72debfb1b61aa73edf40c7c410145474b3c8457cf4874c63b4b1636acbdbf0999a9511c442b2be359f33669beded50a7526f393eee4d5e025d578cef5a41774007a547d370bccd9ef001ce5f874065b965e42d722e18c0a8d629848ff4f5ec4e45cf5a038b171495c8e1f0aaf861b2d49b8bbb966567114fa8fda4e2bd5ca392d2dbd76a3ec49f600c76387f7ad45baeb087466466c8dd47cbe7ea9b48df14556b17d89938b6c285d9885f4fba6a4315f8a3e82223142ac132834d1b750e37b28df016e0e890d3497d6e2d03b1d55892949c828674745a125a7f974c2b77f8fe8cb6dc0a1c55dcdb469a717cea52efa02e48d88e78b9c6ef52963ad3569a396b406b9989de5037184e2da00bdb5dadb8ee42802369da580eb0b62de715c16fe7398242ca733c28c5745f54aeedc2d596497d9ab122e10a0ca483c4e94bf93fc3391d6847e7b2352f627a2e82be9291829ba7838f3b6b419ca5cf142fed7c31e8b663895063383a6f60439c674460f143e7b05580acf603152d04b0c657971d15e68805f1de1cd63c842d436146b39fd27f4e1b9f1979d8758a51e6c225128e09c53d68140a4ed2627a363961459124b91ea21096df95f515b631b14dcb91b00b89f6dcaacec41b6ed6029641cea4e53fcaa5af45e7d960bc15f299fc8d2ae1f92d488c92c774bd8f5e34fc4217144c198fb8c71e346fcdc0dd150e6328542222d2ae9d0619db0c4d9c3198954f0882dd5a64f9dceb7558585315fc6b1801e752fff3ebdf97e697127eb33e90dff911fabc70d74ea9e4c5ce1c6d12417b12d9eb2e05f693ddc649e0c6991b926919c332a1427a8d26ce426bc37636a78a049c40f368f6bbd326fcce6ad320cdbcb0f43602128c2801e44f0e83ce604fa1020a92c0ecf65d582e4f5a0aee155d3d2a9ba08071de1865b8df69ebf1d6955b272da19d6d524e3e755d376f586ae66c2ad89218ac28bc6f93468e33131a4ef1463b70719354c7687dbccb4e9a81b3839b44ea936cf814553dd016f9e1641cfad239c66457c72e543c5c22633c9bc1cb21760e3e2fc10d01d129dd78f43908add3be6d836cbfc9a8e5019b87741b8fb85ef2a877fcfb494000a9b46d780f8eacd95e5d04e6cc9be55341e856c8fa0d5e24dda38f18c9b8e034fcaafdd9f9cbecd1bdaae0c5df7aec1f24af0709fea3f8fc59f67d516bd72bcd819de7c10c8761b4a43cb3b937cdcfdbdb0bcc16f93880f41e4c9deb9b1c2ac8d7171894e7e8f05b4bc00c52abee0c0ad9119541cbdc3618647d3c3e3e3ecdccb03127851265276bd706a7e6e9c3495d651e65642a106bbc8f645daaab57f7f150b6269479f1e31e1ce005c8b14d1d8d8555ab1913304ab7ede0517cd6c668e20e3a700c2e57443311912f28465b92c1c8af3235e405620242fb5c6f43c5bd75e95b644df434b32f19d4aed2934c44d75b5e556f02496c13ca39fb46dd3fd13c08fd339662e76875cf46fe347ec0fa27d794680ce887d16c3fdc46a9aeb254e0658fdc0b169fd18c4a32ea701078681830c6a15ecc4153c802f791ad83259e38f9fc04615aea35296b11569de41f8c17b6991c128bfdc44e2d4040dc8e836729fc398c3a736caec82673413c6d4ac7f8e4d7063509cfe63f460338d927690b25fdec63c6ea91c8284f6d030c025db059ebd64d8fd8dfd271ef628e2f17049121ce50b9338a9f4aa5775977440d2564712358ccd8c7a76a3498b7c6557f0f5da6b3a049041535c7182534eb7cac79744dd7714c064a808d09f14de9494ccba2cb08fceb0b3a06c40dc33755d7b7d7be38d96cdeb7e81350d702900e2360ac500e4a61b80c496ea0772a4e9bf02fc8dd06ad9d3058f938e993020fc84da5782e7fbbebf77d0d32fc259fad1131037a8eed92f3b13b28f114b9fe77fadb0a2ebb624f53937b78d2bcfd86f7b68c901cb23a528d8488d0f6d85a48fd78a7fad4a715a886bcb6f075b081e579a8a51b6bec0d2cda51d9e77ffa37ef269cc2c01721cd28d07125d2bfdbceb28c7d536d94705904360c34c2ebd1c8bef0b4ab482abd0f542a81ffa39cce5c07cc8257b0180dd2737767431c73eac9a0d7c060d28cf28d6cf0059ee610022ba0db770db7ace3fdf1180e352b9a2bdc2456956f6492228008357100f4c1c92ad1464aca7056051fad60693b4d682b34671759c97427de223ffc9ae7f30bf5f84083bddc14a91b0309bca11f60fb2c882dcddb2de9e06d01f828b8436306be43344b77a288fe053cd1c3f1b90fda628ff381679528cc857966e52699e47213089f7b79dae008ec1f218ffcb76f1fb3d40a2c87f0996e7bc5a117cdca4d659ac8ad50092cdf3a43e9a06cbaac548e8f201f2b2f8d6305a5b418546303a2e7da49a736c490170b358a706723fb9fe477fa05ee02f5792c9d4a9397e3d81173ab2e1d4ff0800db71dfc10bcac7ede6178d1f526093e86b975d65eb605f1817d252a259d1c8d426e06b5684635b1f18692e411a2353abc4c47c0629ed825f8b809e6bbddcd1cf9e29a06318766aa87c0cc01acd523597d16ef21e38e8d61b0a619cc2a88a32305c44357c8e61b02d1377e3589676963cd02d630f2b7dfb53002cb34f7d7967ac292b2cd0818f4428e6866477c1c21386ef7a97b7127b5dc51ed91303b1dcac59d32a49e838ca43f72f06108d9c75d69e2d8dd6c16ded056957ba14f633cab39f9df1190ad3ca1c474cf6a809254227c16df660ebf6f</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-xray">      <input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span>      </label>      <svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">        <path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>        <path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path>      </svg>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">论文阅读记录</summary>
    
    
    
    <category term="Medical Image Registration" scheme="https://www.miraclerice.top/categories/Medical-Image-Registration/"/>
    
    
    <category term="Deformable Image Registration" scheme="https://www.miraclerice.top/tags/Deformable-Image-Registration/"/>
    
    <category term="Score-based Generative Model" scheme="https://www.miraclerice.top/tags/Score-based-Generative-Model/"/>
    
  </entry>
  
</feed>
