<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>模块 on On My Way</title>
    <link>https://tuanzi-wow.cn/tags/%E6%A8%A1%E5%9D%97/</link>
    <description>Recent content in 模块 on On My Way</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Fri, 04 Sep 2026 00:00:00 +0800</lastBuildDate>
    <atom:link href="https://tuanzi-wow.cn/tags/%E6%A8%A1%E5%9D%97/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>6. 模块</title>
      <link>https://tuanzi-wow.cn/python/python-06-modules/</link>
      <pubDate>Fri, 04 Sep 2026 00:00:00 +0800</pubDate>
      <guid>https://tuanzi-wow.cn/python/python-06-modules/</guid>
      <description>模块的定义与导入、标准模块、dir() 与包的层级结构。</description>
      <content:encoded><![CDATA[<h2 id="定义">定义：</h2>
<p>模块是包含 Python 定义和语句的文件。其文件名是模块名加后缀名 <code>.py</code> 。在模块内部，通过全局变量 <code>__name__</code> 可以获取模块名（即字符串）。</p>
<h3 id="导入模块">导入模块：</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">import name(模块的真实名字)
</span></span></code></pre></td></tr></table>
</div>
</div><p>本质将模块名称添加到namespeac而非把定义的函数添加进去</p>
<h2 id="61-模块详解">6.1 模块详解：</h2>
<p>模块包含可执行语句及函数定义。这些语句用于初始化模块，且仅在 import 语句 <em>第一次</em> 遇到模块名时执行。
每个模块都有它自己的私有符号表，该表被定义在该模块里的所有函数当作全局符号表使用。
您可以使用与引用模块函数相同的语法去访问一个模块的全局变量，即 <code>modname.itemname</code></p>
<h4 id="导入其他模块import">导入其他模块：import</h4>
<p>被放置于一个模块的最高层级，则被导入的模块名称会被添加到该模块的全局命名空间。
import的变式1：将来自某个模块的名称直接导入到导入方的命名空间里面</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">from fibo import fib, fib2
</span></span><span class="line"><span class="cl">fib(500)
</span></span><span class="line"><span class="cl">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
</span></span></code></pre></td></tr></table>
</div>
</div><p>变式2：导入模块内定义的所有名称（不包含以_开头的名称）</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">from fibo import *
</span></span><span class="line"><span class="cl">fib(500)
</span></span><span class="line"><span class="cl">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
</span></span></code></pre></td></tr></table>
</div>
</div><p>不建议：可能会覆盖已经定义的名称</p>
<p>变式3：模块名后接as</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">import fibo from fib
</span></span><span class="line"><span class="cl">fib.fib(500)
</span></span></code></pre></td></tr></table>
</div>
</div><p>或者变式1，3结合</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">from fibo import fib as fibonacci
</span></span><span class="line"><span class="cl">fibonacci(500)
</span></span><span class="line"><span class="cl">0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="备注">备注</h4>
<p>每次解释器会话只导入一次模块，若模块内容更改，需要重启解释器
如仅交互测试一个模块，可以使用<a href="https://docs.python.org/zh-cn/3/library/importlib.html#importlib.reload"><code>importlib.reload()</code></a>，例如 <code>import importlib; importlib.reload(modulename)</code>。</p>
<h3 id="611以脚本方式执行模块">6.1.1.以脚本方式执行模块</h3>
<p>最常见命令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">python fibo.py &lt;arguments&gt;（这个参数的必须的）
</span></span></code></pre></td></tr></table>
</div>
</div><p>导入模块的代码，但是会将_name_命名为&quot;<strong>main</strong>&quot;(这里前面和后面都有一个__，但是因为md原因导致没有了)</p>
<p>例如</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">python fibo.py 50
</span></span><span class="line"><span class="cl">0 1 1 2 3 5 8 13 21 34
</span></span></code></pre></td></tr></table>
</div>
</div><p>相当于</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">if __name__ == &#34;__main__&#34;:
</span></span><span class="line"><span class="cl">    import sys
</span></span><span class="line"><span class="cl">    fib(int(sys.argv[1]))
</span></span></code></pre></td></tr></table>
</div>
</div><p>该文件既可作为模块又可以作为脚本
而像下面这种导入其他模块则不会</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">import fibo 
</span></span></code></pre></td></tr></table>
</div>
</div><p>用于为模块提供一个便捷的用户接口，或用于测试</p>
<h3 id="612模块的搜索路径">6.1.2.模块的搜索路径</h3>
<p>当导入一个名为 <code>spam</code> 的模块时，解释器首先会搜索具有该名称的内置模块。 这些模块的名称在 <a href="https://docs.python.org/zh-cn/3/library/sys.html#sys.builtin_module_names"><code>sys.builtin_module_names</code></a> 中列出。 如果未找到，它将在变量 <a href="https://docs.python.org/zh-cn/3/library/sys.html#sys.path"><code>sys.path</code></a> 所给出的目录列表中搜索名为 <code>spam.py</code> 的文件。 <code>sys.path</code> 是从这些位置初始化的:</p>
<ul>
<li>被命令行直接运行的脚本所在的目录（或未指定文件时的当前目录）。</li>
<li><a href="https://docs.python.org/zh-cn/3/using/cmdline.html#envvar-PYTHONPATH"><code>PYTHONPATH</code></a> （目录列表，与 shell 变量 <code>PATH</code> 的语法一样）。</li>
<li>依赖于安装的默认值（按照惯例包括一个 <code>site-packages</code> 目录，由 <a href="https://docs.python.org/zh-cn/3/library/site.html#module-site"><code>site</code></a> 模块处理）。</li>
</ul>
<p>更多细节请参阅 <a href="https://docs.python.org/zh-cn/3/library/sys_path_init.html#sys-path-init">sys.path 模块搜索路径的初始化</a>。</p>
<h4 id="备注-1">备注</h4>
<p>在支持符号链接的文件系统中，“被命令行直接运行的脚本所在的目录”是符号链接最终指向的目录。换句话说，符号链接所在的目录并 <strong>没有</strong> 被添加至模块搜索路径。</p>
<p>初始化后，Python 程序可以更改 <a href="https://docs.python.org/zh-cn/3/library/sys.html#sys.path"><code>sys.path</code></a>。脚本所在的目录先于标准库所在的路径被搜索。这意味着，脚本所在的目录如果有和标准库同名的文件，那么加载的是该目录里的，而不是标准库的。这一般是一个错误，除非这样的替换是你有意为之。详见 <a href="https://docs.python.org/zh-cn/3/tutorial/modules.html#tut-standardmodules">标准模块</a>。</p>
<h3 id="613已编译的python文件">6.1.3.”已编译的“Python文件</h3>
<p>模块的编译版本存放在&ndash;pycache__目录中，文件名为module.version.pyc,</p>
<p>version:对编译文件格式进行编码，一般是版本号
可以让不同版本的Python编译的模块可以共存
例子：CPython 的 3.3 发行版中，spam.py 的编译版本缓存为 <code>__pycache__/spam.cpython-33.pyc</code></p>
<p>Python会自动检查编译版本和源码的修改日期来查看编译版是否过期，是否需要重新编译
编译模块与平台无关
Python不检查缓存的两种情况
1.从命令行直接载入的模块：每次重新编译且不存储结果
2.没有源模块
隐藏源代码：将所有源代码编程编译之后的版本，并储存在源目录而非缓存目录中）</p>
<p>ps：
.pyc的读取未必比.py快，只是加载速度更快
<a href="https://docs.python.org/zh-cn/3/library/compileall.html#module-compileall"><code>compileall</code></a> 模块可以为一个目录下的所有模块创建 .pyc 文件。</p>
<h2 id="62标准模块">6.2.标准模块</h2>
<p>Python自带的，在Python的库参考中另外描述
这些模块集是一个配置选项，并且还依赖于底层的操作系统
例如winreg只在WIndows系统上提供
但是sys模块内嵌到每一个Python解释器，sys.psq和sys.ps2变量定义了一些字符，可以作为主提示符和辅助提示符
变量的sys.path：字符串列表，用于确定解释器的模块搜索路径
从环境变量PYTHONPATH提取默认路径进行初始化，若未设置PYTHONPATH，则使用内置的默认路径
可以通过标准列表操作修改该变量</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">import sys
</span></span><span class="line"><span class="cl">sys.path.append(&#39;/ufs/guido/lib/python&#39;)
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="63dir函数">6.3.dir()函数</h2>
<p>查找模块定义的名称，返回值：经过排序的字符串列表
没有参数时：
返回值：当前已经定义的名称
包括：变量，模块，函数&hellip;&hellip;
但是不会列出内置函数和变量的名称
这些内容的定义在标准模块 <a href="https://docs.python.org/zh-cn/3/library/builtins.html#module-builtins"><code>builtins</code></a> 中：</p>
<h2 id="64-包">6.4. 包</h2>
<p>通过”带点号模块名“来狗仔Python模块命名空间的一种方式
可以让不同包的作者不用担心彼此的全局变量名，比如模块名冲突</p>
<p>导入包时，Python 搜索 <code>sys.path</code> 里的目录，查找包的子目录。</p>
<p>需要有 <code>__init__.py</code> 文件才能让 Python 将包含该文件的目录当作包来处理（除非使用 <a href="https://docs.python.org/zh-cn/3/glossary.html#term-namespace-package">namespace package</a>，这是一个相对高级的特性）。 这可以防止重名的目录如 <code>string</code> 在无意中屏蔽后继出现在模块搜索路径中的有效模块。 在最简单的情况下，<code>__init__.py</code> 可以只是一个空文件，但它也可以执行包的初始化代码或设置 <code>__all__</code> 变量，这将在稍后详细描述。</p>
<p>还可以从包中导入单个模块，例如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">import sound.effects.echo
</span></span></code></pre></td></tr></table>
</div>
</div><p>这将加载子模块 <code>sound.effects.echo</code>。 它必须通过其全名来引用。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
</span></span></code></pre></td></tr></table>
</div>
</div><p>另一种导入子模块的方法是 ：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">from sound.effects import echo
</span></span></code></pre></td></tr></table>
</div>
</div><p>这也会加载子模块 <code>echo</code>，并使其不必加包前缀，因此可按如下方式使用:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">echo.echofilter(input, output, delay=0.7, atten=4)
</span></span></code></pre></td></tr></table>
</div>
</div><p>Import 语句的另一种变体是直接导入所需的函数或变量：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">from sound.effects.echo import echofilter
</span></span></code></pre></td></tr></table>
</div>
</div><p>同样，这将加载子模块 <code>echo</code>，但这使其函数 <code>echofilter()</code> 直接可用:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">echofilter(input, output, delay=0.7, atten=4)
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意，使用 <code>from package import item</code> 时，item 可以是包的子模块（或子包），也可以是包中定义的函数、类或变量等其他名称。<code>import</code> 语句首先测试包中是否定义了 item；如果未在包中定义，则假定 item 是模块，并尝试加载。如果找不到 item，则触发 <a href="https://docs.python.org/zh-cn/3/library/exceptions.html#ImportError"><code>ImportError</code></a> 异常。</p>
<p>相反，使用 <code>import item.subitem.subsubitem</code> 句法时，除最后一项外，每个 item 都必须是包；最后一项可以是模块或包，但不能是上一项中定义的类、函数或变量。</p>
<h3 id="641-从包中导入">6.4.1. 从包中导入*</h3>
<p>提供包的显式索引</p>
<p>导入在init.py 代码定义了列表 all
发布新版本时，应更新该列表
例如：<code>sound/effects/__init__.py</code> 文件可以包含以下代码：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">__all__ = [&#34;echo&#34;, &#34;surround&#34;, &#34;reverse&#34;]
</span></span></code></pre></td></tr></table>
</div>
</div><p>这意味着 <code>from sound.effects import *</code> 将导入 <code>sound.effects</code> 包的三个命名子模块。请注意子模块可能会受到本地定义名称的影响。 例如，如果你在 <code>sound/effects/__init__.py</code> 文件中添加了一个 <code>reverse</code> 函数，<code>from sound.effects import *</code> 将只导入 <code>echo</code> 和 <code>surround</code> 这两个子模块，但 <strong>不会</strong> 导入 <code>reverse</code> 子模块，因为它被本地定义的 <code>reverse</code> 函数所遮挡:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">__all__ = [
</span></span><span class="line"><span class="cl">    &#34;echo&#34;,      # 指向 &#39;echo.py&#39; 文件
</span></span><span class="line"><span class="cl">    &#34;surround&#34;,  # 指向 &#39;surround.py&#39; 文件
</span></span><span class="line"><span class="cl">    &#34;reverse&#34;,   # !!! 现在指向 &#39;reverse&#39; 函数 !!!
</span></span><span class="line"><span class="cl">]
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">def reverse(msg: str):  # &lt;-- 此名称将覆盖 &#39;reverse.py&#39; 子模块
</span></span><span class="line"><span class="cl">    return msg[::-1]    #     针对 &#39;from sound.effects import *&#39; 的情况
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="没有定义____all____">没有定义____all____:</h4>
<p>有点没懂</p>
<h3 id="642-相对导入">6.4.2. 相对导入</h3>
<p>使用前导符号.来完成
一般用于子模块</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
