转载--python模块

<div class="forFlow">

<div id="post_detail">
<!--done-->
<div id="topics">
<div class="post">
<h1 class="postTitle">
<a id="cb_post_title_url" class="postTitle2" href="https://www.cnblogs.com/wupeiqi/articles/4963027.html">Python之路【第四篇】:模块</a>
</h1>
<div class="clear"></div>
<div class="postBody">
<div id="cnblogs_post_body" class="blogpost-body"><p>模块,用一砣代码实现了某个功能的代码集合。&nbsp;</p>
<p>类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。</p>
<p>如:os 是系统相关的模块;file是文件操作相关的模块</p>
<p>模块分为三种:</p>
<ul>
<li>自定义模块</li>
<li>内置模块</li>
<li>开源模块</li>
</ul>
<h3>自定义模块</h3>
<p><span style="font-size: 18px;"><strong>1、定义模块</strong></span></p>
<p><strong>情景一:</strong></p>
<p>  <img src="https://images2015.cnblogs.com/blog/425762/201511/425762-20151120210254796-391850912.png" alt="" width="339" height="50"></p>
<p><strong>情景二:</strong></p>
<p>  <img src="https://images2015.cnblogs.com/blog/425762/201511/425762-20151120204455296-1485426970.png" alt="" width="347" height="109"></p>
<p><strong>情景三:</strong></p>
<p>  <img src="https://images2015.cnblogs.com/blog/425762/201511/425762-20151120204617843-2002471507.png" alt="" width="344" height="155"></p>
<p><strong><span style="font-size: 18px;">2、导入模块</span></strong></p>
<p>Python之所以应用越来越广泛,在一定程度上也依赖于其为程序员提供了大量的模块以供使用,如果想要使用模块,则需要导入。导入模块有一下几种方法:</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_73705" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">module</code></div><div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">module.xx.xx </code><code class="python keyword">import</code> <code class="python plain">xx</code></div><div class="line number3 index2 alt2"><code class="python keyword">from</code> <code class="python plain">module.xx.xx </code><code class="python keyword">import</code> <code class="python plain">xx as rename&nbsp;&nbsp; </code></div><div class="line number4 index3 alt1"><code class="python keyword">from</code> <code class="python plain">module.xx.xx </code><code class="python keyword">import</code> <code class="python keyword">*</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>导入模块其实就是告诉Python解释器去解释那个py文件</p>
<ul>
<li>导入一个py文件,解释器解释该py文件</li>
<li>导入一个包,解释器解释该包下的 __init__.py 文件</li>
</ul>
<p>那么问题来了,导入模块时是根据那个路径作为基准来进行的呢?即:sys.path</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_949806" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">sys</code></div><div class="line number2 index1 alt1"><code class="python functions">print</code> <code class="python plain">sys.path</code></div><div class="line number3 index2 alt2"><code class="python spaces">&nbsp;</code>&nbsp;</div><div class="line number4 index3 alt1"><code class="python plain">结果:</code></div><div class="line number5 index4 alt2"><code class="python plain">[</code><code class="python string">'/Users/wupeiqi/PycharmProjects/calculator/p1/pp1'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/setuptools-15.2-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/distribute-0.6.28-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.10-x86_64.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/xlutils-1.7.1-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/xlwt-1.0.0-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/xlrd-0.9.3-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/tornado-4.1-py2.7-macosx-10.10-x86_64.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/backports.ssl_match_hostname-3.4.0.2-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/certifi-2015.4.28-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/pyOpenSSL-0.15.1-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/six-1.9.0-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/cryptography-0.9.1-py2.7-macosx-10.10-x86_64.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/cffi-1.1.1-py2.7-macosx-10.10-x86_64.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/ipaddress-1.0.7-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/enum34-1.0.4-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/pyasn1-0.1.7-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/idna-2.0-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/pycparser-2.13-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/Django-1.7.8-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/paramiko-1.10.1-py2.7.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/gevent-1.0.2-py2.7-macosx-10.10-x86_64.egg'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages/greenlet-0.4.7-py2.7-macosx-10.10-x86_64.egg'</code><code class="python plain">, </code><code class="python string">'/Users/wupeiqi/PycharmProjects/calculator'</code><code class="python plain">, </code><code class="python string">'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python27.zip'</code><code class="python plain">, </code><code class="python string">'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7'</code><code class="python plain">, </code><code class="python string">'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin'</code><code class="python plain">, </code><code class="python string">'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac'</code><code class="python plain">, </code><code class="python string">'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages'</code><code class="python plain">, </code><code class="python string">'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk'</code><code class="python plain">, </code><code class="python string">'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old'</code><code class="python plain">, </code><code class="python string">'/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload'</code><code class="python plain">, </code><code class="python string">'/usr/local/lib/python2.7/site-packages'</code><code class="python plain">, </code><code class="python string">'/Library/Python/2.7/site-packages'</code><code class="python plain">]</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>如果sys.path路径列表没有你想要的路径,可以通过 sys.path.append('路径') 添加。<br>通过os模块可以获取各种目录,例如:</p>
<div class="cnblogs_code" onclick="cnblogs_code_show('7aca22f5-47aa-4b94-a0eb-56a4ec698676')"><img id="code_img_closed_7aca22f5-47aa-4b94-a0eb-56a4ec698676" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: none;"><img id="code_img_opened_7aca22f5-47aa-4b94-a0eb-56a4ec698676" class="code_img_opened" style="" onclick="cnblogs_code_hide('7aca22f5-47aa-4b94-a0eb-56a4ec698676',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_7aca22f5-47aa-4b94-a0eb-56a4ec698676" class="cnblogs_code_hide" style="display: block;">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> sys
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> os

pre_path </span>= os.path.abspath(<span style="color: #800000;">'</span><span style="color: #800000;">../</span><span style="color: #800000;">'</span><span style="color: #000000;">)
sys.path.append(pre_path)</span></pre>
</div>
<span class="cnblogs_code_collapse" style="display: none;">View Code</span>&nbsp;</div>
<h3>开源模块</h3>
<p><strong><span style="font-size: 18px;">一、下载安装</span></strong></p>
<p>下载安装有两种方式:</p>
<div class="cnblogs_code" onclick="cnblogs_code_show('d08a64af-b0fb-4581-b69f-d31684792f82')"><img id="code_img_closed_d08a64af-b0fb-4581-b69f-d31684792f82" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: none;"><img id="code_img_opened_d08a64af-b0fb-4581-b69f-d31684792f82" class="code_img_opened" style="" onclick="cnblogs_code_hide('d08a64af-b0fb-4581-b69f-d31684792f82',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_d08a64af-b0fb-4581-b69f-d31684792f82" class="cnblogs_code_hide" style="display: block;">
<pre><span style="color: #000000;">yum
pip
apt</span>-<span style="color: #000000;">get
...</span></pre>
</div>
<span class="cnblogs_code_collapse" style="display: none;">方式一</span></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('298ac707-04eb-4c09-b870-8215a5cac32b')"><img id="code_img_closed_298ac707-04eb-4c09-b870-8215a5cac32b" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: none;"><img id="code_img_opened_298ac707-04eb-4c09-b870-8215a5cac32b" class="code_img_opened" style="" onclick="cnblogs_code_hide('298ac707-04eb-4c09-b870-8215a5cac32b',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_298ac707-04eb-4c09-b870-8215a5cac32b" class="cnblogs_code_hide" style="display: block;">
<pre><span style="color: #000000;">下载源码
解压源码
进入目录
编译源码 python setup.py build
安装源码 python setup.py install</span></pre>
</div>
<span class="cnblogs_code_collapse" style="display: none;">方式二</span></div>
<p>注:在使用源码安装时,需要使用到gcc编译和python开发环境,所以,需要先执行:</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_370006" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">yum install gcc</code></div><div class="line number2 index1 alt1"><code class="python plain">yum install python</code><code class="python keyword">-</code><code class="python plain">devel</code></div><div class="line number3 index2 alt2"><code class="python plain">或</code></div><div class="line number4 index3 alt1"><code class="python plain">apt</code><code class="python keyword">-</code><code class="python plain">get python</code><code class="python keyword">-</code><code class="python plain">dev</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>安装成功后,模块会自动安装到 sys.path 中的某个目录中,如:</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_122272" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">/</code><code class="python plain">usr</code><code class="python keyword">/</code><code class="python plain">lib</code><code class="python keyword">/</code><code class="python plain">python2.</code><code class="python value">7</code><code class="python keyword">/</code><code class="python plain">site</code><code class="python keyword">-</code><code class="python plain">packages</code><code class="python keyword">/</code></div></div></td></tr></tbody></table></div></div>
</div>
<p><strong><span style="font-size: 18px;">二、导入模块</span></strong></p>
<p>同自定义模块中导入的方式</p>
<p>三、模块 paramiko</p>
<p>paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。</p>
<p>1、下载安装</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_308909" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">pip3 install paramiko</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>或</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_240082" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python comments"># pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="python comments"># 下载安装 pycrypto</code></div><div class="line number4 index3 alt1"><code class="python plain">wget http:</code><code class="python keyword">/</code><code class="python keyword">/</code><code class="python plain">files.cnblogs.com</code><code class="python keyword">/</code><code class="python plain">files</code><code class="python keyword">/</code><code class="python plain">wupeiqi</code><code class="python keyword">/</code><code class="python plain">pycrypto</code><code class="python keyword">-</code><code class="python value">2.6</code><code class="python plain">.</code><code class="python value">1.tar</code><code class="python plain">.gz</code></div><div class="line number5 index4 alt2"><code class="python plain">tar </code><code class="python keyword">-</code><code class="python plain">xvf pycrypto</code><code class="python keyword">-</code><code class="python value">2.6</code><code class="python plain">.</code><code class="python value">1.tar</code><code class="python plain">.gz</code></div><div class="line number6 index5 alt1"><code class="python plain">cd pycrypto</code><code class="python keyword">-</code><code class="python value">2.6</code><code class="python plain">.</code><code class="python value">1</code></div><div class="line number7 index6 alt2"><code class="python plain">python setup.py build</code></div><div class="line number8 index7 alt1"><code class="python plain">python setup.py install</code></div><div class="line number9 index8 alt2">&nbsp;</div><div class="line number10 index9 alt1"><code class="python comments"># 进入python环境,导入Crypto检查是否安装成功</code></div><div class="line number11 index10 alt2">&nbsp;</div><div class="line number12 index11 alt1"><code class="python comments"># 下载安装 paramiko</code></div><div class="line number13 index12 alt2"><code class="python plain">wget http:</code><code class="python keyword">/</code><code class="python keyword">/</code><code class="python plain">files.cnblogs.com</code><code class="python keyword">/</code><code class="python plain">files</code><code class="python keyword">/</code><code class="python plain">wupeiqi</code><code class="python keyword">/</code><code class="python plain">paramiko</code><code class="python keyword">-</code><code class="python value">1.10</code><code class="python plain">.</code><code class="python value">1.tar</code><code class="python plain">.gz</code></div><div class="line number14 index13 alt1"><code class="python plain">tar </code><code class="python keyword">-</code><code class="python plain">xvf paramiko</code><code class="python keyword">-</code><code class="python value">1.10</code><code class="python plain">.</code><code class="python value">1.tar</code><code class="python plain">.gz</code></div><div class="line number15 index14 alt2"><code class="python plain">cd paramiko</code><code class="python keyword">-</code><code class="python value">1.10</code><code class="python plain">.</code><code class="python value">1</code></div><div class="line number16 index15 alt1"><code class="python plain">python setup.py build</code></div><div class="line number17 index16 alt2"><code class="python plain">python setup.py install</code></div><div class="line number18 index17 alt1">&nbsp;</div><div class="line number19 index18 alt2"><code class="python comments"># 进入python环境,导入paramiko检查是否安装成功</code></div></div></td></tr></tbody></table></div></div>
</div>
<p><strong><span style="font-size: 18px;">2、使用模块</span></strong></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('66c96ef9-d373-4c8e-a63e-ae7ea2b667f3')"><img id="code_img_closed_66c96ef9-d373-4c8e-a63e-ae7ea2b667f3" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: inline;"><img id="code_img_opened_66c96ef9-d373-4c8e-a63e-ae7ea2b667f3" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('66c96ef9-d373-4c8e-a63e-ae7ea2b667f3',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_66c96ef9-d373-4c8e-a63e-ae7ea2b667f3" class="cnblogs_code_hide" style="display: none;"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div>
<pre><span style="color: #008000;">#</span><span style="color: #008000;">!/usr/bin/env python</span><span style="color: #008000;">
#</span><span style="color: #008000;">coding:utf-8</span>

<span style="color: #0000ff;">import</span><span style="color: #000000;"> paramiko

ssh </span>=<span style="color: #000000;"> paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(</span><span style="color: #800000;">'</span><span style="color: #800000;">192.168.1.108</span><span style="color: #800000;">'</span>, 22, <span style="color: #800000;">'</span><span style="color: #800000;">alex</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">123</span><span style="color: #800000;">'</span><span style="color: #000000;">)
stdin, stdout, stderr </span>= ssh.exec_command(<span style="color: #800000;">'</span><span style="color: #800000;">df</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span><span style="color: #000000;"> stdout.read()
ssh.close();</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div>
<span class="cnblogs_code_collapse" style="display: inline;">执行命令 - 通过用户名和密码连接服务器</span></div>
<div>
<div class="cnblogs_code" onclick="cnblogs_code_show('c38c41d4-0989-411c-88d9-2583762e63bb')"><img id="code_img_closed_c38c41d4-0989-411c-88d9-2583762e63bb" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: inline;"><img id="code_img_opened_c38c41d4-0989-411c-88d9-2583762e63bb" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('c38c41d4-0989-411c-88d9-2583762e63bb',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_c38c41d4-0989-411c-88d9-2583762e63bb" class="cnblogs_code_hide" style="display: none;"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div>
<pre><span style="color: #000000;">import paramiko

private_key_path </span>= <span style="color: #800000;">'</span><span style="color: #800000;">/home/auto/.ssh/id_rsa</span><span style="color: #800000;">'</span><span style="color: #000000;">
key </span>=<span style="color: #000000;"> paramiko.RSAKey.from_private_key_file(private_key_path)

</span><span style="color: #0000ff;">ssh</span> =<span style="color: #000000;"> paramiko.SSHClient()
</span><span style="color: #0000ff;">ssh</span><span style="color: #000000;">.set_missing_host_key_policy(paramiko.AutoAddPolicy())
</span><span style="color: #0000ff;">ssh</span>.connect(<span style="color: #800000;">'</span><span style="color: #800000;">主机名 </span><span style="color: #800000;">'</span>, 端口, <span style="color: #800000;">'</span><span style="color: #800000;">用户名</span><span style="color: #800000;">'</span><span style="color: #000000;">, key)

stdin, stdout, stderr </span>= <span style="color: #0000ff;">ssh</span>.exec_command(<span style="color: #800000;">'</span><span style="color: #800000;">df</span><span style="color: #800000;">'</span><span style="color: #000000;">)
print stdout.read()
</span><span style="color: #0000ff;">ssh</span>.close()</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div>
<span class="cnblogs_code_collapse" style="display: inline;">执行命令 - 过密钥链接服务器</span></div>
</div>
<div class="cnblogs_code" onclick="cnblogs_code_show('91d34567-70cf-401a-83e5-8c7daf4cf0ca')"><div>按 Ctrl+C 复制代码</div><textarea style="width: 761.009px; height: 379.207px; font-family: &quot;Courier New&quot;; font-size: 12px; line-height: 1.5;"></textarea><div>按 Ctrl+C 复制代码</div></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('24fb141f-c7fd-472f-94fa-505430cdfcb7')"><img id="code_img_closed_24fb141f-c7fd-472f-94fa-505430cdfcb7" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: inline;"><img id="code_img_opened_24fb141f-c7fd-472f-94fa-505430cdfcb7" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('24fb141f-c7fd-472f-94fa-505430cdfcb7',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_24fb141f-c7fd-472f-94fa-505430cdfcb7" class="cnblogs_code_hide" style="display: none;"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div>
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> paramiko

pravie_key_path </span>= <span style="color: #800000;">'</span><span style="color: #800000;">/home/auto/.ssh/id_rsa</span><span style="color: #800000;">'</span><span style="color: #000000;">
key </span>=<span style="color: #000000;"> paramiko.RSAKey.from_private_key_file(pravie_key_path)

t </span>= paramiko.Transport((<span style="color: #800000;">'</span><span style="color: #800000;">182.92.219.86</span><span style="color: #800000;">'</span>,22<span style="color: #000000;">))
t.connect(username</span>=<span style="color: #800000;">'</span><span style="color: #800000;">wupeiqi</span><span style="color: #800000;">'</span>,pkey=<span style="color: #000000;">key)

sftp </span>=<span style="color: #000000;"> paramiko.SFTPClient.from_transport(t)
sftp.put(</span><span style="color: #800000;">'</span><span style="color: #800000;">/tmp/test3.py</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">/tmp/test3.py</span><span style="color: #800000;">'</span><span style="color: #000000;">)

t.close()

</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> paramiko

pravie_key_path </span>= <span style="color: #800000;">'</span><span style="color: #800000;">/home/auto/.ssh/id_rsa</span><span style="color: #800000;">'</span><span style="color: #000000;">
key </span>=<span style="color: #000000;"> paramiko.RSAKey.from_private_key_file(pravie_key_path)

t </span>= paramiko.Transport((<span style="color: #800000;">'</span><span style="color: #800000;">182.92.219.86</span><span style="color: #800000;">'</span>,22<span style="color: #000000;">))
t.connect(username</span>=<span style="color: #800000;">'</span><span style="color: #800000;">wupeiqi</span><span style="color: #800000;">'</span>,pkey=<span style="color: #000000;">key)

sftp </span>=<span style="color: #000000;"> paramiko.SFTPClient.from_transport(t)
sftp.get(</span><span style="color: #800000;">'</span><span style="color: #800000;">/tmp/test3.py</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">/tmp/test4.py</span><span style="color: #800000;">'</span><span style="color: #000000;">)

t.close()</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div>
<span class="cnblogs_code_collapse" style="display: inline;">上传或下载文件 - 通过密钥</span></div>
<h3>内置模块</h3>
<p><span style="font-size: 18px;"><strong>一、os</strong></span></p>
<p>用于提供系统级别的操作</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div>
<pre><span style="color: #000000;">os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir(</span><span style="color: #800000;">"</span><span style="color: #800000;">dirname</span><span style="color: #800000;">"</span><span style="color: #000000;">) 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: (</span><span style="color: #800000;">'</span><span style="color: #800000;">.</span><span style="color: #800000;">'</span><span style="color: #000000;">)
os.pardir 获取当前目录的父目录字符串名:(</span><span style="color: #800000;">'</span><span style="color: #800000;">..</span><span style="color: #800000;">'</span><span style="color: #000000;">)
os.makedirs(</span><span style="color: #800000;">'</span><span style="color: #800000;">dirname1/dirname2</span><span style="color: #800000;">'</span><span style="color: #000000;">) 可生成多层递归目录
os.removedirs(</span><span style="color: #800000;">'</span><span style="color: #800000;">dirname1</span><span style="color: #800000;">'</span><span style="color: #000000;">) 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir(</span><span style="color: #800000;">'</span><span style="color: #800000;">dirname</span><span style="color: #800000;">'</span><span style="color: #000000;">) 生成单级目录;相当于shell中mkdir dirname
os.rmdir(</span><span style="color: #800000;">'</span><span style="color: #800000;">dirname</span><span style="color: #800000;">'</span><span style="color: #000000;">) 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir(</span><span style="color: #800000;">'</span><span style="color: #800000;">dirname</span><span style="color: #800000;">'</span><span style="color: #000000;">) 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename(</span><span style="color: #800000;">"</span><span style="color: #800000;">oldname</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">newname</span><span style="color: #800000;">"</span>) 重命名文件/<span style="color: #000000;">目录
os.stat(</span><span style="color: #800000;">'</span><span style="color: #800000;">path/filename</span><span style="color: #800000;">'</span>) 获取文件/<span style="color: #000000;">目录信息
os.sep 输出操作系统特定的路径分隔符,win下为</span><span style="color: #800000;">"</span><span style="color: #800000;">\\</span><span style="color: #800000;">"</span>,Linux下为<span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">
os.linesep 输出当前平台使用的行终止符,win下为</span><span style="color: #800000;">"</span><span style="color: #800000;">\t\n</span><span style="color: #800000;">"</span>,Linux下为<span style="color: #800000;">"</span><span style="color: #800000;">\n</span><span style="color: #800000;">"</span><span style="color: #000000;">
os.pathsep 输出用于分割文件路径的字符串
os.name 输出字符串指示当前使用平台。win</span>-&gt;<span style="color: #800000;">'</span><span style="color: #800000;">nt</span><span style="color: #800000;">'</span>; Linux-&gt;<span style="color: #800000;">'</span><span style="color: #800000;">posix</span><span style="color: #800000;">'</span><span style="color: #000000;">
os.system(</span><span style="color: #800000;">"</span><span style="color: #800000;">bash command</span><span style="color: #800000;">"</span><span style="color: #000000;">) 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div>
<p>更多<a href="https://docs.python.org/2/library/os.html?highlight=os#module-os" target="_blank">猛击这里</a></p>
<p><span style="font-size: 18px;"><strong>二、sys</strong></span></p>
<p>用于提供对解释器相关的操作</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div>
<pre><span style="color: #000000;">sys.argv 命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
sys.stdout.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">please:</span><span style="color: #800000;">'</span><span style="color: #000000;">)
val </span>= sys.stdin.readline()[:-1]</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div>
<div class="page" title="Page 3">
<div class="section">
<div class="layoutArea">
<div class="column">
<p>更多<a href="https://docs.python.org/2/library/sys.html?highlight=sys#module-sys" target="_blank">猛击这里</a></p>
<p><span style="font-size: 18px;"><strong>三、hashlib&nbsp;</strong></span></p>
<p>用于加密相关的操作,代替了md5模块和sha模块,主要提供&nbsp;SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法</p>
<div class="cnblogs_code" onclick="cnblogs_code_show('a984cc7d-fc3f-4294-bdc0-15a6f301442b')"><img id="code_img_closed_a984cc7d-fc3f-4294-bdc0-15a6f301442b" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: inline;"><img id="code_img_opened_a984cc7d-fc3f-4294-bdc0-15a6f301442b" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('a984cc7d-fc3f-4294-bdc0-15a6f301442b',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_a984cc7d-fc3f-4294-bdc0-15a6f301442b" class="cnblogs_code_hide" style="display: none;">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> md5
hash </span>=<span style="color: #000000;"> md5.new()
hash.update(</span><span style="color: #800000;">'</span><span style="color: #800000;">admin</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span> hash.hexdigest()</pre>
</div>
<span class="cnblogs_code_collapse" style="display: inline;">md5-废弃</span></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('37c4f0f2-92cf-4ad8-80d1-6ac51d09e65f')"><img id="code_img_closed_37c4f0f2-92cf-4ad8-80d1-6ac51d09e65f" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: inline;"><img id="code_img_opened_37c4f0f2-92cf-4ad8-80d1-6ac51d09e65f" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('37c4f0f2-92cf-4ad8-80d1-6ac51d09e65f',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_37c4f0f2-92cf-4ad8-80d1-6ac51d09e65f" class="cnblogs_code_hide" style="display: none;">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> sha

hash </span>=<span style="color: #000000;"> sha.new()
hash.update(</span><span style="color: #800000;">'</span><span style="color: #800000;">admin</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span> hash.hexdigest()</pre>
</div>
<span class="cnblogs_code_collapse" style="display: inline;">sha-废弃</span></div>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_42831" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div><div class="line number28 index27 alt1">28</div><div class="line number29 index28 alt2">29</div><div class="line number30 index29 alt1">30</div><div class="line number31 index30 alt2">31</div><div class="line number32 index31 alt1">32</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">hashlib</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="python comments"># ######## md5 ########</code></div><div class="line number4 index3 alt1">&nbsp;</div><div class="line number5 index4 alt2"><code class="python functions">hash</code> <code class="python keyword">=</code> <code class="python plain">hashlib.md5()</code></div><div class="line number6 index5 alt1"><code class="python functions">hash</code><code class="python plain">.update(</code><code class="python string">'admin'</code><code class="python plain">)</code></div><div class="line number7 index6 alt2"><code class="python functions">print</code> <code class="python functions">hash</code><code class="python plain">.hexdigest()</code></div><div class="line number8 index7 alt1">&nbsp;</div><div class="line number9 index8 alt2"><code class="python comments"># ######## sha1 ########</code></div><div class="line number10 index9 alt1">&nbsp;</div><div class="line number11 index10 alt2"><code class="python functions">hash</code> <code class="python keyword">=</code> <code class="python plain">hashlib.sha1()</code></div><div class="line number12 index11 alt1"><code class="python functions">hash</code><code class="python plain">.update(</code><code class="python string">'admin'</code><code class="python plain">)</code></div><div class="line number13 index12 alt2"><code class="python functions">print</code> <code class="python functions">hash</code><code class="python plain">.hexdigest()</code></div><div class="line number14 index13 alt1">&nbsp;</div><div class="line number15 index14 alt2"><code class="python comments"># ######## sha256 ########</code></div><div class="line number16 index15 alt1">&nbsp;</div><div class="line number17 index16 alt2"><code class="python functions">hash</code> <code class="python keyword">=</code> <code class="python plain">hashlib.sha256()</code></div><div class="line number18 index17 alt1"><code class="python functions">hash</code><code class="python plain">.update(</code><code class="python string">'admin'</code><code class="python plain">)</code></div><div class="line number19 index18 alt2"><code class="python functions">print</code> <code class="python functions">hash</code><code class="python plain">.hexdigest()</code></div><div class="line number20 index19 alt1">&nbsp;</div><div class="line number21 index20 alt2">&nbsp;</div><div class="line number22 index21 alt1"><code class="python comments"># ######## sha384 ########</code></div><div class="line number23 index22 alt2">&nbsp;</div><div class="line number24 index23 alt1"><code class="python functions">hash</code> <code class="python keyword">=</code> <code class="python plain">hashlib.sha384()</code></div><div class="line number25 index24 alt2"><code class="python functions">hash</code><code class="python plain">.update(</code><code class="python string">'admin'</code><code class="python plain">)</code></div><div class="line number26 index25 alt1"><code class="python functions">print</code> <code class="python functions">hash</code><code class="python plain">.hexdigest()</code></div><div class="line number27 index26 alt2">&nbsp;</div><div class="line number28 index27 alt1"><code class="python comments"># ######## sha512 ########</code></div><div class="line number29 index28 alt2">&nbsp;</div><div class="line number30 index29 alt1"><code class="python functions">hash</code> <code class="python keyword">=</code> <code class="python plain">hashlib.sha512()</code></div><div class="line number31 index30 alt2"><code class="python functions">hash</code><code class="python plain">.update(</code><code class="python string">'admin'</code><code class="python plain">)</code></div><div class="line number32 index31 alt1"><code class="python functions">print</code> <code class="python functions">hash</code><code class="python plain">.hexdigest()</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_631222" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">hashlib</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="python comments"># ######## md5 ########</code></div><div class="line number4 index3 alt1">&nbsp;</div><div class="line number5 index4 alt2"><code class="python functions">hash</code> <code class="python keyword">=</code> <code class="python plain">hashlib.md5(</code><code class="python string">'898oaFs09f'</code><code class="python plain">)</code></div><div class="line number6 index5 alt1"><code class="python functions">hash</code><code class="python plain">.update(</code><code class="python string">'admin'</code><code class="python plain">)</code></div><div class="line number7 index6 alt2"><code class="python functions">print</code> <code class="python functions">hash</code><code class="python plain">.hexdigest()</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>还不够吊?python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_620128" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">hmac</code></div><div class="line number2 index1 alt1"><code class="python plain">h </code><code class="python keyword">=</code> <code class="python plain">hmac.new(</code><code class="python string">'wueiqi'</code><code class="python plain">)</code></div><div class="line number3 index2 alt2"><code class="python plain">h.update(</code><code class="python string">'hellowo'</code><code class="python plain">)</code></div><div class="line number4 index3 alt1"><code class="python functions">print</code> <code class="python plain">h.hexdigest()</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>不能再牛逼了!!!</p>
<p><span style="font-size: 18px;"><strong>四、json 和&nbsp;pickle&nbsp;</strong></span></p>
<p>用于序列化的两个模块</p>
<ul>
<li>json,用于字符串 和 python数据类型间进行转换</li>
<li>pickle,用于python特有的类型 和 python的数据类型间进行转换</li>
</ul>
<p>Json模块提供了四个功能:dumps、dump、loads、load</p>
<p>pickle模块提供了四个功能:dumps、dump、loads、load</p>
<p><img src="https://images2015.cnblogs.com/blog/425762/201511/425762-20151114231017087-842020084.png" alt="" width="472" height="381"></p>
<p><span style="font-size: 18px;"><strong>五、执行系统命令&nbsp;</strong></span></p>
<p>可以执行shell命令的相关模块和函数有:</p>
<ul>
<li>os.system</li>
<li>os.spawn*</li>
<li>os.popen* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;--废弃</li>
<li>popen2.* &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --废弃</li>
<li>commands.* &nbsp; &nbsp; &nbsp;--废弃,3.x中被移除</li>
</ul>
<div class="cnblogs_code" onclick="cnblogs_code_show('a8f09697-f1df-4a07-ac55-21292319df2d')"><img id="code_img_closed_a8f09697-f1df-4a07-ac55-21292319df2d" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt="" style="display: none;"><img id="code_img_opened_a8f09697-f1df-4a07-ac55-21292319df2d" class="code_img_opened" style="" onclick="cnblogs_code_hide('a8f09697-f1df-4a07-ac55-21292319df2d',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_a8f09697-f1df-4a07-ac55-21292319df2d" class="cnblogs_code_hide" style="display: block;">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> commands

result </span>= commands.getoutput(<span style="color: #800000;">'</span><span style="color: #800000;">cmd</span><span style="color: #800000;">'</span><span style="color: #000000;">)
result </span>= commands.getstatus(<span style="color: #800000;">'</span><span style="color: #800000;">cmd</span><span style="color: #800000;">'</span><span style="color: #000000;">)
result </span>= commands.getstatusoutput(<span style="color: #800000;">'</span><span style="color: #800000;">cmd</span><span style="color: #800000;">'</span>)</pre>
</div>
<span class="cnblogs_code_collapse" style="display: none;">commands</span></div>
<p>以上执行shell命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了更丰富的功能。</p>
<p><strong>call&nbsp;</strong></p>
<p><span style="color: #888888;">执行命令,返回状态码</span></p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_114913" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">ret </code><code class="python keyword">=</code> <code class="python plain">subprocess.call([</code><code class="python string">"ls"</code><code class="python plain">, </code><code class="python string">"-l"</code><code class="python plain">], shell</code><code class="python keyword">=</code><code class="python color1">False</code><code class="python plain">)</code></div><div class="line number2 index1 alt1"><code class="python plain">ret </code><code class="python keyword">=</code> <code class="python plain">subprocess.call(</code><code class="python string">"ls -l"</code><code class="python plain">, shell</code><code class="python keyword">=</code><code class="python color1">True</code><code class="python plain">)</code></div></div></td></tr></tbody></table></div></div>
</div>
<p><span style="color: #888888;">shell = True ,允许 shell 命令是字符串形式</span></p>
<p><strong>check_call</strong></p>
<p><span style="color: #888888;">执行命令,如果执行状态码是 0 ,则返回0,否则抛异常</span></p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_477062" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">subprocess.check_call([</code><code class="python string">"ls"</code><code class="python plain">, </code><code class="python string">"-l"</code><code class="python plain">])</code></div><div class="line number2 index1 alt1"><code class="python plain">subprocess.check_call(</code><code class="python string">"exit 1"</code><code class="python plain">, shell</code><code class="python keyword">=</code><code class="python color1">True</code><code class="python plain">)</code></div></div></td></tr></tbody></table></div></div>
</div>
<p><strong>check_output</strong></p>
<p><span style="color: #888888;">执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常</span></p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_951562" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">subprocess.check_output([</code><code class="python string">"echo"</code><code class="python plain">, </code><code class="python string">"Hello World!"</code><code class="python plain">])</code></div><div class="line number2 index1 alt1"><code class="python plain">subprocess.check_output(</code><code class="python string">"exit 1"</code><code class="python plain">, shell</code><code class="python keyword">=</code><code class="python color1">True</code><code class="python plain">)</code></div></div></td></tr></tbody></table></div></div>
</div>
<p><strong>subprocess.Popen(...)</strong></p>
<p><span style="color: #888888;">用于执行复杂的系统命令</span></p>
<p><span style="color: #888888;">参数:</span></p>
<ul>
<li><span style="color: #888888;">args:shell命令,可以是字符串或者序列类型(如:list,元组)</span></li>
<li><span style="color: #888888;">bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲</span></li>
<li><span style="color: #888888;">stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄</span></li>
<li><span style="color: #888888;">preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用</span></li>
<li><span style="color: #888888;">close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。</span><br><span style="color: #888888;">所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。</span></li>
<li><span style="color: #888888;">shell:同上</span></li>
<li><span style="color: #888888;">cwd:用于设置子进程的当前目录</span></li>
<li><span style="color: #888888;">env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。</span></li>
<li><span style="color: #888888;">universal_newlines:不同系统的换行符不同,True -&gt; 同意使用 \n</span></li>
<li><span style="color: #888888;">startupinfo与createionflags只在windows下有效</span><br><span style="color: #888888;">将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等</span></li>


</ul>
<div class="cnblogs_code" onclick="cnblogs_code_show('975aff8d-37b0-4d35-99e0-c5d185ef6755')"><img id="code_img_closed_975aff8d-37b0-4d35-99e0-c5d185ef6755" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_975aff8d-37b0-4d35-99e0-c5d185ef6755" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('975aff8d-37b0-4d35-99e0-c5d185ef6755',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_975aff8d-37b0-4d35-99e0-c5d185ef6755" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> subprocess
ret1 </span>= subprocess.Popen([<span style="color: #800000;">"</span><span style="color: #800000;">mkdir</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">t1</span><span style="color: #800000;">"</span><span style="color: #000000;">])
ret2 </span>= subprocess.Popen(<span style="color: #800000;">"</span><span style="color: #800000;">mkdir t2</span><span style="color: #800000;">"</span>, shell=True)</pre>
</div>
<span class="cnblogs_code_collapse">执行普通命令</span></div>
<p><span style="color: #888888;">终端输入的命令分为两种:</span></p>
<ul>
<li><span style="color: #888888;">输入即可得到输出,如:ifconfig</span></li>
<li><span style="color: #888888;">输入进行某环境,依赖再输入,如:python</span></li>
</ul>
<div class="cnblogs_code" onclick="cnblogs_code_show('aca7cea1-4c7d-4ad6-a66b-18fe27615578')"><img id="code_img_closed_aca7cea1-4c7d-4ad6-a66b-18fe27615578" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_aca7cea1-4c7d-4ad6-a66b-18fe27615578" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('aca7cea1-4c7d-4ad6-a66b-18fe27615578',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_aca7cea1-4c7d-4ad6-a66b-18fe27615578" class="cnblogs_code_hide">
<pre><span style="color: #000000;">import subprocess

obj </span>= subprocess.Popen(<span style="color: #800000;">"</span><span style="color: #800000;">mkdir t3</span><span style="color: #800000;">"</span>, shell=True, cwd=<span style="color: #800000;">'</span><span style="color: #800000;">/home/dev</span><span style="color: #800000;">'</span>,)</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('a7371cc9-f428-4d2e-997f-cf45000ca43e')"><img id="code_img_closed_a7371cc9-f428-4d2e-997f-cf45000ca43e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_a7371cc9-f428-4d2e-997f-cf45000ca43e" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('a7371cc9-f428-4d2e-997f-cf45000ca43e',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_a7371cc9-f428-4d2e-997f-cf45000ca43e" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> subprocess

obj </span>= subprocess.Popen([<span style="color: #800000;">"</span><span style="color: #800000;">python</span><span style="color: #800000;">"</span>], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=<span style="color: #000000;">subprocess.PIPE)
obj.stdin.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">print 1 \n </span><span style="color: #800000;">'</span><span style="color: #000000;">)
obj.stdin.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">print 2 \n </span><span style="color: #800000;">'</span><span style="color: #000000;">)
obj.stdin.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">print 3 \n </span><span style="color: #800000;">'</span><span style="color: #000000;">)
obj.stdin.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">print 4 \n </span><span style="color: #800000;">'</span><span style="color: #000000;">)
obj.stdin.close()

cmd_out </span>=<span style="color: #000000;"> obj.stdout.read()
obj.stdout.close()
cmd_error </span>=<span style="color: #000000;"> obj.stderr.read()
obj.stderr.close()

</span><span style="color: #0000ff;">print</span><span style="color: #000000;"> cmd_out
</span><span style="color: #0000ff;">print</span> cmd_error</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('ce289ce1-0a78-4cae-96ec-292f34aa1b8c')"><img id="code_img_closed_ce289ce1-0a78-4cae-96ec-292f34aa1b8c" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_ce289ce1-0a78-4cae-96ec-292f34aa1b8c" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('ce289ce1-0a78-4cae-96ec-292f34aa1b8c',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_ce289ce1-0a78-4cae-96ec-292f34aa1b8c" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> subprocess

obj </span>= subprocess.Popen([<span style="color: #800000;">"</span><span style="color: #800000;">python</span><span style="color: #800000;">"</span>], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=<span style="color: #000000;">subprocess.PIPE)
obj.stdin.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">print 1 \n </span><span style="color: #800000;">'</span><span style="color: #000000;">)
obj.stdin.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">print 2 \n </span><span style="color: #800000;">'</span><span style="color: #000000;">)
obj.stdin.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">print 3 \n </span><span style="color: #800000;">'</span><span style="color: #000000;">)
obj.stdin.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">print 4 \n </span><span style="color: #800000;">'</span><span style="color: #000000;">)

out_error_list </span>=<span style="color: #000000;"> obj.communicate()
</span><span style="color: #0000ff;">print</span> out_error_list</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('9976c0f5-f5c3-4c81-bc5f-38ca41bd8822')"><img id="code_img_closed_9976c0f5-f5c3-4c81-bc5f-38ca41bd8822" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_9976c0f5-f5c3-4c81-bc5f-38ca41bd8822" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('9976c0f5-f5c3-4c81-bc5f-38ca41bd8822',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_9976c0f5-f5c3-4c81-bc5f-38ca41bd8822" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> subprocess

obj </span>= subprocess.Popen([<span style="color: #800000;">"</span><span style="color: #800000;">python</span><span style="color: #800000;">"</span>], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=<span style="color: #000000;">subprocess.PIPE)
out_error_list </span>= obj.communicate(<span style="color: #800000;">'</span><span style="color: #800000;">print "hello"</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span> out_error_list</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>更多<a href="https://docs.python.org/2/library/subprocess.html?highlight=subprocess#frequently-used-arguments" target="_blank">猛击这里</a></p>
<div class="page" title="Page 3">
<div class="section">
<div class="layoutArea">
<div class="column">
<div class="page" title="Page 3">
<div class="section">
<div class="layoutArea">
<div class="column">
<div class="page" title="Page 3">
<div class="section">
<div class="layoutArea">
<div class="column">
<div class="page" title="Page 3">
<div class="section">
<div class="layoutArea">
<div class="column">
<p><strong><span style="font-size: 18px;">六、shutil</span></strong></p>
<p>高级的 文件、文件夹、压缩包 处理模块</p>
<p><strong>shutil.copyfileobj(fsrc, fdst[, length])</strong><br> <span style="color: #888888;">将文件内容拷贝到另一个文件中,可以部分内容</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('3068a95a-bec4-4b4f-9ea4-3367b7e18baa')"><img id="code_img_closed_3068a95a-bec4-4b4f-9ea4-3367b7e18baa" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_3068a95a-bec4-4b4f-9ea4-3367b7e18baa" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('3068a95a-bec4-4b4f-9ea4-3367b7e18baa',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_3068a95a-bec4-4b4f-9ea4-3367b7e18baa" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span> copyfileobj(fsrc, fdst, length=16*1024<span style="color: #000000;">):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">copy data from file-like object fsrc to file-like object fdst</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">while</span> 1<span style="color: #000000;">:
buf </span>=<span style="color: #000000;"> fsrc.read(length)
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> buf:
</span><span style="color: #0000ff;">break</span><span style="color: #000000;">
fdst.write(buf)</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.copyfile(src, dst)</strong><br> <span style="color: #888888;">拷贝文件</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('fe3ecac1-c234-43bc-8d7f-0bcc24a4feb2')"><img id="code_img_closed_fe3ecac1-c234-43bc-8d7f-0bcc24a4feb2" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_fe3ecac1-c234-43bc-8d7f-0bcc24a4feb2" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('fe3ecac1-c234-43bc-8d7f-0bcc24a4feb2',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_fe3ecac1-c234-43bc-8d7f-0bcc24a4feb2" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span><span style="color: #000000;"> copyfile(src, dst):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Copy data from src to dst</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> _samefile(src, dst):
</span><span style="color: #0000ff;">raise</span> Error(<span style="color: #800000;">"</span><span style="color: #800000;">`%s` and `%s` are the same file</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> (src, dst))

</span><span style="color: #0000ff;">for</span> fn <span style="color: #0000ff;">in</span><span style="color: #000000;"> [src, dst]:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
st </span>=<span style="color: #000000;"> os.stat(fn)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> OSError:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> File most likely does not exist</span>
<span style="color: #0000ff;">pass</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> XXX What about other special files? (sockets, devices...)</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> stat.S_ISFIFO(st.st_mode):
</span><span style="color: #0000ff;">raise</span> SpecialFileError(<span style="color: #800000;">"</span><span style="color: #800000;">`%s` is a named pipe</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> fn)

with open(src, </span><span style="color: #800000;">'</span><span style="color: #800000;">rb</span><span style="color: #800000;">'</span><span style="color: #000000;">) as fsrc:
with open(dst, </span><span style="color: #800000;">'</span><span style="color: #800000;">wb</span><span style="color: #800000;">'</span><span style="color: #000000;">) as fdst:
copyfileobj(fsrc, fdst)</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.copymode(src, dst)</strong><br> <span style="color: #888888;">仅拷贝权限。内容、组、用户均不变</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('8b725a52-25d5-4a29-a6e8-0be59607ec06')"><img id="code_img_closed_8b725a52-25d5-4a29-a6e8-0be59607ec06" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_8b725a52-25d5-4a29-a6e8-0be59607ec06" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('8b725a52-25d5-4a29-a6e8-0be59607ec06',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_8b725a52-25d5-4a29-a6e8-0be59607ec06" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span><span style="color: #000000;"> copymode(src, dst):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Copy mode bits from src to dst</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">'</span><span style="color: #800000;">chmod</span><span style="color: #800000;">'</span><span style="color: #000000;">):
st </span>=<span style="color: #000000;"> os.stat(src)
mode </span>=<span style="color: #000000;"> stat.S_IMODE(st.st_mode)
os.chmod(dst, mode)</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.copystat(src, dst)</strong><br> <span style="color: #888888;">拷贝状态的信息,包括:mode bits, atime, mtime, flags</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('e0ddd0cf-e83d-4a49-80ca-ae2bdae666fe')"><img id="code_img_closed_e0ddd0cf-e83d-4a49-80ca-ae2bdae666fe" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_e0ddd0cf-e83d-4a49-80ca-ae2bdae666fe" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('e0ddd0cf-e83d-4a49-80ca-ae2bdae666fe',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_e0ddd0cf-e83d-4a49-80ca-ae2bdae666fe" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span><span style="color: #000000;"> copystat(src, dst):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Copy all stat info (mode bits, atime, mtime, flags) from src to dst</span><span style="color: #800000;">"""</span><span style="color: #000000;">
st </span>=<span style="color: #000000;"> os.stat(src)
mode </span>=<span style="color: #000000;"> stat.S_IMODE(st.st_mode)
</span><span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">'</span><span style="color: #800000;">utime</span><span style="color: #800000;">'</span><span style="color: #000000;">):
os.utime(dst, (st.st_atime, st.st_mtime))
</span><span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">'</span><span style="color: #800000;">chmod</span><span style="color: #800000;">'</span><span style="color: #000000;">):
os.chmod(dst, mode)
</span><span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">'</span><span style="color: #800000;">chflags</span><span style="color: #800000;">'</span>) <span style="color: #0000ff;">and</span> hasattr(st, <span style="color: #800000;">'</span><span style="color: #800000;">st_flags</span><span style="color: #800000;">'</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
os.chflags(dst, st.st_flags)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> OSError, why:
</span><span style="color: #0000ff;">for</span> err <span style="color: #0000ff;">in</span> <span style="color: #800000;">'</span><span style="color: #800000;">EOPNOTSUPP</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">ENOTSUP</span><span style="color: #800000;">'</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> hasattr(errno, err) <span style="color: #0000ff;">and</span> why.errno ==<span style="color: #000000;"> getattr(errno, err):
</span><span style="color: #0000ff;">break</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.copy(src, dst)</strong><br> <span style="color: #888888;">拷贝文件和权限</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('71c1fff6-0989-4215-a4a0-c169f01804ed')"><img id="code_img_closed_71c1fff6-0989-4215-a4a0-c169f01804ed" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_71c1fff6-0989-4215-a4a0-c169f01804ed" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('71c1fff6-0989-4215-a4a0-c169f01804ed',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_71c1fff6-0989-4215-a4a0-c169f01804ed" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span><span style="color: #000000;"> copy(src, dst):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Copy data and mode bits ("cp src dst").

The destination may be a directory.

</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.isdir(dst):
dst </span>=<span style="color: #000000;"> os.path.join(dst, os.path.basename(src))
copyfile(src, dst)
copymode(src, dst)</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.copy2(src, dst)</strong><br> <span style="color: #888888;">拷贝文件和状态信息</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('0ab0f14b-5096-42e6-9615-3fae14bd2b97')"><img id="code_img_closed_0ab0f14b-5096-42e6-9615-3fae14bd2b97" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_0ab0f14b-5096-42e6-9615-3fae14bd2b97" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('0ab0f14b-5096-42e6-9615-3fae14bd2b97',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_0ab0f14b-5096-42e6-9615-3fae14bd2b97" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span><span style="color: #000000;"> copy2(src, dst):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Copy data and all stat info ("cp -p src dst").

The destination may be a directory.

</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.isdir(dst):
dst </span>=<span style="color: #000000;"> os.path.join(dst, os.path.basename(src))
copyfile(src, dst)
copystat(src, dst)</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.ignore_patterns(*patterns)</strong><br><strong>shutil.copytree(src, dst, symlinks=False, ignore=None)</strong><br> <span style="color: #888888;">递归的去拷贝文件</span></p>
<p><span style="color: #888888;">例如:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('4ffa5c9e-d914-4684-b8d3-91fac93b50b0')"><img id="code_img_closed_4ffa5c9e-d914-4684-b8d3-91fac93b50b0" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_4ffa5c9e-d914-4684-b8d3-91fac93b50b0" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('4ffa5c9e-d914-4684-b8d3-91fac93b50b0',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_4ffa5c9e-d914-4684-b8d3-91fac93b50b0" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span> ignore_patterns(*<span style="color: #000000;">patterns):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Function that can be used as copytree() ignore parameter.

Patterns is a sequence of glob-style patterns
that are used to exclude files</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">def</span><span style="color: #000000;"> _ignore_patterns(path, names):
ignored_names </span>=<span style="color: #000000;"> []
</span><span style="color: #0000ff;">for</span> pattern <span style="color: #0000ff;">in</span><span style="color: #000000;"> patterns:
ignored_names.extend(fnmatch.filter(names, pattern))
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> set(ignored_names)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> _ignore_patterns

</span><span style="color: #0000ff;">def</span> copytree(src, dst, symlinks=False, ignore=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Recursively copy a directory tree using copy2().

The destination directory must not already exist.
If exception(s) occur, an Error is raised with a list of reasons.

If the optional symlinks flag is true, symbolic links in the
source tree result in symbolic links in the destination tree; if
it is false, the contents of the files pointed to by symbolic
links are copied.

The optional ignore argument is a callable. If given, it
is called with the `src` parameter, which is the directory
being visited by copytree(), and `names` which is the list of
`src` contents, as returned by os.listdir():

callable(src, names) -&gt; ignored_names

Since copytree() is called recursively, the callable will be
called once for each directory that is copied. It returns a
list of names relative to the `src` directory that should
not be copied.

XXX Consider this example code rather than the ultimate tool.

</span><span style="color: #800000;">"""</span><span style="color: #000000;">
names </span>=<span style="color: #000000;"> os.listdir(src)
</span><span style="color: #0000ff;">if</span> ignore <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
ignored_names </span>=<span style="color: #000000;"> ignore(src, names)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
ignored_names </span>=<span style="color: #000000;"> set()

os.makedirs(dst)
errors </span>=<span style="color: #000000;"> []
</span><span style="color: #0000ff;">for</span> name <span style="color: #0000ff;">in</span><span style="color: #000000;"> names:
</span><span style="color: #0000ff;">if</span> name <span style="color: #0000ff;">in</span><span style="color: #000000;"> ignored_names:
</span><span style="color: #0000ff;">continue</span><span style="color: #000000;">
srcname </span>=<span style="color: #000000;"> os.path.join(src, name)
dstname </span>=<span style="color: #000000;"> os.path.join(dst, name)
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> symlinks <span style="color: #0000ff;">and</span><span style="color: #000000;"> os.path.islink(srcname):
linkto </span>=<span style="color: #000000;"> os.readlink(srcname)
os.symlink(linkto, dstname)
</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Will raise a SpecialFileError for unsupported file types</span>
<span style="color: #000000;"> copy2(srcname, dstname)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> catch the Error from the recursive copytree so that we can</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> continue with other files</span>
<span style="color: #0000ff;">except</span><span style="color: #000000;"> Error, err:
errors.extend(err.args[0])
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EnvironmentError, why:
errors.append((srcname, dstname, str(why)))
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
copystat(src, dst)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> OSError, why:
</span><span style="color: #0000ff;">if</span> WindowsError <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span> None <span style="color: #0000ff;">and</span><span style="color: #000000;"> isinstance(why, WindowsError):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Copying file access times may fail on Windows</span>
<span style="color: #0000ff;">pass</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
errors.append((src, dst, str(why)))
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> errors:
</span><span style="color: #0000ff;">raise</span> Error, errors</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.rmtree(path[, ignore_errors[, onerror]])</strong><br> <span style="color: #888888;">递归的去删除文件</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('9b27efd9-873b-47b9-af74-af999d89e72b')"><img id="code_img_closed_9b27efd9-873b-47b9-af74-af999d89e72b" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_9b27efd9-873b-47b9-af74-af999d89e72b" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('9b27efd9-873b-47b9-af74-af999d89e72b',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_9b27efd9-873b-47b9-af74-af999d89e72b" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span> rmtree(path, ignore_errors=False, onerror=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Recursively delete a directory tree.

If ignore_errors is set, errors are ignored; otherwise, if onerror
is set, it is called to handle the error with arguments (func,
path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
path is the argument to that function that caused it to fail; and
exc_info is a tuple returned by sys.exc_info(). If ignore_errors
is false and onerror is None, an exception is raised.

</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> ignore_errors:
</span><span style="color: #0000ff;">def</span> onerror(*<span style="color: #000000;">args):
</span><span style="color: #0000ff;">pass</span>
<span style="color: #0000ff;">elif</span> onerror <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">def</span> onerror(*<span style="color: #000000;">args):
</span><span style="color: #0000ff;">raise</span>
<span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.islink(path):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> symlinks to directories are forbidden, see bug #1669</span>
<span style="color: #0000ff;">raise</span> OSError(<span style="color: #800000;">"</span><span style="color: #800000;">Cannot call rmtree on a symbolic link</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> OSError:
onerror(os.path.islink, path, sys.exc_info())
</span><span style="color: #008000;">#</span><span style="color: #008000;"> can't continue even if onerror hook returns</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;">
names </span>=<span style="color: #000000;"> []
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
names </span>=<span style="color: #000000;"> os.listdir(path)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> os.error, err:
onerror(os.listdir, path, sys.exc_info())
</span><span style="color: #0000ff;">for</span> name <span style="color: #0000ff;">in</span><span style="color: #000000;"> names:
fullname </span>=<span style="color: #000000;"> os.path.join(path, name)
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
mode </span>=<span style="color: #000000;"> os.lstat(fullname).st_mode
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> os.error:
mode </span>=<span style="color: #000000;"> 0
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> stat.S_ISDIR(mode):
rmtree(fullname, ignore_errors, onerror)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
os.remove(fullname)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> os.error, err:
onerror(os.remove, fullname, sys.exc_info())
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
os.rmdir(path)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> os.error:
onerror(os.rmdir, path, sys.exc_info())</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.move(src, dst)</strong><br> <span style="color: #888888;">递归的去移动文件</span></p>
<div class="cnblogs_code" onclick="cnblogs_code_show('435fbc8f-18ec-4cc6-bedb-094e849a3c24')"><img id="code_img_closed_435fbc8f-18ec-4cc6-bedb-094e849a3c24" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_435fbc8f-18ec-4cc6-bedb-094e849a3c24" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('435fbc8f-18ec-4cc6-bedb-094e849a3c24',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_435fbc8f-18ec-4cc6-bedb-094e849a3c24" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span><span style="color: #000000;"> move(src, dst):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Recursively move a file or directory to another location. This is
similar to the Unix "mv" command.

If the destination is a directory or a symlink to a directory, the source
is moved inside the directory. The destination path must not already
exist.

If the destination already exists but is not a directory, it may be
overwritten depending on os.rename() semantics.

If the destination is on our current filesystem, then rename() is used.
Otherwise, src is copied to the destination and then removed.
A lot more could be done here... A look at a mv.c shows a lot of
the issues this implementation glosses over.

</span><span style="color: #800000;">"""</span><span style="color: #000000;">
real_dst </span>=<span style="color: #000000;"> dst
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.isdir(dst):
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> _samefile(src, dst):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> We might be on a case insensitive filesystem,</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> perform the rename anyway.</span>
<span style="color: #000000;"> os.rename(src, dst)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;">

real_dst </span>=<span style="color: #000000;"> os.path.join(dst, _basename(src))
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.exists(real_dst):
</span><span style="color: #0000ff;">raise</span> Error, <span style="color: #800000;">"</span><span style="color: #800000;">Destination path '%s' already exists</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> real_dst
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
os.rename(src, real_dst)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> OSError:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.isdir(src):
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> _destinsrc(src, dst):
</span><span style="color: #0000ff;">raise</span> Error, <span style="color: #800000;">"</span><span style="color: #800000;">Cannot move a directory '%s' into itself '%s'.</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> (src, dst)
copytree(src, real_dst, symlinks</span>=<span style="color: #000000;">True)
rmtree(src)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
copy2(src, real_dst)
os.unlink(src)</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p><strong>shutil.make_archive(base_name, format,...)</strong></p>
<p><span style="color: #888888;">创建压缩包并返回文件路径,例如:zip、tar</span></p>
<ul>
<li><span style="color: #888888;">base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,</span><br><span style="color: #888888;"><span style="line-height: 1.5;">如:www &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=&gt;保存至当前路径<br></span><span style="line-height: 1.5;">如:/Users/wupeiqi/www =&gt;保存至/Users/wupeiqi/</span></span></li>
<li><span style="color: #888888;">format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”</span></li>
<li><span style="color: #888888;">root_dir: 要压缩的文件夹路径(默认当前目录)</span></li>
<li><span style="color: #888888;">owner: 用户,默认当前用户</span></li>
<li><span style="color: #888888;">group: 组,默认当前组</span></li>
<li><span style="color: #888888;">logger: 用于记录日志,通常是logging.Logger对象</span></li>

</ul>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_379218" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python comments">#将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="python keyword">import</code> <code class="python plain">shutil</code></div><div class="line number4 index3 alt1"><code class="python plain">ret </code><code class="python keyword">=</code> <code class="python plain">shutil.make_archive(</code><code class="python string">"wwwwwwwwww"</code><code class="python plain">, </code><code class="python string">'gztar'</code><code class="python plain">, root_dir</code><code class="python keyword">=</code><code class="python string">'/Users/wupeiqi/Downloads/test'</code><code class="python plain">)</code></div><div class="line number5 index4 alt2">&nbsp;</div><div class="line number6 index5 alt1">&nbsp;</div><div class="line number7 index6 alt2"><code class="python comments">#将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录</code></div><div class="line number8 index7 alt1"><code class="python keyword">import</code> <code class="python plain">shutil</code></div><div class="line number9 index8 alt2"><code class="python plain">ret </code><code class="python keyword">=</code> <code class="python plain">shutil.make_archive(</code><code class="python string">"/Users/wupeiqi/wwwwwwwwww"</code><code class="python plain">, </code><code class="python string">'gztar'</code><code class="python plain">, root_dir</code><code class="python keyword">=</code><code class="python string">'/Users/wupeiqi/Downloads/test'</code><code class="python plain">)</code></div></div></td></tr></tbody></table></div></div>
</div>
<div class="cnblogs_code" onclick="cnblogs_code_show('23280a1e-e26c-4107-a218-872860ac85b9')"><img id="code_img_closed_23280a1e-e26c-4107-a218-872860ac85b9" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_23280a1e-e26c-4107-a218-872860ac85b9" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('23280a1e-e26c-4107-a218-872860ac85b9',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_23280a1e-e26c-4107-a218-872860ac85b9" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">def</span> make_archive(base_name, format, root_dir=None, base_dir=None, verbose=<span style="color: #000000;">0,
dry_run</span>=0, owner=None, group=None, logger=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Create an archive file (eg. zip or tar).

'base_name' is the name of the file to create, minus any format-specific
extension; 'format' is the archive format: one of "zip", "tar", "bztar"
or "gztar".

'root_dir' is a directory that will be the root directory of the
archive; ie. we typically chdir into 'root_dir' before creating the
archive. 'base_dir' is the directory where we start archiving from;
ie. 'base_dir' will be the common prefix of all files and
directories in the archive. 'root_dir' and 'base_dir' both default
to the current directory. Returns the name of the archive file.

'owner' and 'group' are used when creating a tar archive. By default,
uses the current owner and group.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
save_cwd </span>=<span style="color: #000000;"> os.getcwd()
</span><span style="color: #0000ff;">if</span> root_dir <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">if</span> logger <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
logger.debug(</span><span style="color: #800000;">"</span><span style="color: #800000;">changing into '%s'</span><span style="color: #800000;">"</span><span style="color: #000000;">, root_dir)
base_name </span>=<span style="color: #000000;"> os.path.abspath(base_name)
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> dry_run:
os.chdir(root_dir)

</span><span style="color: #0000ff;">if</span> base_dir <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
base_dir </span>=<span style="color: #000000;"> os.curdir

kwargs </span>= {<span style="color: #800000;">'</span><span style="color: #800000;">dry_run</span><span style="color: #800000;">'</span>: dry_run, <span style="color: #800000;">'</span><span style="color: #800000;">logger</span><span style="color: #800000;">'</span><span style="color: #000000;">: logger}

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
format_info </span>=<span style="color: #000000;"> _ARCHIVE_FORMATS[format]
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> KeyError:
</span><span style="color: #0000ff;">raise</span> ValueError, <span style="color: #800000;">"</span><span style="color: #800000;">unknown archive format '%s'</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> format

func </span>=<span style="color: #000000;"> format_info[0]
</span><span style="color: #0000ff;">for</span> arg, val <span style="color: #0000ff;">in</span> format_info[1<span style="color: #000000;">]:
kwargs[arg] </span>=<span style="color: #000000;"> val

</span><span style="color: #0000ff;">if</span> format != <span style="color: #800000;">'</span><span style="color: #800000;">zip</span><span style="color: #800000;">'</span><span style="color: #000000;">:
kwargs[</span><span style="color: #800000;">'</span><span style="color: #800000;">owner</span><span style="color: #800000;">'</span>] =<span style="color: #000000;"> owner
kwargs[</span><span style="color: #800000;">'</span><span style="color: #800000;">group</span><span style="color: #800000;">'</span>] =<span style="color: #000000;"> group

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
filename </span>= func(base_name, base_dir, **<span style="color: #000000;">kwargs)
</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> root_dir <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">if</span> logger <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
logger.debug(</span><span style="color: #800000;">"</span><span style="color: #800000;">changing back to '%s'</span><span style="color: #800000;">"</span><span style="color: #000000;">, save_cwd)
os.chdir(save_cwd)

</span><span style="color: #0000ff;">return</span> filename</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:</p>
<div class="cnblogs_code" onclick="cnblogs_code_show('39689b83-db05-4a45-a165-b39af52823d6')"><img id="code_img_closed_39689b83-db05-4a45-a165-b39af52823d6" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_39689b83-db05-4a45-a165-b39af52823d6" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('39689b83-db05-4a45-a165-b39af52823d6',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_39689b83-db05-4a45-a165-b39af52823d6" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> zipfile

</span><span style="color: #008000;">#</span><span style="color: #008000;"> 压缩</span>
z = zipfile.ZipFile(<span style="color: #800000;">'</span><span style="color: #800000;">laxi.zip</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">w</span><span style="color: #800000;">'</span><span style="color: #000000;">)
z.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">a.log</span><span style="color: #800000;">'</span><span style="color: #000000;">)
z.write(</span><span style="color: #800000;">'</span><span style="color: #800000;">data.data</span><span style="color: #800000;">'</span><span style="color: #000000;">)
z.close()

</span><span style="color: #008000;">#</span><span style="color: #008000;"> 解压</span>
z = zipfile.ZipFile(<span style="color: #800000;">'</span><span style="color: #800000;">laxi.zip</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">r</span><span style="color: #800000;">'</span><span style="color: #000000;">)
z.extractall()
z.close()</span></pre>
</div>
<span class="cnblogs_code_collapse">zipfile 压缩解压</span></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('a7d089e2-7147-416c-9b25-ba64f1f45745')"><img id="code_img_closed_a7d089e2-7147-416c-9b25-ba64f1f45745" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_a7d089e2-7147-416c-9b25-ba64f1f45745" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('a7d089e2-7147-416c-9b25-ba64f1f45745',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_a7d089e2-7147-416c-9b25-ba64f1f45745" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> tarfile

</span><span style="color: #008000;">#</span><span style="color: #008000;"> 压缩</span>
tar = tarfile.open(<span style="color: #800000;">'</span><span style="color: #800000;">your.tar</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">w</span><span style="color: #800000;">'</span><span style="color: #000000;">)
tar.add(</span><span style="color: #800000;">'</span><span style="color: #800000;">/Users/wupeiqi/PycharmProjects/bbs2.zip</span><span style="color: #800000;">'</span>, arcname=<span style="color: #800000;">'</span><span style="color: #800000;">bbs2.zip</span><span style="color: #800000;">'</span><span style="color: #000000;">)
tar.add(</span><span style="color: #800000;">'</span><span style="color: #800000;">/Users/wupeiqi/PycharmProjects/cmdb.zip</span><span style="color: #800000;">'</span>, arcname=<span style="color: #800000;">'</span><span style="color: #800000;">cmdb.zip</span><span style="color: #800000;">'</span><span style="color: #000000;">)
tar.close()

</span><span style="color: #008000;">#</span><span style="color: #008000;"> 解压</span>
tar = tarfile.open(<span style="color: #800000;">'</span><span style="color: #800000;">your.tar</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">r</span><span style="color: #800000;">'</span><span style="color: #000000;">)
tar.extractall() </span><span style="color: #008000;">#</span><span style="color: #008000;"> 可设置解压地址</span>
tar.close()</pre>
</div>
<span class="cnblogs_code_collapse">tarfile 压缩解压</span></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('2a06489e-fbd2-40ba-86e4-85e5513f1199')"><img id="code_img_closed_2a06489e-fbd2-40ba-86e4-85e5513f1199" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_2a06489e-fbd2-40ba-86e4-85e5513f1199" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('2a06489e-fbd2-40ba-86e4-85e5513f1199',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_2a06489e-fbd2-40ba-86e4-85e5513f1199" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> ZipFile(object):
</span><span style="color: #800000;">"""</span><span style="color: #800000;"> Class with methods to open, read, write, close, list zip files.

z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False)

file: Either the path to the file, or a file-like object.
If it is a path, the file will be opened and closed by ZipFile.
mode: The mode can be either read "r", write "w" or append "a".
compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib).
allowZip64: if True ZipFile will create files with ZIP64 extensions when
needed, otherwise it will raise an exception when this would
be necessary.

</span><span style="color: #800000;">"""</span><span style="color: #000000;">

fp </span>= None <span style="color: #008000;">#</span><span style="color: #008000;"> Set here since __del__ checks it</span>

<span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span>(self, file, mode=<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, compression=ZIP_STORED, allowZip64=<span style="color: #000000;">False):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Open the ZIP file with mode read "r", write "w" or append "a".</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> mode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">raise</span> RuntimeError(<span style="color: #800000;">'</span><span style="color: #800000;">ZipFile() requires mode "r", "w", or "a"</span><span style="color: #800000;">'</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">if</span> compression ==<span style="color: #000000;"> ZIP_STORED:
</span><span style="color: #0000ff;">pass</span>
<span style="color: #0000ff;">elif</span> compression ==<span style="color: #000000;"> ZIP_DEFLATED:
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> zlib:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> RuntimeError,\
</span><span style="color: #800000;">"</span><span style="color: #800000;">Compression requires the (missing) zlib module</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span> RuntimeError, <span style="color: #800000;">"</span><span style="color: #800000;">That compression method is not supported</span><span style="color: #800000;">"</span><span style="color: #000000;">

self._allowZip64 </span>=<span style="color: #000000;"> allowZip64
self._didModify </span>=<span style="color: #000000;"> False
self.debug </span>= 0 <span style="color: #008000;">#</span><span style="color: #008000;"> Level of printing: 0 through 3</span>
self.NameToInfo = {} <span style="color: #008000;">#</span><span style="color: #008000;"> Find file info given name</span>
self.filelist = [] <span style="color: #008000;">#</span><span style="color: #008000;"> List of ZipInfo instances for archive</span>
self.compression = compression <span style="color: #008000;">#</span><span style="color: #008000;"> Method of compression</span>
self.mode = key = mode.replace(<span style="color: #800000;">'</span><span style="color: #800000;">b</span><span style="color: #800000;">'</span>, <span style="color: #800000;">''</span><span style="color: #000000;">)[0]
self.pwd </span>=<span style="color: #000000;"> None
self._comment </span>= <span style="color: #800000;">''</span>

<span style="color: #008000;">#</span><span style="color: #008000;"> Check if we were passed a file-like object</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> isinstance(file, basestring):
self._filePassed </span>=<span style="color: #000000;"> 0
self.filename </span>=<span style="color: #000000;"> file
modeDict </span>= {<span style="color: #800000;">'</span><span style="color: #800000;">r</span><span style="color: #800000;">'</span> : <span style="color: #800000;">'</span><span style="color: #800000;">rb</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">w</span><span style="color: #800000;">'</span>: <span style="color: #800000;">'</span><span style="color: #800000;">wb</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">a</span><span style="color: #800000;">'</span> : <span style="color: #800000;">'</span><span style="color: #800000;">r+b</span><span style="color: #800000;">'</span><span style="color: #000000;">}
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
self.fp </span>=<span style="color: #000000;"> open(file, modeDict[mode])
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> IOError:
</span><span style="color: #0000ff;">if</span> mode == <span style="color: #800000;">'</span><span style="color: #800000;">a</span><span style="color: #800000;">'</span><span style="color: #000000;">:
mode </span>= key = <span style="color: #800000;">'</span><span style="color: #800000;">w</span><span style="color: #800000;">'</span><span style="color: #000000;">
self.fp </span>=<span style="color: #000000;"> open(file, modeDict[mode])
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
self._filePassed </span>= 1<span style="color: #000000;">
self.fp </span>=<span style="color: #000000;"> file
self.filename </span>= getattr(file, <span style="color: #800000;">'</span><span style="color: #800000;">name</span><span style="color: #800000;">'</span><span style="color: #000000;">, None)

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> key == <span style="color: #800000;">'</span><span style="color: #800000;">r</span><span style="color: #800000;">'</span><span style="color: #000000;">:
self._RealGetContents()
</span><span style="color: #0000ff;">elif</span> key == <span style="color: #800000;">'</span><span style="color: #800000;">w</span><span style="color: #800000;">'</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> set the modified flag so central directory gets written</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> even if no files are added to the archive</span>
self._didModify =<span style="color: #000000;"> True
</span><span style="color: #0000ff;">elif</span> key == <span style="color: #800000;">'</span><span style="color: #800000;">a</span><span style="color: #800000;">'</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> See if file is a zip file</span>
<span style="color: #000000;"> self._RealGetContents()
</span><span style="color: #008000;">#</span><span style="color: #008000;"> seek to start of directory and overwrite</span>
<span style="color: #000000;"> self.fp.seek(self.start_dir, 0)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> BadZipfile:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> file is not a zip file, just append</span>
self.fp.seek(0, 2<span style="color: #000000;">)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> set the modified flag so central directory gets written</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> even if no files are added to the archive</span>
self._didModify =<span style="color: #000000;"> True
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span> RuntimeError(<span style="color: #800000;">'</span><span style="color: #800000;">Mode must be "r", "w" or "a"</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;">:
fp </span>=<span style="color: #000000;"> self.fp
self.fp </span>=<span style="color: #000000;"> None
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self._filePassed:
fp.close()
</span><span style="color: #0000ff;">raise</span>

<span style="color: #0000ff;">def</span> <span style="color: #800080;">__enter__</span><span style="color: #000000;">(self):
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self

</span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__exit__</span><span style="color: #000000;">(self, type, value, traceback):
self.close()

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> _RealGetContents(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Read in the table of contents for the ZIP file.</span><span style="color: #800000;">"""</span><span style="color: #000000;">
fp </span>=<span style="color: #000000;"> self.fp
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
endrec </span>=<span style="color: #000000;"> _EndRecData(fp)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> IOError:
</span><span style="color: #0000ff;">raise</span> BadZipfile(<span style="color: #800000;">"</span><span style="color: #800000;">File is not a zip file</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> endrec:
</span><span style="color: #0000ff;">raise</span> BadZipfile, <span style="color: #800000;">"</span><span style="color: #800000;">File is not a zip file</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">if</span> self.debug &gt; 1<span style="color: #000000;">:
</span><span style="color: #0000ff;">print</span><span style="color: #000000;"> endrec
size_cd </span>= endrec[_ECD_SIZE] <span style="color: #008000;">#</span><span style="color: #008000;"> bytes in central directory</span>
offset_cd = endrec[_ECD_OFFSET] <span style="color: #008000;">#</span><span style="color: #008000;"> offset of central directory</span>
self._comment = endrec[_ECD_COMMENT] <span style="color: #008000;">#</span><span style="color: #008000;"> archive comment</span>

<span style="color: #008000;">#</span><span style="color: #008000;"> "concat" is zero, unless zip was concatenated to another file</span>
concat = endrec[_ECD_LOCATION] - size_cd -<span style="color: #000000;"> offset_cd
</span><span style="color: #0000ff;">if</span> endrec[_ECD_SIGNATURE] ==<span style="color: #000000;"> stringEndArchive64:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> If Zip64 extension structures are present, account for them</span>
concat -= (sizeEndCentDir64 +<span style="color: #000000;"> sizeEndCentDir64Locator)

</span><span style="color: #0000ff;">if</span> self.debug &gt; 2<span style="color: #000000;">:
inferred </span>= concat +<span style="color: #000000;"> offset_cd
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">given, inferred, offset</span><span style="color: #800000;">"</span><span style="color: #000000;">, offset_cd, inferred, concat
</span><span style="color: #008000;">#</span><span style="color: #008000;"> self.start_dir: Position of start of central directory</span>
self.start_dir = offset_cd +<span style="color: #000000;"> concat
fp.seek(self.start_dir, 0)
data </span>=<span style="color: #000000;"> fp.read(size_cd)
fp </span>=<span style="color: #000000;"> cStringIO.StringIO(data)
total </span>=<span style="color: #000000;"> 0
</span><span style="color: #0000ff;">while</span> total &lt;<span style="color: #000000;"> size_cd:
centdir </span>=<span style="color: #000000;"> fp.read(sizeCentralDir)
</span><span style="color: #0000ff;">if</span> len(centdir) !=<span style="color: #000000;"> sizeCentralDir:
</span><span style="color: #0000ff;">raise</span> BadZipfile(<span style="color: #800000;">"</span><span style="color: #800000;">Truncated central directory</span><span style="color: #800000;">"</span><span style="color: #000000;">)
centdir </span>=<span style="color: #000000;"> struct.unpack(structCentralDir, centdir)
</span><span style="color: #0000ff;">if</span> centdir[_CD_SIGNATURE] !=<span style="color: #000000;"> stringCentralDir:
</span><span style="color: #0000ff;">raise</span> BadZipfile(<span style="color: #800000;">"</span><span style="color: #800000;">Bad magic number for central directory</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> self.debug &gt; 2<span style="color: #000000;">:
</span><span style="color: #0000ff;">print</span><span style="color: #000000;"> centdir
filename </span>=<span style="color: #000000;"> fp.read(centdir[_CD_FILENAME_LENGTH])
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Create ZipInfo instance to store file information</span>
x =<span style="color: #000000;"> ZipInfo(filename)
x.extra </span>=<span style="color: #000000;"> fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
x.comment </span>=<span style="color: #000000;"> fp.read(centdir[_CD_COMMENT_LENGTH])
x.header_offset </span>=<span style="color: #000000;"> centdir[_CD_LOCAL_HEADER_OFFSET]
(x.create_version, x.create_system, x.extract_version, x.reserved,
x.flag_bits, x.compress_type, t, d,
x.CRC, x.compress_size, x.file_size) </span>= centdir[1:12<span style="color: #000000;">]
x.volume, x.internal_attr, x.external_attr </span>= centdir[15:18<span style="color: #000000;">]
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Convert date/time code to (year, month, day, hour, min, sec)</span>
x._raw_time =<span style="color: #000000;"> t
x.date_time </span>= ( (d&gt;&gt;9)+1980, (d&gt;&gt;5)&amp;0xF, d&amp;0x1F<span style="color: #000000;">,
t</span>&gt;&gt;11, (t&gt;&gt;5)&amp;0x3F, (t&amp;0x1F) * 2<span style="color: #000000;"> )

x._decodeExtra()
x.header_offset </span>= x.header_offset +<span style="color: #000000;"> concat
x.filename </span>=<span style="color: #000000;"> x._decodeFilename()
self.filelist.append(x)
self.NameToInfo[x.filename] </span>=<span style="color: #000000;"> x

</span><span style="color: #008000;">#</span><span style="color: #008000;"> update total bytes read from central directory</span>
total = (total + sizeCentralDir +<span style="color: #000000;"> centdir[_CD_FILENAME_LENGTH]
</span>+<span style="color: #000000;"> centdir[_CD_EXTRA_FIELD_LENGTH]
</span>+<span style="color: #000000;"> centdir[_CD_COMMENT_LENGTH])

</span><span style="color: #0000ff;">if</span> self.debug &gt; 2<span style="color: #000000;">:
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">total</span><span style="color: #800000;">"</span><span style="color: #000000;">, total


</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> namelist(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return a list of file names in the archive.</span><span style="color: #800000;">"""</span><span style="color: #000000;">
l </span>=<span style="color: #000000;"> []
</span><span style="color: #0000ff;">for</span> data <span style="color: #0000ff;">in</span><span style="color: #000000;"> self.filelist:
l.append(data.filename)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> l

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> infolist(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return a list of class ZipInfo instances for files in the
archive.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;"> self.filelist

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> printdir(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Print a table of contents for the zip file.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">%-46s %19s %12s</span><span style="color: #800000;">"</span> % (<span style="color: #800000;">"</span><span style="color: #800000;">File Name</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">Modified </span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">Size</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">for</span> zinfo <span style="color: #0000ff;">in</span><span style="color: #000000;"> self.filelist:
date </span>= <span style="color: #800000;">"</span><span style="color: #800000;">%d-%02d-%02d %02d:%02d:%02d</span><span style="color: #800000;">"</span> % zinfo.date_time[:6<span style="color: #000000;">]
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">%-46s %s %12d</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> (zinfo.filename, date, zinfo.file_size)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> testzip(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Read all the files and check the CRC.</span><span style="color: #800000;">"""</span><span style="color: #000000;">
chunk_size </span>= 2 ** 20
<span style="color: #0000ff;">for</span> zinfo <span style="color: #0000ff;">in</span><span style="color: #000000;"> self.filelist:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Read by chunks, to avoid an OverflowError or a</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> MemoryError with very large embedded files.</span>
with self.open(zinfo.filename, <span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span><span style="color: #000000;">) as f:
</span><span style="color: #0000ff;">while</span> f.read(chunk_size): <span style="color: #008000;">#</span><span style="color: #008000;"> Check CRC-32</span>
<span style="color: #0000ff;">pass</span>
<span style="color: #0000ff;">except</span><span style="color: #000000;"> BadZipfile:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> zinfo.filename

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> getinfo(self, name):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return the instance of ZipInfo given 'name'.</span><span style="color: #800000;">"""</span><span style="color: #000000;">
info </span>=<span style="color: #000000;"> self.NameToInfo.get(name)
</span><span style="color: #0000ff;">if</span> info <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> KeyError(
</span><span style="color: #800000;">'</span><span style="color: #800000;">There is no item named %r in the archive</span><span style="color: #800000;">'</span> %<span style="color: #000000;"> name)

</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> info

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> setpassword(self, pwd):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Set default password for encrypted files.</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self.pwd </span>=<span style="color: #000000;"> pwd

@property
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> comment(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">The comment text associated with the ZIP file.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;"> self._comment

@comment.setter
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> comment(self, comment):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> check for valid comment length</span>
<span style="color: #0000ff;">if</span> len(comment) &gt;<span style="color: #000000;"> ZIP_MAX_COMMENT:
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> warnings
warnings.warn(</span><span style="color: #800000;">'</span><span style="color: #800000;">Archive comment is too long; truncating to %d bytes</span><span style="color: #800000;">'</span>
% ZIP_MAX_COMMENT, stacklevel=2<span style="color: #000000;">)
comment </span>=<span style="color: #000000;"> comment[:ZIP_MAX_COMMENT]
self._comment </span>=<span style="color: #000000;"> comment
self._didModify </span>=<span style="color: #000000;"> True

</span><span style="color: #0000ff;">def</span> read(self, name, pwd=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return file bytes (as a string) for name.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">return</span> self.open(name, <span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span><span style="color: #000000;">, pwd).read()

</span><span style="color: #0000ff;">def</span> open(self, name, mode=<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, pwd=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return file-like object for 'name'.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> mode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">U</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">rU</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">raise</span> RuntimeError, <span style="color: #800000;">'</span><span style="color: #800000;">open() requires mode "r", "U", or "rU"</span><span style="color: #800000;">'</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self.fp:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> RuntimeError, \
</span><span style="color: #800000;">"</span><span style="color: #800000;">Attempt to read ZIP archive that was already closed</span><span style="color: #800000;">"</span>

<span style="color: #008000;">#</span><span style="color: #008000;"> Only open a new file for instances where we were not</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> given a file object in the constructor</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> self._filePassed:
zef_file </span>=<span style="color: #000000;"> self.fp
should_close </span>=<span style="color: #000000;"> False
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
zef_file </span>= open(self.filename, <span style="color: #800000;">'</span><span style="color: #800000;">rb</span><span style="color: #800000;">'</span><span style="color: #000000;">)
should_close </span>=<span style="color: #000000;"> True

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Make sure we have an info object</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> isinstance(name, ZipInfo):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> 'name' is already an info object</span>
zinfo =<span style="color: #000000;"> name
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Get info object for name</span>
zinfo =<span style="color: #000000;"> self.getinfo(name)

zef_file.seek(zinfo.header_offset, 0)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Skip the file header:</span>
fheader =<span style="color: #000000;"> zef_file.read(sizeFileHeader)
</span><span style="color: #0000ff;">if</span> len(fheader) !=<span style="color: #000000;"> sizeFileHeader:
</span><span style="color: #0000ff;">raise</span> BadZipfile(<span style="color: #800000;">"</span><span style="color: #800000;">Truncated file header</span><span style="color: #800000;">"</span><span style="color: #000000;">)
fheader </span>=<span style="color: #000000;"> struct.unpack(structFileHeader, fheader)
</span><span style="color: #0000ff;">if</span> fheader[_FH_SIGNATURE] !=<span style="color: #000000;"> stringFileHeader:
</span><span style="color: #0000ff;">raise</span> BadZipfile(<span style="color: #800000;">"</span><span style="color: #800000;">Bad magic number for file header</span><span style="color: #800000;">"</span><span style="color: #000000;">)

fname </span>=<span style="color: #000000;"> zef_file.read(fheader[_FH_FILENAME_LENGTH])
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> fheader[_FH_EXTRA_FIELD_LENGTH]:
zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])

</span><span style="color: #0000ff;">if</span> fname !=<span style="color: #000000;"> zinfo.orig_filename:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> BadZipfile, \
</span><span style="color: #800000;">'</span><span style="color: #800000;">File name in directory "%s" and header "%s" differ.</span><span style="color: #800000;">'</span> %<span style="color: #000000;"> (
zinfo.orig_filename, fname)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> check for encrypted flag &amp; handle password</span>
is_encrypted = zinfo.flag_bits &amp; 0x1<span style="color: #000000;">
zd </span>=<span style="color: #000000;"> None
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> is_encrypted:
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> pwd:
pwd </span>=<span style="color: #000000;"> self.pwd
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> pwd:
</span><span style="color: #0000ff;">raise</span> RuntimeError, <span style="color: #800000;">"</span><span style="color: #800000;">File %s is encrypted, </span><span style="color: #800000;">"</span><span style="color: #000000;"> \
</span><span style="color: #800000;">"</span><span style="color: #800000;">password required for extraction</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> name

zd </span>=<span style="color: #000000;"> _ZipDecrypter(pwd)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> The first 12 bytes in the cypher stream is an encryption header</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> used to strengthen the algorithm. The first 11 bytes are</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> completely random, while the 12th contains the MSB of the CRC,</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> or the MSB of the file time depending on the header type</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> and is used to check the correctness of the password.</span>
bytes = zef_file.read(12<span style="color: #000000;">)
h </span>= map(zd, bytes[0:12<span style="color: #000000;">])
</span><span style="color: #0000ff;">if</span> zinfo.flag_bits &amp; 0x8<span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> compare against the file type from extended local headers</span>
check_byte = (zinfo._raw_time &gt;&gt; 8) &amp; 0xff
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> compare against the CRC otherwise</span>
check_byte = (zinfo.CRC &gt;&gt; 24) &amp; 0xff
<span style="color: #0000ff;">if</span> ord(h[11]) !=<span style="color: #000000;"> check_byte:
</span><span style="color: #0000ff;">raise</span> RuntimeError(<span style="color: #800000;">"</span><span style="color: #800000;">Bad password for file</span><span style="color: #800000;">"</span><span style="color: #000000;">, name)

</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ZipExtFile(zef_file, mode, zinfo, zd,
close_fileobj</span>=<span style="color: #000000;">should_close)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> should_close:
zef_file.close()
</span><span style="color: #0000ff;">raise</span>

<span style="color: #0000ff;">def</span> extract(self, member, path=None, pwd=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Extract a member from the archive to the current working directory,
using its full name. Its file information is extracted as accurately
as possible. `member' may be a filename or a ZipInfo object. You can
specify a different directory using `path'.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> isinstance(member, ZipInfo):
member </span>=<span style="color: #000000;"> self.getinfo(member)

</span><span style="color: #0000ff;">if</span> path <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
path </span>=<span style="color: #000000;"> os.getcwd()

</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self._extract_member(member, path, pwd)

</span><span style="color: #0000ff;">def</span> extractall(self, path=None, members=None, pwd=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Extract all members from the archive to the current working
directory. `path' specifies a different directory to extract to.
`members' is optional and must be a subset of the list returned
by namelist().
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> members <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
members </span>=<span style="color: #000000;"> self.namelist()

</span><span style="color: #0000ff;">for</span> zipinfo <span style="color: #0000ff;">in</span><span style="color: #000000;"> members:
self.extract(zipinfo, path, pwd)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> _extract_member(self, member, targetpath, pwd):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Extract the ZipInfo object 'member' to a physical
file on the path targetpath.
</span><span style="color: #800000;">"""</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> build the destination pathname, replacing</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> forward slashes to platform specific separators.</span>
arcname = member.filename.replace(<span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span><span style="color: #000000;">, os.path.sep)

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.altsep:
arcname </span>=<span style="color: #000000;"> arcname.replace(os.path.altsep, os.path.sep)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> interpret absolute pathname as relative, remove drive letter or</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> UNC path, redundant separators, "." and ".." components.</span>
arcname = os.path.splitdrive(arcname)[1<span style="color: #000000;">]
arcname </span>= os.path.sep.join(x <span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span><span style="color: #000000;"> arcname.split(os.path.sep)
</span><span style="color: #0000ff;">if</span> x <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> (<span style="color: #800000;">''</span><span style="color: #000000;">, os.path.curdir, os.path.pardir))
</span><span style="color: #0000ff;">if</span> os.path.sep == <span style="color: #800000;">'</span><span style="color: #800000;">\\</span><span style="color: #800000;">'</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> filter illegal characters on Windows</span>
illegal = <span style="color: #800000;">'</span><span style="color: #800000;">:&lt;&gt;|"?*</span><span style="color: #800000;">'</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> isinstance(arcname, unicode):
table </span>= {ord(c): ord(<span style="color: #800000;">'</span><span style="color: #800000;">_</span><span style="color: #800000;">'</span>) <span style="color: #0000ff;">for</span> c <span style="color: #0000ff;">in</span><span style="color: #000000;"> illegal}
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
table </span>= string.maketrans(illegal, <span style="color: #800000;">'</span><span style="color: #800000;">_</span><span style="color: #800000;">'</span> *<span style="color: #000000;"> len(illegal))
arcname </span>=<span style="color: #000000;"> arcname.translate(table)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> remove trailing dots</span>
arcname = (x.rstrip(<span style="color: #800000;">'</span><span style="color: #800000;">.</span><span style="color: #800000;">'</span>) <span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span><span style="color: #000000;"> arcname.split(os.path.sep))
arcname </span>= os.path.sep.join(x <span style="color: #0000ff;">for</span> x <span style="color: #0000ff;">in</span> arcname <span style="color: #0000ff;">if</span><span style="color: #000000;"> x)

targetpath </span>=<span style="color: #000000;"> os.path.join(targetpath, arcname)
targetpath </span>=<span style="color: #000000;"> os.path.normpath(targetpath)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Create all upper directories if necessary.</span>
upperdirs =<span style="color: #000000;"> os.path.dirname(targetpath)
</span><span style="color: #0000ff;">if</span> upperdirs <span style="color: #0000ff;">and</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> os.path.exists(upperdirs):
os.makedirs(upperdirs)

</span><span style="color: #0000ff;">if</span> member.filename[-1] == <span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> os.path.isdir(targetpath):
os.mkdir(targetpath)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> targetpath

with self.open(member, pwd</span>=<span style="color: #000000;">pwd) as source, \
file(targetpath, </span><span style="color: #800000;">"</span><span style="color: #800000;">wb</span><span style="color: #800000;">"</span><span style="color: #000000;">) as target:
shutil.copyfileobj(source, target)

</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> targetpath

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> _writecheck(self, zinfo):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Check for errors before writing a file to the archive.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> zinfo.filename <span style="color: #0000ff;">in</span><span style="color: #000000;"> self.NameToInfo:
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> warnings
warnings.warn(</span><span style="color: #800000;">'</span><span style="color: #800000;">Duplicate name: %r</span><span style="color: #800000;">'</span> % zinfo.filename, stacklevel=3<span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> self.mode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">raise</span> RuntimeError, <span style="color: #800000;">'</span><span style="color: #800000;">write() requires mode "w" or "a"</span><span style="color: #800000;">'</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self.fp:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> RuntimeError, \
</span><span style="color: #800000;">"</span><span style="color: #800000;">Attempt to write ZIP archive that was already closed</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">if</span> zinfo.compress_type == ZIP_DEFLATED <span style="color: #0000ff;">and</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> zlib:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> RuntimeError, \
</span><span style="color: #800000;">"</span><span style="color: #800000;">Compression requires the (missing) zlib module</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">if</span> zinfo.compress_type <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> (ZIP_STORED, ZIP_DEFLATED):
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> RuntimeError, \
</span><span style="color: #800000;">"</span><span style="color: #800000;">That compression method is not supported</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self._allowZip64:
requires_zip64 </span>=<span style="color: #000000;"> None
</span><span style="color: #0000ff;">if</span> len(self.filelist) &gt;=<span style="color: #000000;"> ZIP_FILECOUNT_LIMIT:
requires_zip64 </span>= <span style="color: #800000;">"</span><span style="color: #800000;">Files count</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">elif</span> zinfo.file_size &gt;<span style="color: #000000;"> ZIP64_LIMIT:
requires_zip64 </span>= <span style="color: #800000;">"</span><span style="color: #800000;">Filesize</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">elif</span> zinfo.header_offset &gt;<span style="color: #000000;"> ZIP64_LIMIT:
requires_zip64 </span>= <span style="color: #800000;">"</span><span style="color: #800000;">Zipfile size</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> requires_zip64:
</span><span style="color: #0000ff;">raise</span> LargeZipFile(requires_zip64 +
<span style="color: #800000;">"</span><span style="color: #800000;"> would require ZIP64 extensions</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">def</span> write(self, filename, arcname=None, compress_type=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Put the bytes from filename into the archive under the name
arcname.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self.fp:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> RuntimeError(
</span><span style="color: #800000;">"</span><span style="color: #800000;">Attempt to write to ZIP archive that was already closed</span><span style="color: #800000;">"</span><span style="color: #000000;">)

st </span>=<span style="color: #000000;"> os.stat(filename)
isdir </span>=<span style="color: #000000;"> stat.S_ISDIR(st.st_mode)
mtime </span>=<span style="color: #000000;"> time.localtime(st.st_mtime)
date_time </span>= mtime[0:6<span style="color: #000000;">]
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Create ZipInfo instance to store file information</span>
<span style="color: #0000ff;">if</span> arcname <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
arcname </span>=<span style="color: #000000;"> filename
arcname </span>= os.path.normpath(os.path.splitdrive(arcname)[1<span style="color: #000000;">])
</span><span style="color: #0000ff;">while</span> arcname[0] <span style="color: #0000ff;">in</span><span style="color: #000000;"> (os.sep, os.altsep):
arcname </span>= arcname[1<span style="color: #000000;">:]
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> isdir:
arcname </span>+= <span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span><span style="color: #000000;">
zinfo </span>=<span style="color: #000000;"> ZipInfo(arcname, date_time)
zinfo.external_attr </span>= (st[0] &amp; 0xFFFF) &lt;&lt; 16L <span style="color: #008000;">#</span><span style="color: #008000;"> Unix attributes</span>
<span style="color: #0000ff;">if</span> compress_type <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
zinfo.compress_type </span>=<span style="color: #000000;"> self.compression
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
zinfo.compress_type </span>=<span style="color: #000000;"> compress_type

zinfo.file_size </span>=<span style="color: #000000;"> st.st_size
zinfo.flag_bits </span>= 0x00<span style="color: #000000;">
zinfo.header_offset </span>= self.fp.tell() <span style="color: #008000;">#</span><span style="color: #008000;"> Start of header bytes</span>
<span style="color: #000000;">
self._writecheck(zinfo)
self._didModify </span>=<span style="color: #000000;"> True

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> isdir:
zinfo.file_size </span>=<span style="color: #000000;"> 0
zinfo.compress_size </span>=<span style="color: #000000;"> 0
zinfo.CRC </span>=<span style="color: #000000;"> 0
zinfo.external_attr </span>|= 0x10 <span style="color: #008000;">#</span><span style="color: #008000;"> MS-DOS directory flag</span>
<span style="color: #000000;"> self.filelist.append(zinfo)
self.NameToInfo[zinfo.filename] </span>=<span style="color: #000000;"> zinfo
self.fp.write(zinfo.FileHeader(False))
</span><span style="color: #0000ff;">return</span><span style="color: #000000;">

with open(filename, </span><span style="color: #800000;">"</span><span style="color: #800000;">rb</span><span style="color: #800000;">"</span><span style="color: #000000;">) as fp:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Must overwrite CRC and sizes with correct data later</span>
zinfo.CRC = CRC =<span style="color: #000000;"> 0
zinfo.compress_size </span>= compress_size =<span style="color: #000000;"> 0
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Compressed size can be larger than uncompressed size</span>
zip64 = self._allowZip64 <span style="color: #0000ff;">and</span><span style="color: #000000;"> \
zinfo.file_size </span>* 1.05 &gt;<span style="color: #000000;"> ZIP64_LIMIT
self.fp.write(zinfo.FileHeader(zip64))
</span><span style="color: #0000ff;">if</span> zinfo.compress_type ==<span style="color: #000000;"> ZIP_DEFLATED:
cmpr </span>=<span style="color: #000000;"> zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
zlib.DEFLATED, </span>-15<span style="color: #000000;">)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
cmpr </span>=<span style="color: #000000;"> None
file_size </span>=<span style="color: #000000;"> 0
</span><span style="color: #0000ff;">while</span> 1<span style="color: #000000;">:
buf </span>= fp.read(1024 * 8<span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> buf:
</span><span style="color: #0000ff;">break</span><span style="color: #000000;">
file_size </span>= file_size +<span style="color: #000000;"> len(buf)
CRC </span>= crc32(buf, CRC) &amp; 0xffffffff
<span style="color: #0000ff;">if</span><span style="color: #000000;"> cmpr:
buf </span>=<span style="color: #000000;"> cmpr.compress(buf)
compress_size </span>= compress_size +<span style="color: #000000;"> len(buf)
self.fp.write(buf)
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> cmpr:
buf </span>=<span style="color: #000000;"> cmpr.flush()
compress_size </span>= compress_size +<span style="color: #000000;"> len(buf)
self.fp.write(buf)
zinfo.compress_size </span>=<span style="color: #000000;"> compress_size
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
zinfo.compress_size </span>=<span style="color: #000000;"> file_size
zinfo.CRC </span>=<span style="color: #000000;"> CRC
zinfo.file_size </span>=<span style="color: #000000;"> file_size
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> zip64 <span style="color: #0000ff;">and</span><span style="color: #000000;"> self._allowZip64:
</span><span style="color: #0000ff;">if</span> file_size &gt;<span style="color: #000000;"> ZIP64_LIMIT:
</span><span style="color: #0000ff;">raise</span> RuntimeError(<span style="color: #800000;">'</span><span style="color: #800000;">File size has increased during compressing</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> compress_size &gt;<span style="color: #000000;"> ZIP64_LIMIT:
</span><span style="color: #0000ff;">raise</span> RuntimeError(<span style="color: #800000;">'</span><span style="color: #800000;">Compressed size larger than uncompressed size</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Seek backwards and write file header (which will now include</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> correct CRC and file sizes)</span>
position = self.fp.tell() <span style="color: #008000;">#</span><span style="color: #008000;"> Preserve current position in file</span>
<span style="color: #000000;"> self.fp.seek(zinfo.header_offset, 0)
self.fp.write(zinfo.FileHeader(zip64))
self.fp.seek(position, 0)
self.filelist.append(zinfo)
self.NameToInfo[zinfo.filename] </span>=<span style="color: #000000;"> zinfo

</span><span style="color: #0000ff;">def</span> writestr(self, zinfo_or_arcname, bytes, compress_type=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Write a file into the archive. The contents is the string
'bytes'. 'zinfo_or_arcname' is either a ZipInfo instance or
the name of the file in the archive.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> isinstance(zinfo_or_arcname, ZipInfo):
zinfo </span>= ZipInfo(filename=<span style="color: #000000;">zinfo_or_arcname,
date_time</span>=time.localtime(time.time())[:6<span style="color: #000000;">])

zinfo.compress_type </span>=<span style="color: #000000;"> self.compression
</span><span style="color: #0000ff;">if</span> zinfo.filename[-1] == <span style="color: #800000;">'</span><span style="color: #800000;">/</span><span style="color: #800000;">'</span><span style="color: #000000;">:
zinfo.external_attr </span>= 0o40775 &lt;&lt; 16 <span style="color: #008000;">#</span><span style="color: #008000;"> drwxrwxr-x</span>
zinfo.external_attr |= 0x10 <span style="color: #008000;">#</span><span style="color: #008000;"> MS-DOS directory flag</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
zinfo.external_attr </span>= 0o600 &lt;&lt; 16 <span style="color: #008000;">#</span><span style="color: #008000;"> ?rw-------</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
zinfo </span>=<span style="color: #000000;"> zinfo_or_arcname

</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self.fp:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> RuntimeError(
</span><span style="color: #800000;">"</span><span style="color: #800000;">Attempt to write to ZIP archive that was already closed</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">if</span> compress_type <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
zinfo.compress_type </span>=<span style="color: #000000;"> compress_type

zinfo.file_size </span>= len(bytes) <span style="color: #008000;">#</span><span style="color: #008000;"> Uncompressed size</span>
zinfo.header_offset = self.fp.tell() <span style="color: #008000;">#</span><span style="color: #008000;"> Start of header bytes</span>
<span style="color: #000000;"> self._writecheck(zinfo)
self._didModify </span>=<span style="color: #000000;"> True
zinfo.CRC </span>= crc32(bytes) &amp; 0xffffffff <span style="color: #008000;">#</span><span style="color: #008000;"> CRC-32 checksum</span>
<span style="color: #0000ff;">if</span> zinfo.compress_type ==<span style="color: #000000;"> ZIP_DEFLATED:
co </span>=<span style="color: #000000;"> zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
zlib.DEFLATED, </span>-15<span style="color: #000000;">)
bytes </span>= co.compress(bytes) +<span style="color: #000000;"> co.flush()
zinfo.compress_size </span>= len(bytes) <span style="color: #008000;">#</span><span style="color: #008000;"> Compressed size</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
zinfo.compress_size </span>=<span style="color: #000000;"> zinfo.file_size
zip64 </span>= zinfo.file_size &gt; ZIP64_LIMIT <span style="color: #0000ff;">or</span><span style="color: #000000;"> \
zinfo.compress_size </span>&gt;<span style="color: #000000;"> ZIP64_LIMIT
</span><span style="color: #0000ff;">if</span> zip64 <span style="color: #0000ff;">and</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self._allowZip64:
</span><span style="color: #0000ff;">raise</span> LargeZipFile(<span style="color: #800000;">"</span><span style="color: #800000;">Filesize would require ZIP64 extensions</span><span style="color: #800000;">"</span><span style="color: #000000;">)
self.fp.write(zinfo.FileHeader(zip64))
self.fp.write(bytes)
</span><span style="color: #0000ff;">if</span> zinfo.flag_bits &amp; 0x08<span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Write CRC and file sizes after the file data</span>
fmt = <span style="color: #800000;">'</span><span style="color: #800000;">&lt;LQQ</span><span style="color: #800000;">'</span> <span style="color: #0000ff;">if</span> zip64 <span style="color: #0000ff;">else</span> <span style="color: #800000;">'</span><span style="color: #800000;">&lt;LLL</span><span style="color: #800000;">'</span><span style="color: #000000;">
self.fp.write(struct.pack(fmt, zinfo.CRC, zinfo.compress_size,
zinfo.file_size))
self.fp.flush()
self.filelist.append(zinfo)
self.NameToInfo[zinfo.filename] </span>=<span style="color: #000000;"> zinfo

</span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__del__</span><span style="color: #000000;">(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Call the "close()" method in case the user forgot.</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self.close()

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> close(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Close the file, and for mode "w" and "a" write the ending
records.</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> self.fp <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">return</span>

<span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> self.mode <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span>) <span style="color: #0000ff;">and</span> self._didModify: <span style="color: #008000;">#</span><span style="color: #008000;"> write ending records</span>
pos1 =<span style="color: #000000;"> self.fp.tell()
</span><span style="color: #0000ff;">for</span> zinfo <span style="color: #0000ff;">in</span> self.filelist: <span style="color: #008000;">#</span><span style="color: #008000;"> write central directory</span>
dt =<span style="color: #000000;"> zinfo.date_time
dosdate </span>= (dt[0] - 1980) &lt;&lt; 9 | dt[1] &lt;&lt; 5 | dt[2<span style="color: #000000;">]
dostime </span>= dt[3] &lt;&lt; 11 | dt[4] &lt;&lt; 5 | (dt[5] // 2<span style="color: #000000;">)
extra </span>=<span style="color: #000000;"> []
</span><span style="color: #0000ff;">if</span> zinfo.file_size &gt;<span style="color: #000000;"> ZIP64_LIMIT \
</span><span style="color: #0000ff;">or</span> zinfo.compress_size &gt;<span style="color: #000000;"> ZIP64_LIMIT:
extra.append(zinfo.file_size)
extra.append(zinfo.compress_size)
file_size </span>= 0xffffffff<span style="color: #000000;">
compress_size </span>= 0xffffffff
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
file_size </span>=<span style="color: #000000;"> zinfo.file_size
compress_size </span>=<span style="color: #000000;"> zinfo.compress_size

</span><span style="color: #0000ff;">if</span> zinfo.header_offset &gt;<span style="color: #000000;"> ZIP64_LIMIT:
extra.append(zinfo.header_offset)
header_offset </span>= 0xffffffffL
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
header_offset </span>=<span style="color: #000000;"> zinfo.header_offset

extra_data </span>=<span style="color: #000000;"> zinfo.extra
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> extra:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Append a ZIP64 field to the extra's</span>
extra_data =<span style="color: #000000;"> struct.pack(
</span><span style="color: #800000;">'</span><span style="color: #800000;">&lt;HH</span><span style="color: #800000;">'</span> + <span style="color: #800000;">'</span><span style="color: #800000;">Q</span><span style="color: #800000;">'</span>*<span style="color: #000000;">len(extra),
</span>1, 8*len(extra), *extra) +<span style="color: #000000;"> extra_data

extract_version </span>= max(45<span style="color: #000000;">, zinfo.extract_version)
create_version </span>= max(45<span style="color: #000000;">, zinfo.create_version)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
extract_version </span>=<span style="color: #000000;"> zinfo.extract_version
create_version </span>=<span style="color: #000000;"> zinfo.create_version

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
filename, flag_bits </span>=<span style="color: #000000;"> zinfo._encodeFilenameFlags()
centdir </span>=<span style="color: #000000;"> struct.pack(structCentralDir,
stringCentralDir, create_version,
zinfo.create_system, extract_version, zinfo.reserved,
flag_bits, zinfo.compress_type, dostime, dosdate,
zinfo.CRC, compress_size, file_size,
len(filename), len(extra_data), len(zinfo.comment),
0, zinfo.internal_attr, zinfo.external_attr,
header_offset)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> DeprecationWarning:
</span><span style="color: #0000ff;">print</span> &gt;&gt;<span style="color: #000000;">sys.stderr, (structCentralDir,
stringCentralDir, create_version,
zinfo.create_system, extract_version, zinfo.reserved,
zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
zinfo.CRC, compress_size, file_size,
len(zinfo.filename), len(extra_data), len(zinfo.comment),
0, zinfo.internal_attr, zinfo.external_attr,
header_offset)
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;">
self.fp.write(centdir)
self.fp.write(filename)
self.fp.write(extra_data)
self.fp.write(zinfo.comment)

pos2 </span>=<span style="color: #000000;"> self.fp.tell()
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Write end-of-zip-archive record</span>
centDirCount =<span style="color: #000000;"> len(self.filelist)
centDirSize </span>= pos2 -<span style="color: #000000;"> pos1
centDirOffset </span>=<span style="color: #000000;"> pos1
requires_zip64 </span>=<span style="color: #000000;"> None
</span><span style="color: #0000ff;">if</span> centDirCount &gt;<span style="color: #000000;"> ZIP_FILECOUNT_LIMIT:
requires_zip64 </span>= <span style="color: #800000;">"</span><span style="color: #800000;">Files count</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">elif</span> centDirOffset &gt;<span style="color: #000000;"> ZIP64_LIMIT:
requires_zip64 </span>= <span style="color: #800000;">"</span><span style="color: #800000;">Central directory offset</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">elif</span> centDirSize &gt;<span style="color: #000000;"> ZIP64_LIMIT:
requires_zip64 </span>= <span style="color: #800000;">"</span><span style="color: #800000;">Central directory size</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> requires_zip64:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Need to write the ZIP64 end-of-archive records</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self._allowZip64:
</span><span style="color: #0000ff;">raise</span> LargeZipFile(requires_zip64 +
<span style="color: #800000;">"</span><span style="color: #800000;"> would require ZIP64 extensions</span><span style="color: #800000;">"</span><span style="color: #000000;">)
zip64endrec </span>=<span style="color: #000000;"> struct.pack(
structEndArchive64, stringEndArchive64,
</span>44, 45, 45<span style="color: #000000;">, 0, 0, centDirCount, centDirCount,
centDirSize, centDirOffset)
self.fp.write(zip64endrec)

zip64locrec </span>=<span style="color: #000000;"> struct.pack(
structEndArchive64Locator,
stringEndArchive64Locator, 0, pos2, </span>1<span style="color: #000000;">)
self.fp.write(zip64locrec)
centDirCount </span>= min(centDirCount, 0xFFFF<span style="color: #000000;">)
centDirSize </span>= min(centDirSize, 0xFFFFFFFF<span style="color: #000000;">)
centDirOffset </span>= min(centDirOffset, 0xFFFFFFFF<span style="color: #000000;">)

endrec </span>=<span style="color: #000000;"> struct.pack(structEndArchive, stringEndArchive,
0, 0, centDirCount, centDirCount,
centDirSize, centDirOffset, len(self._comment))
self.fp.write(endrec)
self.fp.write(self._comment)
self.fp.flush()
</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">:
fp </span>=<span style="color: #000000;"> self.fp
self.fp </span>=<span style="color: #000000;"> None
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self._filePassed:
fp.close()</span></pre>
</div>
<span class="cnblogs_code_collapse">ZipFile</span></div>
<div class="cnblogs_code" onclick="cnblogs_code_show('386e503f-3b78-4999-b634-5cea354659f9')"><img id="code_img_closed_386e503f-3b78-4999-b634-5cea354659f9" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_386e503f-3b78-4999-b634-5cea354659f9" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('386e503f-3b78-4999-b634-5cea354659f9',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_386e503f-3b78-4999-b634-5cea354659f9" class="cnblogs_code_hide">
<pre><span style="color: #0000ff;">class</span><span style="color: #000000;"> TarFile(object):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">The TarFile Class provides an interface to tar archives.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">

debug </span>= 0 <span style="color: #008000;">#</span><span style="color: #008000;"> May be set from 0 (no msgs) to 3 (all msgs)</span>
<span style="color: #000000;">
dereference </span>= False <span style="color: #008000;">#</span><span style="color: #008000;"> If true, add content of linked file to the</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> tar file, else the link.</span>
<span style="color: #000000;">
ignore_zeros </span>= False <span style="color: #008000;">#</span><span style="color: #008000;"> If true, skips empty or invalid blocks and</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> continues processing.</span>
<span style="color: #000000;">
errorlevel </span>= 1 <span style="color: #008000;">#</span><span style="color: #008000;"> If 0, fatal errors only appear in debug</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> messages (if debug &gt;= 0). If &gt; 0, errors</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> are passed to the caller as exceptions.</span>
<span style="color: #000000;">
format </span>= DEFAULT_FORMAT <span style="color: #008000;">#</span><span style="color: #008000;"> The format to use when creating an archive.</span>
<span style="color: #000000;">
encoding </span>= ENCODING <span style="color: #008000;">#</span><span style="color: #008000;"> Encoding for 8-bit character strings.</span>
<span style="color: #000000;">
errors </span>= None <span style="color: #008000;">#</span><span style="color: #008000;"> Error handler for unicode conversion.</span>
<span style="color: #000000;">
tarinfo </span>= TarInfo <span style="color: #008000;">#</span><span style="color: #008000;"> The default TarInfo class to use.</span>
<span style="color: #000000;">
fileobject </span>= ExFileObject <span style="color: #008000;">#</span><span style="color: #008000;"> The default ExFileObject class to use.</span>

<span style="color: #0000ff;">def</span> <span style="color: #800080;">__init__</span>(self, name=None, mode=<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, fileobj=None, format=<span style="color: #000000;">None,
tarinfo</span>=None, dereference=None, ignore_zeros=None, encoding=<span style="color: #000000;">None,
errors</span>=None, pax_headers=None, debug=None, errorlevel=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
read from an existing archive, 'a' to append data to an existing
file or 'w' to create a new file overwriting an existing one. `mode'
defaults to 'r'.
If `fileobj' is given, it is used for reading or writing data. If it
can be determined, `mode' is overridden by `fileobj's mode.
`fileobj' is not closed, when TarFile is closed.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
modes </span>= {<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">rb</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">r+b</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">wb</span><span style="color: #800000;">"</span><span style="color: #000000;">}
</span><span style="color: #0000ff;">if</span> mode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> modes:
</span><span style="color: #0000ff;">raise</span> ValueError(<span style="color: #800000;">"</span><span style="color: #800000;">mode must be 'r', 'a' or 'w'</span><span style="color: #800000;">"</span><span style="color: #000000;">)
self.mode </span>=<span style="color: #000000;"> mode
self._mode </span>=<span style="color: #000000;"> modes[mode]

</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> fileobj:
</span><span style="color: #0000ff;">if</span> self.mode == <span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">and</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> os.path.exists(name):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Create nonexistent files in append mode.</span>
self.mode = <span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span><span style="color: #000000;">
self._mode </span>= <span style="color: #800000;">"</span><span style="color: #800000;">wb</span><span style="color: #800000;">"</span><span style="color: #000000;">
fileobj </span>=<span style="color: #000000;"> bltn_open(name, self._mode)
self._extfileobj </span>=<span style="color: #000000;"> False
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> name <span style="color: #0000ff;">is</span> None <span style="color: #0000ff;">and</span> hasattr(fileobj, <span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">):
name </span>=<span style="color: #000000;"> fileobj.name
</span><span style="color: #0000ff;">if</span> hasattr(fileobj, <span style="color: #800000;">"</span><span style="color: #800000;">mode</span><span style="color: #800000;">"</span><span style="color: #000000;">):
self._mode </span>=<span style="color: #000000;"> fileobj.mode
self._extfileobj </span>=<span style="color: #000000;"> True
self.name </span>= os.path.abspath(name) <span style="color: #0000ff;">if</span> name <span style="color: #0000ff;">else</span><span style="color: #000000;"> None
self.fileobj </span>=<span style="color: #000000;"> fileobj

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Init attributes.</span>
<span style="color: #0000ff;">if</span> format <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.format </span>=<span style="color: #000000;"> format
</span><span style="color: #0000ff;">if</span> tarinfo <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.tarinfo </span>=<span style="color: #000000;"> tarinfo
</span><span style="color: #0000ff;">if</span> dereference <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.dereference </span>=<span style="color: #000000;"> dereference
</span><span style="color: #0000ff;">if</span> ignore_zeros <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.ignore_zeros </span>=<span style="color: #000000;"> ignore_zeros
</span><span style="color: #0000ff;">if</span> encoding <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.encoding </span>=<span style="color: #000000;"> encoding

</span><span style="color: #0000ff;">if</span> errors <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.errors </span>=<span style="color: #000000;"> errors
</span><span style="color: #0000ff;">elif</span> mode == <span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span><span style="color: #000000;">:
self.errors </span>= <span style="color: #800000;">"</span><span style="color: #800000;">utf-8</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
self.errors </span>= <span style="color: #800000;">"</span><span style="color: #800000;">strict</span><span style="color: #800000;">"</span>

<span style="color: #0000ff;">if</span> pax_headers <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span> None <span style="color: #0000ff;">and</span> self.format ==<span style="color: #000000;"> PAX_FORMAT:
self.pax_headers </span>=<span style="color: #000000;"> pax_headers
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
self.pax_headers </span>=<span style="color: #000000;"> {}

</span><span style="color: #0000ff;">if</span> debug <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.debug </span>=<span style="color: #000000;"> debug
</span><span style="color: #0000ff;">if</span> errorlevel <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.errorlevel </span>=<span style="color: #000000;"> errorlevel

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Init datastructures.</span>
self.closed =<span style="color: #000000;"> False
self.members </span>= [] <span style="color: #008000;">#</span><span style="color: #008000;"> list of members as TarInfo objects</span>
self._loaded = False <span style="color: #008000;">#</span><span style="color: #008000;"> flag if all members have been read</span>
self.offset =<span style="color: #000000;"> self.fileobj.tell()
</span><span style="color: #008000;">#</span><span style="color: #008000;"> current position in the archive file</span>
self.inodes = {} <span style="color: #008000;">#</span><span style="color: #008000;"> dictionary caching the inodes of</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> archive members already added</span>

<span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> self.mode == <span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span><span style="color: #000000;">:
self.firstmember </span>=<span style="color: #000000;"> None
self.firstmember </span>=<span style="color: #000000;"> self.next()

</span><span style="color: #0000ff;">if</span> self.mode == <span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Move to the end of the archive,</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> before the first empty block.</span>
<span style="color: #0000ff;">while</span><span style="color: #000000;"> True:
self.fileobj.seek(self.offset)
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
tarinfo </span>=<span style="color: #000000;"> self.tarinfo.fromtarfile(self)
self.members.append(tarinfo)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EOFHeaderError:
self.fileobj.seek(self.offset)
</span><span style="color: #0000ff;">break</span>
<span style="color: #0000ff;">except</span><span style="color: #000000;"> HeaderError, e:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> ReadError(str(e))

</span><span style="color: #0000ff;">if</span> self.mode <span style="color: #0000ff;">in</span> <span style="color: #800000;">"</span><span style="color: #800000;">aw</span><span style="color: #800000;">"</span><span style="color: #000000;">:
self._loaded </span>=<span style="color: #000000;"> True

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> self.pax_headers:
buf </span>=<span style="color: #000000;"> self.tarinfo.create_pax_global_header(self.pax_headers.copy())
self.fileobj.write(buf)
self.offset </span>+=<span style="color: #000000;"> len(buf)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self._extfileobj:
self.fileobj.close()
self.closed </span>=<span style="color: #000000;"> True
</span><span style="color: #0000ff;">raise</span>

<span style="color: #0000ff;">def</span><span style="color: #000000;"> _getposix(self):
</span><span style="color: #0000ff;">return</span> self.format ==<span style="color: #000000;"> USTAR_FORMAT
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> _setposix(self, value):
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> warnings
warnings.warn(</span><span style="color: #800000;">"</span><span style="color: #800000;">use the format attribute instead</span><span style="color: #800000;">"</span><span style="color: #000000;">, DeprecationWarning,
</span>2<span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> value:
self.format </span>=<span style="color: #000000;"> USTAR_FORMAT
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
self.format </span>=<span style="color: #000000;"> GNU_FORMAT
posix </span>=<span style="color: #000000;"> property(_getposix, _setposix)

</span><span style="color: #008000;">#</span><span style="color: #008000;">--------------------------------------------------------------------------</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Below are the classmethods which act as alternate constructors to the</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> TarFile class. The open() method is the only one that is needed for</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> public use; it is the "super"-constructor and is able to select an</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> adequate "sub"-constructor for a particular compression using the mapping</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> from OPEN_METH.</span>
<span style="color: #008000;">#
</span> <span style="color: #008000;">#</span><span style="color: #008000;"> This concept allows one to subclass TarFile without losing the comfort of</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> the super-constructor. A sub-constructor is registered and made available</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> by adding it to the mapping in OPEN_METH.</span>
<span style="color: #000000;">
@classmethod
</span><span style="color: #0000ff;">def</span> open(cls, name=None, mode=<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, fileobj=None, bufsize=RECORDSIZE, **<span style="color: #000000;">kwargs):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Open a tar archive for reading, writing or appending. Return
an appropriate TarFile class.

mode:
'r' or 'r:*' open for reading with transparent compression
'r:' open for reading exclusively uncompressed
'r:gz' open for reading with gzip compression
'r:bz2' open for reading with bzip2 compression
'a' or 'a:' open for appending, creating the file if necessary
'w' or 'w:' open for writing without compression
'w:gz' open for writing with gzip compression
'w:bz2' open for writing with bzip2 compression

'r|*' open a stream of tar blocks with transparent compression
'r|' open an uncompressed stream of tar blocks for reading
'r|gz' open a gzip compressed stream of tar blocks
'r|bz2' open a bzip2 compressed stream of tar blocks
'w|' open an uncompressed stream for writing
'w|gz' open a gzip compressed stream for writing
'w|bz2' open a bzip2 compressed stream for writing
</span><span style="color: #800000;">"""</span>

<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> name <span style="color: #0000ff;">and</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> fileobj:
</span><span style="color: #0000ff;">raise</span> ValueError(<span style="color: #800000;">"</span><span style="color: #800000;">nothing to open</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">if</span> mode <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">r:*</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Find out which *open() is appropriate for opening the file.</span>
<span style="color: #0000ff;">for</span> comptype <span style="color: #0000ff;">in</span><span style="color: #000000;"> cls.OPEN_METH:
func </span>=<span style="color: #000000;"> getattr(cls, cls.OPEN_METH[comptype])
</span><span style="color: #0000ff;">if</span> fileobj <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
saved_pos </span>=<span style="color: #000000;"> fileobj.tell()
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span> func(name, <span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, fileobj, **<span style="color: #000000;">kwargs)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> (ReadError, CompressionError), e:
</span><span style="color: #0000ff;">if</span> fileobj <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
fileobj.seek(saved_pos)
</span><span style="color: #0000ff;">continue</span>
<span style="color: #0000ff;">raise</span> ReadError(<span style="color: #800000;">"</span><span style="color: #800000;">file could not be opened successfully</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">elif</span> <span style="color: #800000;">"</span><span style="color: #800000;">:</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> mode:
filemode, comptype </span>= mode.split(<span style="color: #800000;">"</span><span style="color: #800000;">:</span><span style="color: #800000;">"</span>, 1<span style="color: #000000;">)
filemode </span>= filemode <span style="color: #0000ff;">or</span> <span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span><span style="color: #000000;">
comptype </span>= comptype <span style="color: #0000ff;">or</span> <span style="color: #800000;">"</span><span style="color: #800000;">tar</span><span style="color: #800000;">"</span>

<span style="color: #008000;">#</span><span style="color: #008000;"> Select the *open() function according to</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> given compression.</span>
<span style="color: #0000ff;">if</span> comptype <span style="color: #0000ff;">in</span><span style="color: #000000;"> cls.OPEN_METH:
func </span>=<span style="color: #000000;"> getattr(cls, cls.OPEN_METH[comptype])
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span> CompressionError(<span style="color: #800000;">"</span><span style="color: #800000;">unknown compression type %r</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> comptype)
</span><span style="color: #0000ff;">return</span> func(name, filemode, fileobj, **<span style="color: #000000;">kwargs)

</span><span style="color: #0000ff;">elif</span> <span style="color: #800000;">"</span><span style="color: #800000;">|</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> mode:
filemode, comptype </span>= mode.split(<span style="color: #800000;">"</span><span style="color: #800000;">|</span><span style="color: #800000;">"</span>, 1<span style="color: #000000;">)
filemode </span>= filemode <span style="color: #0000ff;">or</span> <span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span><span style="color: #000000;">
comptype </span>= comptype <span style="color: #0000ff;">or</span> <span style="color: #800000;">"</span><span style="color: #800000;">tar</span><span style="color: #800000;">"</span>

<span style="color: #0000ff;">if</span> filemode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">raise</span> ValueError(<span style="color: #800000;">"</span><span style="color: #800000;">mode must be 'r' or 'w'</span><span style="color: #800000;">"</span><span style="color: #000000;">)

stream </span>=<span style="color: #000000;"> _Stream(name, filemode, comptype, fileobj, bufsize)
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
t </span>= cls(name, filemode, stream, **<span style="color: #000000;">kwargs)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;">:
stream.close()
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;">
t._extfileobj </span>=<span style="color: #000000;"> False
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> t

</span><span style="color: #0000ff;">elif</span> mode <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">return</span> cls.taropen(name, mode, fileobj, **<span style="color: #000000;">kwargs)

</span><span style="color: #0000ff;">raise</span> ValueError(<span style="color: #800000;">"</span><span style="color: #800000;">undiscernible mode</span><span style="color: #800000;">"</span><span style="color: #000000;">)

@classmethod
</span><span style="color: #0000ff;">def</span> taropen(cls, name, mode=<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, fileobj=None, **<span style="color: #000000;">kwargs):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Open uncompressed tar archive name for reading or writing.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> mode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">a</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">raise</span> ValueError(<span style="color: #800000;">"</span><span style="color: #800000;">mode must be 'r', 'a' or 'w'</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">return</span> cls(name, mode, fileobj, **<span style="color: #000000;">kwargs)

@classmethod
</span><span style="color: #0000ff;">def</span> gzopen(cls, name, mode=<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, fileobj=None, compresslevel=9, **<span style="color: #000000;">kwargs):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Open gzip compressed tar archive name for reading or writing.
Appending is not allowed.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> mode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">raise</span> ValueError(<span style="color: #800000;">"</span><span style="color: #800000;">mode must be 'r' or 'w'</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> gzip
gzip.GzipFile
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> (ImportError, AttributeError):
</span><span style="color: #0000ff;">raise</span> CompressionError(<span style="color: #800000;">"</span><span style="color: #800000;">gzip module is not available</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
fileobj </span>=<span style="color: #000000;"> gzip.GzipFile(name, mode, compresslevel, fileobj)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> OSError:
</span><span style="color: #0000ff;">if</span> fileobj <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span> None <span style="color: #0000ff;">and</span> mode == <span style="color: #800000;">'</span><span style="color: #800000;">r</span><span style="color: #800000;">'</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span> ReadError(<span style="color: #800000;">"</span><span style="color: #800000;">not a gzip file</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">raise</span>

<span style="color: #0000ff;">try</span><span style="color: #000000;">:
t </span>= cls.taropen(name, mode, fileobj, **<span style="color: #000000;">kwargs)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> IOError:
fileobj.close()
</span><span style="color: #0000ff;">if</span> mode == <span style="color: #800000;">'</span><span style="color: #800000;">r</span><span style="color: #800000;">'</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span> ReadError(<span style="color: #800000;">"</span><span style="color: #800000;">not a gzip file</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">raise</span>
<span style="color: #0000ff;">except</span><span style="color: #000000;">:
fileobj.close()
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;">
t._extfileobj </span>=<span style="color: #000000;"> False
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> t

@classmethod
</span><span style="color: #0000ff;">def</span> bz2open(cls, name, mode=<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, fileobj=None, compresslevel=9, **<span style="color: #000000;">kwargs):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Open bzip2 compressed tar archive name for reading or writing.
Appending is not allowed.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> mode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span> (<span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">w</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">raise</span> ValueError(<span style="color: #800000;">"</span><span style="color: #800000;">mode must be 'r' or 'w'.</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> bz2
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> ImportError:
</span><span style="color: #0000ff;">raise</span> CompressionError(<span style="color: #800000;">"</span><span style="color: #800000;">bz2 module is not available</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">if</span> fileobj <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
fileobj </span>=<span style="color: #000000;"> _BZ2Proxy(fileobj, mode)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
fileobj </span>= bz2.BZ2File(name, mode, compresslevel=<span style="color: #000000;">compresslevel)

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
t </span>= cls.taropen(name, mode, fileobj, **<span style="color: #000000;">kwargs)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> (IOError, EOFError):
fileobj.close()
</span><span style="color: #0000ff;">if</span> mode == <span style="color: #800000;">'</span><span style="color: #800000;">r</span><span style="color: #800000;">'</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span> ReadError(<span style="color: #800000;">"</span><span style="color: #800000;">not a bzip2 file</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">raise</span>
<span style="color: #0000ff;">except</span><span style="color: #000000;">:
fileobj.close()
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;">
t._extfileobj </span>=<span style="color: #000000;"> False
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> t

</span><span style="color: #008000;">#</span><span style="color: #008000;"> All *open() methods are registered here.</span>
OPEN_METH =<span style="color: #000000;"> {
</span><span style="color: #800000;">"</span><span style="color: #800000;">tar</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">taropen</span><span style="color: #800000;">"</span>, <span style="color: #008000;">#</span><span style="color: #008000;"> uncompressed tar</span>
<span style="color: #800000;">"</span><span style="color: #800000;">gz</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">gzopen</span><span style="color: #800000;">"</span>, <span style="color: #008000;">#</span><span style="color: #008000;"> gzip compressed tar</span>
<span style="color: #800000;">"</span><span style="color: #800000;">bz2</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">bz2open</span><span style="color: #800000;">"</span> <span style="color: #008000;">#</span><span style="color: #008000;"> bzip2 compressed tar</span>
<span style="color: #000000;"> }

</span><span style="color: #008000;">#</span><span style="color: #008000;">--------------------------------------------------------------------------</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> The public methods which TarFile provides:</span>

<span style="color: #0000ff;">def</span><span style="color: #000000;"> close(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Close the TarFile. In write-mode, two finishing zero blocks are
appended to the archive.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> self.closed:
</span><span style="color: #0000ff;">return</span>

<span style="color: #0000ff;">if</span> self.mode <span style="color: #0000ff;">in</span> <span style="color: #800000;">"</span><span style="color: #800000;">aw</span><span style="color: #800000;">"</span><span style="color: #000000;">:
self.fileobj.write(NUL </span>* (BLOCKSIZE * 2<span style="color: #000000;">))
self.offset </span>+= (BLOCKSIZE * 2<span style="color: #000000;">)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> fill up the end with zero-blocks</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> (like option -b20 for tar does)</span>
blocks, remainder =<span style="color: #000000;"> divmod(self.offset, RECORDSIZE)
</span><span style="color: #0000ff;">if</span> remainder &gt;<span style="color: #000000;"> 0:
self.fileobj.write(NUL </span>* (RECORDSIZE -<span style="color: #000000;"> remainder))

</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self._extfileobj:
self.fileobj.close()
self.closed </span>=<span style="color: #000000;"> True

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> getmember(self, name):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return a TarInfo object for member `name'. If `name' can not be
found in the archive, KeyError is raised. If a member occurs more
than once in the archive, its last occurrence is assumed to be the
most up-to-date version.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
tarinfo </span>=<span style="color: #000000;"> self._getmember(name)
</span><span style="color: #0000ff;">if</span> tarinfo <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">raise</span> KeyError(<span style="color: #800000;">"</span><span style="color: #800000;">filename %r not found</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> name)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> tarinfo

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> getmembers(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return the members of the archive as a list of TarInfo objects. The
list has the same order as the members in the archive.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._check()
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> self._loaded: <span style="color: #008000;">#</span><span style="color: #008000;"> if we want to obtain a list of</span>
self._load() <span style="color: #008000;">#</span><span style="color: #008000;"> all members, we first have to</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> scan the whole archive.</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;"> self.members

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> getnames(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return the members of the archive as a list of their names. It has
the same order as the list returned by getmembers().
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">return</span> [tarinfo.name <span style="color: #0000ff;">for</span> tarinfo <span style="color: #0000ff;">in</span><span style="color: #000000;"> self.getmembers()]

</span><span style="color: #0000ff;">def</span> gettarinfo(self, name=None, arcname=None, fileobj=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Create a TarInfo object for either the file `name' or the file
object `fileobj' (using os.fstat on its file descriptor). You can
modify some of the TarInfo's attributes before you add it using
addfile(). If given, `arcname' specifies an alternative name for the
file in the archive.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._check(</span><span style="color: #800000;">"</span><span style="color: #800000;">aw</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> When fileobj is given, replace name by</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> fileobj's real name.</span>
<span style="color: #0000ff;">if</span> fileobj <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
name </span>=<span style="color: #000000;"> fileobj.name

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Building the name of the member in the archive.</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Backward slashes are converted to forward slashes,</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Absolute paths are turned to relative paths.</span>
<span style="color: #0000ff;">if</span> arcname <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
arcname </span>=<span style="color: #000000;"> name
drv, arcname </span>=<span style="color: #000000;"> os.path.splitdrive(arcname)
arcname </span>= arcname.replace(os.sep, <span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">)
arcname </span>= arcname.lstrip(<span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Now, fill the TarInfo object with</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> information specific for the file.</span>
tarinfo =<span style="color: #000000;"> self.tarinfo()
tarinfo.tarfile </span>=<span style="color: #000000;"> self

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Use os.stat or os.lstat, depending on platform</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> and if symlinks shall be resolved.</span>
<span style="color: #0000ff;">if</span> fileobj <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">lstat</span><span style="color: #800000;">"</span>) <span style="color: #0000ff;">and</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self.dereference:
statres </span>=<span style="color: #000000;"> os.lstat(name)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
statres </span>=<span style="color: #000000;"> os.stat(name)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
statres </span>=<span style="color: #000000;"> os.fstat(fileobj.fileno())
linkname </span>= <span style="color: #800000;">""</span><span style="color: #000000;">

stmd </span>=<span style="color: #000000;"> statres.st_mode
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> stat.S_ISREG(stmd):
inode </span>=<span style="color: #000000;"> (statres.st_ino, statres.st_dev)
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> self.dereference <span style="color: #0000ff;">and</span> statres.st_nlink &gt; 1 <span style="color: #0000ff;">and</span><span style="color: #000000;"> \
inode </span><span style="color: #0000ff;">in</span> self.inodes <span style="color: #0000ff;">and</span> arcname !=<span style="color: #000000;"> self.inodes[inode]:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Is it a hardlink to an already</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> archived file?</span>
type =<span style="color: #000000;"> LNKTYPE
linkname </span>=<span style="color: #000000;"> self.inodes[inode]
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> The inode is added only if its valid.</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> For win32 it is always 0.</span>
type =<span style="color: #000000;"> REGTYPE
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> inode[0]:
self.inodes[inode] </span>=<span style="color: #000000;"> arcname
</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> stat.S_ISDIR(stmd):
type </span>=<span style="color: #000000;"> DIRTYPE
</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> stat.S_ISFIFO(stmd):
type </span>=<span style="color: #000000;"> FIFOTYPE
</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> stat.S_ISLNK(stmd):
type </span>=<span style="color: #000000;"> SYMTYPE
linkname </span>=<span style="color: #000000;"> os.readlink(name)
</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> stat.S_ISCHR(stmd):
type </span>=<span style="color: #000000;"> CHRTYPE
</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> stat.S_ISBLK(stmd):
type </span>=<span style="color: #000000;"> BLKTYPE
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> None

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Fill the TarInfo object with all</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> information we can get.</span>
tarinfo.name =<span style="color: #000000;"> arcname
tarinfo.mode </span>=<span style="color: #000000;"> stmd
tarinfo.uid </span>=<span style="color: #000000;"> statres.st_uid
tarinfo.gid </span>=<span style="color: #000000;"> statres.st_gid
</span><span style="color: #0000ff;">if</span> type ==<span style="color: #000000;"> REGTYPE:
tarinfo.size </span>=<span style="color: #000000;"> statres.st_size
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
tarinfo.size </span>=<span style="color: #000000;"> 0L
tarinfo.mtime </span>=<span style="color: #000000;"> statres.st_mtime
tarinfo.type </span>=<span style="color: #000000;"> type
tarinfo.linkname </span>=<span style="color: #000000;"> linkname
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> pwd:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
tarinfo.uname </span>=<span style="color: #000000;"> pwd.getpwuid(tarinfo.uid)[0]
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> KeyError:
</span><span style="color: #0000ff;">pass</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> grp:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
tarinfo.gname </span>=<span style="color: #000000;"> grp.getgrgid(tarinfo.gid)[0]
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> KeyError:
</span><span style="color: #0000ff;">pass</span>

<span style="color: #0000ff;">if</span> type <span style="color: #0000ff;">in</span><span style="color: #000000;"> (CHRTYPE, BLKTYPE):
</span><span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">major</span><span style="color: #800000;">"</span>) <span style="color: #0000ff;">and</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">minor</span><span style="color: #800000;">"</span><span style="color: #000000;">):
tarinfo.devmajor </span>=<span style="color: #000000;"> os.major(statres.st_rdev)
tarinfo.devminor </span>=<span style="color: #000000;"> os.minor(statres.st_rdev)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> tarinfo

</span><span style="color: #0000ff;">def</span> list(self, verbose=<span style="color: #000000;">True):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Print a table of contents to sys.stdout. If `verbose' is False, only
the names of the members are printed. If it is True, an `ls -l'-like
output is produced.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._check()

</span><span style="color: #0000ff;">for</span> tarinfo <span style="color: #0000ff;">in</span><span style="color: #000000;"> self:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> verbose:
</span><span style="color: #0000ff;">print</span><span style="color: #000000;"> filemode(tarinfo.mode),
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">%s/%s</span><span style="color: #800000;">"</span> % (tarinfo.uname <span style="color: #0000ff;">or</span><span style="color: #000000;"> tarinfo.uid,
tarinfo.gname </span><span style="color: #0000ff;">or</span><span style="color: #000000;"> tarinfo.gid),
</span><span style="color: #0000ff;">if</span> tarinfo.ischr() <span style="color: #0000ff;">or</span><span style="color: #000000;"> tarinfo.isblk():
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">%10s</span><span style="color: #800000;">"</span> % (<span style="color: #800000;">"</span><span style="color: #800000;">%d,%d</span><span style="color: #800000;">"</span><span style="color: #000000;"> \
</span>%<span style="color: #000000;"> (tarinfo.devmajor, tarinfo.devminor)),
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">%10d</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> tarinfo.size,
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">%d-%02d-%02d %02d:%02d:%02d</span><span style="color: #800000;">"</span><span style="color: #000000;"> \
</span>% time.localtime(tarinfo.mtime)[:6<span style="color: #000000;">],

</span><span style="color: #0000ff;">print</span> tarinfo.name + (<span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span> <span style="color: #0000ff;">if</span> tarinfo.isdir() <span style="color: #0000ff;">else</span> <span style="color: #800000;">""</span><span style="color: #000000;">),

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> verbose:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.issym():
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">-&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">, tarinfo.linkname,
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.islnk():
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">link to</span><span style="color: #800000;">"</span><span style="color: #000000;">, tarinfo.linkname,
</span><span style="color: #0000ff;">print</span>

<span style="color: #0000ff;">def</span> add(self, name, arcname=None, recursive=True, exclude=None, filter=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Add the file `name' to the archive. `name' may be any type of file
(directory, fifo, symbolic link, etc.). If given, `arcname'
specifies an alternative name for the file in the archive.
Directories are added recursively by default. This can be avoided by
setting `recursive' to False. `exclude' is a function that should
return True for each filename to be excluded. `filter' is a function
that expects a TarInfo object argument and returns the changed
TarInfo object, if it returns None the TarInfo object will be
excluded from the archive.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._check(</span><span style="color: #800000;">"</span><span style="color: #800000;">aw</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">if</span> arcname <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
arcname </span>=<span style="color: #000000;"> name

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Exclude pathnames.</span>
<span style="color: #0000ff;">if</span> exclude <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">import</span><span style="color: #000000;"> warnings
warnings.warn(</span><span style="color: #800000;">"</span><span style="color: #800000;">use the filter argument instead</span><span style="color: #800000;">"</span><span style="color: #000000;">,
DeprecationWarning, </span>2<span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> exclude(name):
self._dbg(</span>2, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: Excluded %r</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> name)
</span><span style="color: #0000ff;">return</span>

<span style="color: #008000;">#</span><span style="color: #008000;"> Skip if somebody tries to archive the archive...</span>
<span style="color: #0000ff;">if</span> self.name <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span> None <span style="color: #0000ff;">and</span> os.path.abspath(name) ==<span style="color: #000000;"> self.name:
self._dbg(</span>2, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: Skipped %r</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> name)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;">

self._dbg(</span>1<span style="color: #000000;">, name)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Create a TarInfo object from the file.</span>
tarinfo =<span style="color: #000000;"> self.gettarinfo(name, arcname)

</span><span style="color: #0000ff;">if</span> tarinfo <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
self._dbg(</span>1, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: Unsupported type %r</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> name)
</span><span style="color: #0000ff;">return</span>

<span style="color: #008000;">#</span><span style="color: #008000;"> Change or exclude the TarInfo object.</span>
<span style="color: #0000ff;">if</span> filter <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
tarinfo </span>=<span style="color: #000000;"> filter(tarinfo)
</span><span style="color: #0000ff;">if</span> tarinfo <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
self._dbg(</span>2, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: Excluded %r</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> name)
</span><span style="color: #0000ff;">return</span>

<span style="color: #008000;">#</span><span style="color: #008000;"> Append the tar header and data to the archive.</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.isreg():
with bltn_open(name, </span><span style="color: #800000;">"</span><span style="color: #800000;">rb</span><span style="color: #800000;">"</span><span style="color: #000000;">) as f:
self.addfile(tarinfo, f)

</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> tarinfo.isdir():
self.addfile(tarinfo)
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> recursive:
</span><span style="color: #0000ff;">for</span> f <span style="color: #0000ff;">in</span><span style="color: #000000;"> os.listdir(name):
self.add(os.path.join(name, f), os.path.join(arcname, f),
recursive, exclude, filter)

</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
self.addfile(tarinfo)

</span><span style="color: #0000ff;">def</span> addfile(self, tarinfo, fileobj=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
given, tarinfo.size bytes are read from it and added to the archive.
You can create TarInfo objects using gettarinfo().
On Windows platforms, `fileobj' should always be opened with mode
'rb' to avoid irritation about the file size.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._check(</span><span style="color: #800000;">"</span><span style="color: #800000;">aw</span><span style="color: #800000;">"</span><span style="color: #000000;">)

tarinfo </span>=<span style="color: #000000;"> copy.copy(tarinfo)

buf </span>=<span style="color: #000000;"> tarinfo.tobuf(self.format, self.encoding, self.errors)
self.fileobj.write(buf)
self.offset </span>+=<span style="color: #000000;"> len(buf)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> If there's data to follow, append it.</span>
<span style="color: #0000ff;">if</span> fileobj <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
copyfileobj(fileobj, self.fileobj, tarinfo.size)
blocks, remainder </span>=<span style="color: #000000;"> divmod(tarinfo.size, BLOCKSIZE)
</span><span style="color: #0000ff;">if</span> remainder &gt;<span style="color: #000000;"> 0:
self.fileobj.write(NUL </span>* (BLOCKSIZE -<span style="color: #000000;"> remainder))
blocks </span>+= 1<span style="color: #000000;">
self.offset </span>+= blocks *<span style="color: #000000;"> BLOCKSIZE

self.members.append(tarinfo)

</span><span style="color: #0000ff;">def</span> extractall(self, path=<span style="color: #800000;">"</span><span style="color: #800000;">.</span><span style="color: #800000;">"</span>, members=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Extract all members from the archive to the current working
directory and set owner, modification time and permissions on
directories afterwards. `path' specifies a different directory
to extract to. `members' is optional and must be a subset of the
list returned by getmembers().
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
directories </span>=<span style="color: #000000;"> []

</span><span style="color: #0000ff;">if</span> members <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
members </span>=<span style="color: #000000;"> self

</span><span style="color: #0000ff;">for</span> tarinfo <span style="color: #0000ff;">in</span><span style="color: #000000;"> members:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.isdir():
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Extract directories with a safe mode.</span>
<span style="color: #000000;"> directories.append(tarinfo)
tarinfo </span>=<span style="color: #000000;"> copy.copy(tarinfo)
tarinfo.mode </span>= 0700<span style="color: #000000;">
self.extract(tarinfo, path)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Reverse sort directories.</span>
directories.sort(key=operator.attrgetter(<span style="color: #800000;">'</span><span style="color: #800000;">name</span><span style="color: #800000;">'</span><span style="color: #000000;">))
directories.reverse()

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Set correct owner, mtime and filemode on directories.</span>
<span style="color: #0000ff;">for</span> tarinfo <span style="color: #0000ff;">in</span><span style="color: #000000;"> directories:
dirpath </span>=<span style="color: #000000;"> os.path.join(path, tarinfo.name)
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
self.chown(tarinfo, dirpath)
self.utime(tarinfo, dirpath)
self.chmod(tarinfo, dirpath)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> ExtractError, e:
</span><span style="color: #0000ff;">if</span> self.errorlevel &gt; 1<span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
self._dbg(</span>1, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: %s</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> e)

</span><span style="color: #0000ff;">def</span> extract(self, member, path=<span style="color: #800000;">""</span><span style="color: #000000;">):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Extract a member from the archive to the current working directory,
using its full name. Its file information is extracted as accurately
as possible. `member' may be a filename or a TarInfo object. You can
specify a different directory using `path'.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._check(</span><span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> isinstance(member, basestring):
tarinfo </span>=<span style="color: #000000;"> self.getmember(member)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
tarinfo </span>=<span style="color: #000000;"> member

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Prepare the link target for makelink().</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.islnk():
tarinfo._link_target </span>=<span style="color: #000000;"> os.path.join(path, tarinfo.linkname)

</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
self._extract_member(tarinfo, os.path.join(path, tarinfo.name))
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EnvironmentError, e:
</span><span style="color: #0000ff;">if</span> self.errorlevel &gt;<span style="color: #000000;"> 0:
</span><span style="color: #0000ff;">raise</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> e.filename <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
self._dbg(</span>1, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: %s</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> e.strerror)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
self._dbg(</span>1, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: %s %r</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> (e.strerror, e.filename))
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> ExtractError, e:
</span><span style="color: #0000ff;">if</span> self.errorlevel &gt; 1<span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span>
<span style="color: #0000ff;">else</span><span style="color: #000000;">:
self._dbg(</span>1, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: %s</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> e)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> extractfile(self, member):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Extract a member from the archive as a file object. `member' may be
a filename or a TarInfo object. If `member' is a regular file, a
file-like object is returned. If `member' is a link, a file-like
object is constructed from the link's target. If `member' is none of
the above, None is returned.
The file-like object is read-only and provides the following
methods: read(), readline(), readlines(), seek() and tell()
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._check(</span><span style="color: #800000;">"</span><span style="color: #800000;">r</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> isinstance(member, basestring):
tarinfo </span>=<span style="color: #000000;"> self.getmember(member)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
tarinfo </span>=<span style="color: #000000;"> member

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.isreg():
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self.fileobject(self, tarinfo)

</span><span style="color: #0000ff;">elif</span> tarinfo.type <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> SUPPORTED_TYPES:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> If a member's type is unknown, it is treated as a</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> regular file.</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;"> self.fileobject(self, tarinfo)

</span><span style="color: #0000ff;">elif</span> tarinfo.islnk() <span style="color: #0000ff;">or</span><span style="color: #000000;"> tarinfo.issym():
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> isinstance(self.fileobj, _Stream):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> A small but ugly workaround for the case that someone tries</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> to extract a (sym)link as a file-object from a non-seekable</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> stream of tar blocks.</span>
<span style="color: #0000ff;">raise</span> StreamError(<span style="color: #800000;">"</span><span style="color: #800000;">cannot extract (sym)link as file object</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> A (sym)link's file object is its target's file object.</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;"> self.extractfile(self._find_link_target(tarinfo))
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> If there's no data associated with the member (directory, chrdev,</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> blkdev, etc.), return None instead of a file object.</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;"> None

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> _extract_member(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Extract the TarInfo object tarinfo to a physical
file called targetpath.
</span><span style="color: #800000;">"""</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Fetch the TarInfo object for the given name</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> and build the destination pathname, replacing</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> forward slashes to platform specific separators.</span>
targetpath = targetpath.rstrip(<span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">)
targetpath </span>= targetpath.replace(<span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">, os.sep)

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Create all upper directories.</span>
upperdirs =<span style="color: #000000;"> os.path.dirname(targetpath)
</span><span style="color: #0000ff;">if</span> upperdirs <span style="color: #0000ff;">and</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> os.path.exists(upperdirs):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Create directories that are not part of the archive with</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> default permissions.</span>
<span style="color: #000000;"> os.makedirs(upperdirs)

</span><span style="color: #0000ff;">if</span> tarinfo.islnk() <span style="color: #0000ff;">or</span><span style="color: #000000;"> tarinfo.issym():
self._dbg(</span>1, <span style="color: #800000;">"</span><span style="color: #800000;">%s -&gt; %s</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> (tarinfo.name, tarinfo.linkname))
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
self._dbg(</span>1<span style="color: #000000;">, tarinfo.name)

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.isreg():
self.makefile(tarinfo, targetpath)
</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> tarinfo.isdir():
self.makedir(tarinfo, targetpath)
</span><span style="color: #0000ff;">elif</span><span style="color: #000000;"> tarinfo.isfifo():
self.makefifo(tarinfo, targetpath)
</span><span style="color: #0000ff;">elif</span> tarinfo.ischr() <span style="color: #0000ff;">or</span><span style="color: #000000;"> tarinfo.isblk():
self.makedev(tarinfo, targetpath)
</span><span style="color: #0000ff;">elif</span> tarinfo.islnk() <span style="color: #0000ff;">or</span><span style="color: #000000;"> tarinfo.issym():
self.makelink(tarinfo, targetpath)
</span><span style="color: #0000ff;">elif</span> tarinfo.type <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> SUPPORTED_TYPES:
self.makeunknown(tarinfo, targetpath)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
self.makefile(tarinfo, targetpath)

self.chown(tarinfo, targetpath)
</span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> tarinfo.issym():
self.chmod(tarinfo, targetpath)
self.utime(tarinfo, targetpath)

</span><span style="color: #008000;">#</span><span style="color: #008000;">--------------------------------------------------------------------------</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Below are the different file methods. They are called via</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> _extract_member() when extract() is called. They can be replaced in a</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> subclass to implement other functionality.</span>

<span style="color: #0000ff;">def</span><span style="color: #000000;"> makedir(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Make a directory called targetpath.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Use a safe mode for the directory, the real mode is set</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> later in _extract_member().</span>
os.mkdir(targetpath, 0700<span style="color: #000000;">)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EnvironmentError, e:
</span><span style="color: #0000ff;">if</span> e.errno !=<span style="color: #000000;"> errno.EEXIST:
</span><span style="color: #0000ff;">raise</span>

<span style="color: #0000ff;">def</span><span style="color: #000000;"> makefile(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Make a file called targetpath.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
source </span>=<span style="color: #000000;"> self.extractfile(tarinfo)
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
with bltn_open(targetpath, </span><span style="color: #800000;">"</span><span style="color: #800000;">wb</span><span style="color: #800000;">"</span><span style="color: #000000;">) as target:
copyfileobj(source, target)
</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">:
source.close()

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> makeunknown(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Make a file from a TarInfo object with an unknown type
at targetpath.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self.makefile(tarinfo, targetpath)
self._dbg(</span>1, <span style="color: #800000;">"</span><span style="color: #800000;">tarfile: Unknown file type %r, </span><span style="color: #800000;">"</span><span style="color: #000000;"> \
</span><span style="color: #800000;">"</span><span style="color: #800000;">extracted as regular file.</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> tarinfo.type)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> makefifo(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Make a fifo called targetpath.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">mkfifo</span><span style="color: #800000;">"</span><span style="color: #000000;">):
os.mkfifo(targetpath)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">raise</span> ExtractError(<span style="color: #800000;">"</span><span style="color: #800000;">fifo not supported by system</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> makedev(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Make a character or block device called targetpath.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">mknod</span><span style="color: #800000;">"</span>) <span style="color: #0000ff;">or</span> <span style="color: #0000ff;">not</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">makedev</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">raise</span> ExtractError(<span style="color: #800000;">"</span><span style="color: #800000;">special devices not supported by system</span><span style="color: #800000;">"</span><span style="color: #000000;">)

mode </span>=<span style="color: #000000;"> tarinfo.mode
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.isblk():
mode </span>|=<span style="color: #000000;"> stat.S_IFBLK
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
mode </span>|=<span style="color: #000000;"> stat.S_IFCHR

os.mknod(targetpath, mode,
os.makedev(tarinfo.devmajor, tarinfo.devminor))

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> makelink(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Make a (symbolic) link called targetpath. If it cannot be created
(platform limitation), we try to make a copy of the referenced file
instead of a link.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">symlink</span><span style="color: #800000;">"</span>) <span style="color: #0000ff;">and</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">link</span><span style="color: #800000;">"</span><span style="color: #000000;">):
</span><span style="color: #008000;">#</span><span style="color: #008000;"> For systems that support symbolic and hard links.</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.issym():
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.lexists(targetpath):
os.unlink(targetpath)
os.symlink(tarinfo.linkname, targetpath)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> See extract().</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.exists(tarinfo._link_target):
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> os.path.lexists(targetpath):
os.unlink(targetpath)
os.link(tarinfo._link_target, targetpath)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
self._extract_member(self._find_link_target(tarinfo), targetpath)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
self._extract_member(self._find_link_target(tarinfo), targetpath)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> KeyError:
</span><span style="color: #0000ff;">raise</span> ExtractError(<span style="color: #800000;">"</span><span style="color: #800000;">unable to resolve link inside archive</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> chown(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Set owner of targetpath according to tarinfo.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> pwd <span style="color: #0000ff;">and</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">geteuid</span><span style="color: #800000;">"</span>) <span style="color: #0000ff;">and</span> os.geteuid() ==<span style="color: #000000;"> 0:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> We have to be root to do so.</span>
<span style="color: #0000ff;">try</span><span style="color: #000000;">:
g </span>= grp.getgrnam(tarinfo.gname)[2<span style="color: #000000;">]
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> KeyError:
g </span>=<span style="color: #000000;"> tarinfo.gid
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
u </span>= pwd.getpwnam(tarinfo.uname)[2<span style="color: #000000;">]
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> KeyError:
u </span>=<span style="color: #000000;"> tarinfo.uid
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> tarinfo.issym() <span style="color: #0000ff;">and</span> hasattr(os, <span style="color: #800000;">"</span><span style="color: #800000;">lchown</span><span style="color: #800000;">"</span><span style="color: #000000;">):
os.lchown(targetpath, u, g)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">if</span> sys.platform != <span style="color: #800000;">"</span><span style="color: #800000;">os2emx</span><span style="color: #800000;">"</span><span style="color: #000000;">:
os.chown(targetpath, u, g)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EnvironmentError, e:
</span><span style="color: #0000ff;">raise</span> ExtractError(<span style="color: #800000;">"</span><span style="color: #800000;">could not change owner</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> chmod(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Set file permissions of targetpath according to tarinfo.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> hasattr(os, <span style="color: #800000;">'</span><span style="color: #800000;">chmod</span><span style="color: #800000;">'</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
os.chmod(targetpath, tarinfo.mode)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EnvironmentError, e:
</span><span style="color: #0000ff;">raise</span> ExtractError(<span style="color: #800000;">"</span><span style="color: #800000;">could not change mode</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> utime(self, tarinfo, targetpath):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Set modification time of targetpath according to tarinfo.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> hasattr(os, <span style="color: #800000;">'</span><span style="color: #800000;">utime</span><span style="color: #800000;">'</span><span style="color: #000000;">):
</span><span style="color: #0000ff;">return</span>
<span style="color: #0000ff;">try</span><span style="color: #000000;">:
os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EnvironmentError, e:
</span><span style="color: #0000ff;">raise</span> ExtractError(<span style="color: #800000;">"</span><span style="color: #800000;">could not change modification time</span><span style="color: #800000;">"</span><span style="color: #000000;">)

</span><span style="color: #008000;">#</span><span style="color: #008000;">--------------------------------------------------------------------------</span>
<span style="color: #0000ff;">def</span><span style="color: #000000;"> next(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Return the next member of the archive as a TarInfo object, when
TarFile is opened for reading. Return None if there is no more
available.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._check(</span><span style="color: #800000;">"</span><span style="color: #800000;">ra</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> self.firstmember <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
m </span>=<span style="color: #000000;"> self.firstmember
self.firstmember </span>=<span style="color: #000000;"> None
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> m

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Read the next block.</span>
<span style="color: #000000;"> self.fileobj.seek(self.offset)
tarinfo </span>=<span style="color: #000000;"> None
</span><span style="color: #0000ff;">while</span><span style="color: #000000;"> True:
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
tarinfo </span>=<span style="color: #000000;"> self.tarinfo.fromtarfile(self)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EOFHeaderError, e:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> self.ignore_zeros:
self._dbg(</span>2, <span style="color: #800000;">"</span><span style="color: #800000;">0x%X: %s</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> (self.offset, e))
self.offset </span>+=<span style="color: #000000;"> BLOCKSIZE
</span><span style="color: #0000ff;">continue</span>
<span style="color: #0000ff;">except</span><span style="color: #000000;"> InvalidHeaderError, e:
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> self.ignore_zeros:
self._dbg(</span>2, <span style="color: #800000;">"</span><span style="color: #800000;">0x%X: %s</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> (self.offset, e))
self.offset </span>+=<span style="color: #000000;"> BLOCKSIZE
</span><span style="color: #0000ff;">continue</span>
<span style="color: #0000ff;">elif</span> self.offset ==<span style="color: #000000;"> 0:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> ReadError(str(e))
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> EmptyHeaderError:
</span><span style="color: #0000ff;">if</span> self.offset ==<span style="color: #000000;"> 0:
</span><span style="color: #0000ff;">raise</span> ReadError(<span style="color: #800000;">"</span><span style="color: #800000;">empty file</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> TruncatedHeaderError, e:
</span><span style="color: #0000ff;">if</span> self.offset ==<span style="color: #000000;"> 0:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> ReadError(str(e))
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> SubsequentHeaderError, e:
</span><span style="color: #0000ff;">raise</span><span style="color: #000000;"> ReadError(str(e))
</span><span style="color: #0000ff;">break</span>

<span style="color: #0000ff;">if</span> tarinfo <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
self.members.append(tarinfo)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
self._loaded </span>=<span style="color: #000000;"> True

</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> tarinfo

</span><span style="color: #008000;">#</span><span style="color: #008000;">--------------------------------------------------------------------------</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Little helper methods:</span>

<span style="color: #0000ff;">def</span> _getmember(self, name, tarinfo=None, normalize=<span style="color: #000000;">False):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Find an archive member by name from bottom to top.
If tarinfo is given, it is used as the starting point.
</span><span style="color: #800000;">"""</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> Ensure that all members have been loaded.</span>
members =<span style="color: #000000;"> self.getmembers()

</span><span style="color: #008000;">#</span><span style="color: #008000;"> Limit the member search list up to tarinfo.</span>
<span style="color: #0000ff;">if</span> tarinfo <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> None:
members </span>=<span style="color: #000000;"> members[:members.index(tarinfo)]

</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> normalize:
name </span>=<span style="color: #000000;"> os.path.normpath(name)

</span><span style="color: #0000ff;">for</span> member <span style="color: #0000ff;">in</span><span style="color: #000000;"> reversed(members):
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> normalize:
member_name </span>=<span style="color: #000000;"> os.path.normpath(member.name)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
member_name </span>=<span style="color: #000000;"> member.name

</span><span style="color: #0000ff;">if</span> name ==<span style="color: #000000;"> member_name:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> member

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> _load(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Read through the entire archive file and look for readable
members.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">while</span><span style="color: #000000;"> True:
tarinfo </span>=<span style="color: #000000;"> self.next()
</span><span style="color: #0000ff;">if</span> tarinfo <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">break</span><span style="color: #000000;">
self._loaded </span>=<span style="color: #000000;"> True

</span><span style="color: #0000ff;">def</span> _check(self, mode=<span style="color: #000000;">None):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Check if TarFile is still open, and if the operation's mode
corresponds to TarFile's mode.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> self.closed:
</span><span style="color: #0000ff;">raise</span> IOError(<span style="color: #800000;">"</span><span style="color: #800000;">%s is closed</span><span style="color: #800000;">"</span> % self.<span style="color: #800080;">__class__</span>.<span style="color: #800080;">__name__</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> mode <span style="color: #0000ff;">is</span> <span style="color: #0000ff;">not</span> None <span style="color: #0000ff;">and</span> self.mode <span style="color: #0000ff;">not</span> <span style="color: #0000ff;">in</span><span style="color: #000000;"> mode:
</span><span style="color: #0000ff;">raise</span> IOError(<span style="color: #800000;">"</span><span style="color: #800000;">bad operation for mode %r</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> self.mode)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> _find_link_target(self, tarinfo):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Find the target member of a symlink or hardlink member in the
archive.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> tarinfo.issym():
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Always search the entire archive.</span>
linkname = <span style="color: #800000;">"</span><span style="color: #800000;">/</span><span style="color: #800000;">"</span><span style="color: #000000;">.join(filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname)))
limit </span>=<span style="color: #000000;"> None
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Search the archive before the link, because a hard link is</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> just a reference to an already archived file.</span>
linkname =<span style="color: #000000;"> tarinfo.linkname
limit </span>=<span style="color: #000000;"> tarinfo

member </span>= self._getmember(linkname, tarinfo=limit, normalize=<span style="color: #000000;">True)
</span><span style="color: #0000ff;">if</span> member <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
</span><span style="color: #0000ff;">raise</span> KeyError(<span style="color: #800000;">"</span><span style="color: #800000;">linkname %r not found</span><span style="color: #800000;">"</span> %<span style="color: #000000;"> linkname)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> member

</span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__iter__</span><span style="color: #000000;">(self):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Provide an iterator object.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span><span style="color: #000000;"> self._loaded:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> iter(self.members)
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> TarIter(self)

</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> _dbg(self, level, msg):
</span><span style="color: #800000;">"""</span><span style="color: #800000;">Write debugging output to sys.stderr.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> level &lt;=<span style="color: #000000;"> self.debug:
</span><span style="color: #0000ff;">print</span> &gt;&gt;<span style="color: #000000;"> sys.stderr, msg

</span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__enter__</span><span style="color: #000000;">(self):
self._check()
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> self

</span><span style="color: #0000ff;">def</span> <span style="color: #800080;">__exit__</span><span style="color: #000000;">(self, type, value, traceback):
</span><span style="color: #0000ff;">if</span> type <span style="color: #0000ff;">is</span><span style="color: #000000;"> None:
self.close()
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
</span><span style="color: #008000;">#</span><span style="color: #008000;"> An exception occurred. We must not call close() because</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> it would try to write end-of-archive blocks and padding.</span>
<span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> self._extfileobj:
self.fileobj.close()
self.closed </span>=<span style="color: #000000;"> True
</span><span style="color: #008000;">#</span><span style="color: #008000;"> class TarFile</span></pre>
</div>
<span class="cnblogs_code_collapse">TarFile</span>&nbsp;</div>
<p><strong><span style="font-size: 18px;">七、ConfigParser</span></strong></p>
<p>用于对特定的配置进行操作,当前模块的名称在 python 3.x 版本中变更为 configparser。</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_311582" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python comments"># 注释1</code></div><div class="line number2 index1 alt1"><code class="python plain">; 注释</code><code class="python value">2</code></div><div class="line number3 index2 alt2">&nbsp;</div><div class="line number4 index3 alt1"><code class="python plain">[section1]</code></div><div class="line number5 index4 alt2"><code class="python plain">k1 </code><code class="python keyword">=</code> <code class="python plain">v1</code></div><div class="line number6 index5 alt1"><code class="python plain">k2:v2</code></div><div class="line number7 index6 alt2">&nbsp;</div><div class="line number8 index7 alt1"><code class="python plain">[section2]</code></div><div class="line number9 index8 alt2"><code class="python plain">k1 </code><code class="python keyword">=</code> <code class="python plain">v1</code></div></div></td></tr></tbody></table></div></div>
</div>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_674463" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div><div class="line number26 index25 alt1">26</div><div class="line number27 index26 alt2">27</div><div class="line number28 index27 alt1">28</div><div class="line number29 index28 alt2">29</div><div class="line number30 index29 alt1">30</div><div class="line number31 index30 alt2">31</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">ConfigParser</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2"><code class="python plain">config </code><code class="python keyword">=</code> <code class="python plain">ConfigParser.ConfigParser()</code></div><div class="line number4 index3 alt1"><code class="python plain">config.read(</code><code class="python string">'i.cfg'</code><code class="python plain">)</code></div><div class="line number5 index4 alt2">&nbsp;</div><div class="line number6 index5 alt1"><code class="python comments"># ########## 读 ##########</code></div><div class="line number7 index6 alt2"><code class="python comments">#secs = config.sections()</code></div><div class="line number8 index7 alt1"><code class="python comments">#print secs</code></div><div class="line number9 index8 alt2"><code class="python comments">#options = config.options('group2')</code></div><div class="line number10 index9 alt1"><code class="python comments">#print options</code></div><div class="line number11 index10 alt2">&nbsp;</div><div class="line number12 index11 alt1"><code class="python comments">#item_list = config.items('group2')</code></div><div class="line number13 index12 alt2"><code class="python comments">#print item_list</code></div><div class="line number14 index13 alt1">&nbsp;</div><div class="line number15 index14 alt2"><code class="python comments">#val = config.get('group1','key')</code></div><div class="line number16 index15 alt1"><code class="python comments">#val = config.getint('group1','key')</code></div><div class="line number17 index16 alt2">&nbsp;</div><div class="line number18 index17 alt1"><code class="python comments"># ########## 改写 ##########</code></div><div class="line number19 index18 alt2"><code class="python comments">#sec = config.remove_section('group1')</code></div><div class="line number20 index19 alt1"><code class="python comments">#config.write(open('i.cfg', "w"))</code></div><div class="line number21 index20 alt2">&nbsp;</div><div class="line number22 index21 alt1"><code class="python comments">#sec = config.has_section('wupeiqi')</code></div><div class="line number23 index22 alt2"><code class="python comments">#sec = config.add_section('wupeiqi')</code></div><div class="line number24 index23 alt1"><code class="python comments">#config.write(open('i.cfg', "w"))</code></div><div class="line number25 index24 alt2">&nbsp;</div><div class="line number26 index25 alt1">&nbsp;</div><div class="line number27 index26 alt2"><code class="python comments">#config.set('group2','k1',11111)</code></div><div class="line number28 index27 alt1"><code class="python comments">#config.write(open('i.cfg', "w"))</code></div><div class="line number29 index28 alt2">&nbsp;</div><div class="line number30 index29 alt1"><code class="python comments">#config.remove_option('group2','age')</code></div><div class="line number31 index30 alt2"><code class="python comments">#config.write(open('i.cfg', "w"))</code></div></div></td></tr></tbody></table></div></div>
</div>
<p><span style="font-size: 18px;"><strong>八、logging</strong></span></p>
<p>用于便捷记录日志且线程安全的模块</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_364925" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">logging</code></div><div class="line number2 index1 alt1">&nbsp;</div><div class="line number3 index2 alt2">&nbsp;</div><div class="line number4 index3 alt1"><code class="python plain">logging.basicConfig(filename</code><code class="python keyword">=</code><code class="python string">'log.log'</code><code class="python plain">,</code></div><div class="line number5 index4 alt2"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python functions">format</code><code class="python keyword">=</code><code class="python string">'%(asctime)s - %(name)s - %(levelname)s -%(module)s:&nbsp; %(message)s'</code><code class="python plain">,</code></div><div class="line number6 index5 alt1"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python plain">datefmt</code><code class="python keyword">=</code><code class="python string">'%Y-%m-%d %H:%M:%S %p'</code><code class="python plain">,</code></div><div class="line number7 index6 alt2"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python plain">level</code><code class="python keyword">=</code><code class="python value">10</code><code class="python plain">)</code></div><div class="line number8 index7 alt1">&nbsp;</div><div class="line number9 index8 alt2"><code class="python plain">logging.debug(</code><code class="python string">'debug'</code><code class="python plain">)</code></div><div class="line number10 index9 alt1"><code class="python plain">logging.info(</code><code class="python string">'info'</code><code class="python plain">)</code></div><div class="line number11 index10 alt2"><code class="python plain">logging.warning(</code><code class="python string">'warning'</code><code class="python plain">)</code></div><div class="line number12 index11 alt1"><code class="python plain">logging.error(</code><code class="python string">'error'</code><code class="python plain">)</code></div><div class="line number13 index12 alt2"><code class="python plain">logging.critical(</code><code class="python string">'critical'</code><code class="python plain">)</code></div><div class="line number14 index13 alt1"><code class="python plain">logging.log(</code><code class="python value">10</code><code class="python plain">,</code><code class="python string">'log'</code><code class="python plain">)</code></div></div></td></tr></tbody></table></div></div>
</div>
<p><strong>对于等级:</strong></p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_955981" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">CRITICAL </code><code class="python keyword">=</code> <code class="python value">50</code></div><div class="line number2 index1 alt1"><code class="python plain">FATAL </code><code class="python keyword">=</code> <code class="python plain">CRITICAL</code></div><div class="line number3 index2 alt2"><code class="python plain">ERROR </code><code class="python keyword">=</code> <code class="python value">40</code></div><div class="line number4 index3 alt1"><code class="python plain">WARNING </code><code class="python keyword">=</code> <code class="python value">30</code></div><div class="line number5 index4 alt2"><code class="python plain">WARN </code><code class="python keyword">=</code> <code class="python plain">WARNING</code></div><div class="line number6 index5 alt1"><code class="python plain">INFO </code><code class="python keyword">=</code> <code class="python value">20</code></div><div class="line number7 index6 alt2"><code class="python plain">DEBUG </code><code class="python keyword">=</code> <code class="python value">10</code></div><div class="line number8 index7 alt1"><code class="python plain">NOTSET </code><code class="python keyword">=</code> <code class="python value">0</code></div></div></td></tr></tbody></table></div></div>
</div>
<p><span style="color: #888888;">只有大于当前日志等级的操作才会被记录。</span></p>
<p><strong>对于格式,有如下属性可是配置:</strong></p>
<p><img src="https://images2015.cnblogs.com/blog/425762/201511/425762-20151121233619577-1645688724.png" alt="" width="677" height="332"></p>
<p><strong><span style="font-size: 18px;">九、time</span></strong></p>
<p>时间相关的操作,时间有三种表示方式:</p>
<ul>
<li>时间戳 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1970年1月1日之后的秒,即:time.time()</li>
<li>格式化的字符串 &nbsp; &nbsp;2014-11-11 11:11, &nbsp; &nbsp;即:time.strftime('%Y-%m-%d')</li>
<li>结构化时间 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;元组包含了:年、日、星期等... time.struct_time &nbsp; &nbsp;即:time.localtime()</li>
</ul>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_190403" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div><div class="line number20 index19 alt1">20</div><div class="line number21 index20 alt2">21</div><div class="line number22 index21 alt1">22</div><div class="line number23 index22 alt2">23</div><div class="line number24 index23 alt1">24</div><div class="line number25 index24 alt2">25</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python functions">print</code> <code class="python plain">time.time()</code></div><div class="line number2 index1 alt1"><code class="python functions">print</code> <code class="python plain">time.mktime(time.localtime())</code></div><div class="line number3 index2 alt2"><code class="python spaces">&nbsp;</code>&nbsp;</div><div class="line number4 index3 alt1"><code class="python functions">print</code> <code class="python plain">time.gmtime()&nbsp;&nbsp;&nbsp; </code><code class="python comments">#可加时间戳参数</code></div><div class="line number5 index4 alt2"><code class="python functions">print</code> <code class="python plain">time.localtime() </code><code class="python comments">#可加时间戳参数</code></div><div class="line number6 index5 alt1"><code class="python functions">print</code> <code class="python plain">time.strptime(</code><code class="python string">'2014-11-11'</code><code class="python plain">, </code><code class="python string">'%Y-%m-%d'</code><code class="python plain">)</code></div><div class="line number7 index6 alt2"><code class="python spaces">&nbsp;</code>&nbsp;</div><div class="line number8 index7 alt1"><code class="python functions">print</code> <code class="python plain">time.strftime(</code><code class="python string">'%Y-%m-%d'</code><code class="python plain">) </code><code class="python comments">#默认当前时间</code></div><div class="line number9 index8 alt2"><code class="python functions">print</code> <code class="python plain">time.strftime(</code><code class="python string">'%Y-%m-%d'</code><code class="python plain">,time.localtime()) </code><code class="python comments">#默认当前时间</code></div><div class="line number10 index9 alt1"><code class="python functions">print</code> <code class="python plain">time.asctime()</code></div><div class="line number11 index10 alt2"><code class="python functions">print</code> <code class="python plain">time.asctime(time.localtime())</code></div><div class="line number12 index11 alt1"><code class="python functions">print</code> <code class="python plain">time.ctime(time.time())</code></div><div class="line number13 index12 alt2"><code class="python spaces">&nbsp;</code>&nbsp;</div><div class="line number14 index13 alt1"><code class="python keyword">import</code> <code class="python plain">datetime</code></div><div class="line number15 index14 alt2"><code class="python comments">'''</code></div><div class="line number16 index15 alt1"><code class="python comments">datetime.date:表示日期的类。常用的属性有year, month, day</code></div><div class="line number17 index16 alt2"><code class="python comments">datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond</code></div><div class="line number18 index17 alt1"><code class="python comments">datetime.datetime:表示日期时间</code></div><div class="line number19 index18 alt2"><code class="python comments">datetime.timedelta:表示时间间隔,即两个时间点之间的长度</code></div><div class="line number20 index19 alt1"><code class="python comments">timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])</code></div><div class="line number21 index20 alt2"><code class="python comments">strftime("%Y-%m-%d")</code></div><div class="line number22 index21 alt1"><code class="python comments">'''</code></div><div class="line number23 index22 alt2"><code class="python keyword">import</code> <code class="python plain">datetime</code></div><div class="line number24 index23 alt1"><code class="python functions">print</code> <code class="python plain">datetime.datetime.now()</code></div><div class="line number25 index24 alt2"><code class="python functions">print</code> <code class="python plain">datetime.datetime.now() </code><code class="python keyword">-</code> <code class="python plain">datetime.timedelta(days</code><code class="python keyword">=</code><code class="python value">5</code><code class="python plain">)</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>&nbsp;<img src="https://images0.cnblogs.com/blog/425762/201412/182222027044557.png" alt="" width="573" height="255"></p>
<p><img src="https://images0.cnblogs.com/blog/425762/201412/182222117511121.png" alt=""></p>
<p><strong><span style="font-size: 18px;">十、re<span style="line-height: 1.5;">&nbsp;</span></span></strong></p>
<p><span style="font-size: 14px; line-height: 1.5;">re模块用于对python的正则表达式的操作。</span></p>
<p><span style="font-size: 14px; line-height: 1.5;">字符:</span></p>
<p>  . 匹配除换行符以外的任意字符<br>  \w 匹配字母或数字或下划线或汉字<br>  \s 匹配任意的空白符<br>  \d 匹配数字<br>  \b 匹配单词的开始或结束<br>  ^ 匹配字符串的开始<br>  $ 匹配字符串的结束</p>
<p>次数:</p>
<p>  * 重复零次或更多次<br>  + 重复一次或更多次<br>  ? 重复零次或一次<br>  {n} 重复n次<br>  {n,} 重复n次或更多次<br>  {n,m} 重复n到m次</p>
<div class="cnblogs_code">
<pre><span style="color: #000000;">IP:
</span>^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3<span style="color: #000000;">}$
手机号:
</span>^1[3|4|5|8][0-9]\d{8}$</pre>
</div>
<p>1、match(pattern, string, flags=0)</p>
<p>从起始位置开始根据模型去字符串中匹配指定内容,匹配单个</p>
<ul>
<li>正则表达式</li>
<li>要匹配的字符串</li>
<li>标志位,用于控制正则表达式的匹配方式</li>
</ul>
<div class="cnblogs_code">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> re

obj </span>= re.match(<span style="color: #800000;">'</span><span style="color: #800000;">\d+</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">123uuasf</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj:
</span><span style="color: #0000ff;">print</span> obj.group()</pre>
</div>
<div class="cnblogs_code" onclick="cnblogs_code_show('b2328c8f-82fc-46f1-a56a-1fd295c962bd')"><img id="code_img_closed_b2328c8f-82fc-46f1-a56a-1fd295c962bd" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b2328c8f-82fc-46f1-a56a-1fd295c962bd" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('b2328c8f-82fc-46f1-a56a-1fd295c962bd',event)" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b2328c8f-82fc-46f1-a56a-1fd295c962bd" class="cnblogs_code_hide">
<pre><span style="color: #008000;">#</span><span style="color: #008000;"> flags</span>
I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE <span style="color: #008000;">#</span><span style="color: #008000;"> ignore case</span>
L = LOCALE = sre_compile.SRE_FLAG_LOCALE <span style="color: #008000;">#</span><span style="color: #008000;"> assume current 8-bit locale</span>
U = UNICODE = sre_compile.SRE_FLAG_UNICODE <span style="color: #008000;">#</span><span style="color: #008000;"> assume unicode locale</span>
M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE <span style="color: #008000;">#</span><span style="color: #008000;"> make anchors look for newline</span>
S = DOTALL = sre_compile.SRE_FLAG_DOTALL <span style="color: #008000;">#</span><span style="color: #008000;"> make dot match newline</span>
X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE <span style="color: #008000;">#</span><span style="color: #008000;"> ignore whitespace and comments</span></pre>
</div>
<span class="cnblogs_code_collapse">flags</span></div>
<p>2、search(pattern, string, flags=0)</p>
<p>根据模型去字符串中匹配指定内容,匹配单个</p>
<div class="cnblogs_code">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> re

obj </span>= re.search(<span style="color: #800000;">'</span><span style="color: #800000;">\d+</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">u123uu888asf</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span><span style="color: #000000;"> obj:
</span><span style="color: #0000ff;">print</span> obj.group()</pre>
</div>
<p>3、group和groups</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div>
<pre>a = <span style="color: #800000;">"</span><span style="color: #800000;">123abc456</span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">print</span> re.search(<span style="color: #800000;">"</span><span style="color: #800000;">([0-9]*)([a-z]*)([0-9]*)</span><span style="color: #800000;">"</span><span style="color: #000000;">, a).group()

</span><span style="color: #0000ff;">print</span> re.search(<span style="color: #800000;">"</span><span style="color: #800000;">([0-9]*)([a-z]*)([0-9]*)</span><span style="color: #800000;">"</span><span style="color: #000000;">, a).group(0)
</span><span style="color: #0000ff;">print</span> re.search(<span style="color: #800000;">"</span><span style="color: #800000;">([0-9]*)([a-z]*)([0-9]*)</span><span style="color: #800000;">"</span>, a).group(1<span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span> re.search(<span style="color: #800000;">"</span><span style="color: #800000;">([0-9]*)([a-z]*)([0-9]*)</span><span style="color: #800000;">"</span>, a).group(2<span style="color: #000000;">)

</span><span style="color: #0000ff;">print</span> re.search(<span style="color: #800000;">"</span><span style="color: #800000;">([0-9]*)([a-z]*)([0-9]*)</span><span style="color: #800000;">"</span>, a).groups()</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div>
<p>4、findall(pattern, string, flags=0)</p>
<p>上述两中方式均用于匹配单值,即:只能匹配字符串中的一个,如果想要匹配到字符串中所有符合条件的元素,则需要使用&nbsp;findall。</p>
<div class="cnblogs_code">
<pre><span style="color: #0000ff;">import</span><span style="color: #000000;"> re

obj </span>= re.findall(<span style="color: #800000;">'</span><span style="color: #800000;">\d+</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'fa</span><span style="color: #800000;">123uu888asf</span><span style="color: #800000;">'</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span> obj</pre>
</div>
<p>5、sub(pattern, repl, string, count=0, flags=0)</p>
<p>用于替换匹配的字符串</p>
<div class="cnblogs_code">
<pre>content = <span style="color: #800000;">"</span><span style="color: #800000;">123abc456</span><span style="color: #800000;">"</span><span style="color: #000000;">
new_content </span>= re.sub(<span style="color: #800000;">'</span><span style="color: #800000;">\d+</span><span style="color: #800000;">'</span>, <span style="color: #800000;">'</span><span style="color: #800000;">sb</span><span style="color: #800000;">'</span><span style="color: #000000;">, content)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> new_content = re.sub('\d+', 'sb', content, 1)</span>
<span style="color: #0000ff;">print</span> new_content</pre>
</div>
<p>相比于str.replace功能更加强大</p>
<p>6、split(pattern, string, maxsplit=0, flags=0)</p>
<p>根据指定匹配进行分组</p>
<div class="cnblogs_code">
<pre>content = <span style="color: #800000;">"</span><span style="color: #800000;">'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'</span><span style="color: #800000;">"</span><span style="color: #000000;">
new_content </span>= re.split(<span style="color: #800000;">'</span><span style="color: #800000;">\*</span><span style="color: #800000;">'</span><span style="color: #000000;">, content)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> new_content = re.split('\*', content, 1)</span>
<span style="color: #0000ff;">print</span> new_content</pre>
</div>
<div class="cnblogs_code">
<pre>content = <span style="color: #800000;">"</span><span style="color: #800000;">'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'</span><span style="color: #800000;">"</span><span style="color: #000000;">
new_content </span>= re.split(<span style="color: #800000;">'</span><span style="color: #800000;">[\+\-\*\/]+</span><span style="color: #800000;">'</span><span style="color: #000000;">, content)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> new_content = re.split('\*', content, 1)</span>
<span style="color: #0000ff;">print</span> new_content</pre>
</div>
<div class="cnblogs_code">
<pre>inpp = <span style="color: #800000;">'</span><span style="color: #800000;">1-2*((60-30 +(-40-5)*(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))</span><span style="color: #800000;">'</span><span style="color: #000000;">
inpp </span>= re.sub(<span style="color: #800000;">'</span><span style="color: #800000;">\s*</span><span style="color: #800000;">'</span>,<span style="color: #800000;">''</span><span style="color: #000000;">,inpp)
new_content </span>= re.split(<span style="color: #800000;">'</span><span style="color: #800000;">\(([\+\-\*\/]?\d+[\+\-\*\/]?\d+){1}\)</span><span style="color: #800000;">'</span>, inpp, 1<span style="color: #000000;">)
</span><span style="color: #0000ff;">print</span> new_content</pre>
</div>
<p>相比于str.split更加强大&nbsp;&nbsp;</p>
<p>实例:<a href="http://www.cnblogs.com/wupeiqi/articles/4949995.html" target="_blank">计算器源码</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p><span style="font-size: 18px;"><strong>十一、random</strong></span></p>
<p>随机数</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_620228" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python plain">mport random</code></div><div class="line number2 index1 alt1"><code class="python functions">print</code> <code class="python plain">random.random()</code></div><div class="line number3 index2 alt2"><code class="python functions">print</code> <code class="python plain">random.randint(</code><code class="python value">1</code><code class="python plain">,</code><code class="python value">2</code><code class="python plain">)</code></div><div class="line number4 index3 alt1"><code class="python functions">print</code> <code class="python plain">random.randrange(</code><code class="python value">1</code><code class="python plain">,</code><code class="python value">10</code><code class="python plain">)</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>随机验证码实例:</p>
<div class="cnblogs_Highlighter sh-gutter">
<div><div id="highlighter_471157" class="syntaxhighlighter python"><div class="toolbar"><span><a href="#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="python keyword">import</code> <code class="python plain">random</code></div><div class="line number2 index1 alt1"><code class="python plain">checkcode </code><code class="python keyword">=</code> <code class="python plain">''</code></div><div class="line number3 index2 alt2"><code class="python keyword">for</code> <code class="python plain">i </code><code class="python keyword">in</code> <code class="python functions">range</code><code class="python plain">(</code><code class="python value">4</code><code class="python plain">):</code></div><div class="line number4 index3 alt1"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python plain">current </code><code class="python keyword">=</code> <code class="python plain">random.randrange(</code><code class="python value">0</code><code class="python plain">,</code><code class="python value">4</code><code class="python plain">)</code></div><div class="line number5 index4 alt2"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python keyword">if</code> <code class="python plain">current !</code><code class="python keyword">=</code> <code class="python plain">i:</code></div><div class="line number6 index5 alt1"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python plain">temp </code><code class="python keyword">=</code> <code class="python functions">chr</code><code class="python plain">(random.randint(</code><code class="python value">65</code><code class="python plain">,</code><code class="python value">90</code><code class="python plain">))</code></div><div class="line number7 index6 alt2"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python keyword">else</code><code class="python plain">:</code></div><div class="line number8 index7 alt1"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python plain">temp </code><code class="python keyword">=</code> <code class="python plain">random.randint(</code><code class="python value">0</code><code class="python plain">,</code><code class="python value">9</code><code class="python plain">)</code></div><div class="line number9 index8 alt2"><code class="python spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="python plain">checkcode </code><code class="python keyword">+</code><code class="python keyword">=</code> <code class="python functions">str</code><code class="python plain">(temp)</code></div><div class="line number10 index9 alt1"><code class="python functions">print</code> <code class="python plain">checkcode</code></div></div></td></tr></tbody></table></div></div>
</div>
<p>  </p>
<p>&nbsp;</p></div><div id="MySignature" style="display: block;"><div id="AllanboltSignature">
<div style="border-bottom: #e0e0e0 1px dashed; border-left: #e0e0e0 1px dashed; padding: 10px; font-family: 微软雅黑; font-size: 11px; border-top: #e0e0e0 1px dashed; border-right: #e0e0e0 1px dashed; " id="PSignature">
<div style="float:left;width:10%;">
<img src="https://images.cnblogs.com/cnblogs_com/wupeiqi/662608/o_Warning.png" style="width:70px;height:70px">
</div>
<div style="float:left;width:90%;padding-top:10px;">
作者:<a href="http://www.cnblogs.com/wupeiqi/" target="_blank">武沛齐</a> <br>
出处:<a href="http://www.cnblogs.com/wupeiqi/" target="_blank">http://www.cnblogs.com/wupeiqi/</a> <br>
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。<br>
</div>
<div style="clear:both;"></div>
</div>
</div></div>
<div class="clear"></div>
<div id="blog_post_info_block">
<div id="BlogPostCategory"></div>
<div id="EntryTag"></div>
<div id="blog_post_info"><div id="green_channel">
<a href="javascript:void(0);" id="green_channel_digg" onclick="DiggIt(4963027,cb_blogId,1);green_channel_success(this,'谢谢推荐!');">好文要顶</a>
<a id="green_channel_follow" onclick="follow('7208b24d-95c9-e111-aa3f-842b2b196315');" href="javascript:void(0);">关注我</a>
<a id="green_channel_favorite" onclick="AddToWz(cb_entryId);return false;" href="javascript:void(0);">收藏该文</a>
<a id="green_channel_weibo" href="javascript:void(0);" title="分享至新浪微博" onclick="ShareToTsina()"><img src="//common.cnblogs.com/images/icon_weibo_24.png" alt=""></a>
<a id="green_channel_wechat" href="javascript:void(0);" title="分享至微信" onclick="shareOnWechat()"><img src="//common.cnblogs.com/images/wechat.png" alt=""></a>
</div>
<div id="author_profile">
<div id="author_profile_info" class="author_profile_info">
<a href="http://home.cnblogs.com/u/wupeiqi/" target="_blank"><img src="//pic.cnblogs.com/face/425762/20130809170024.png" class="author_avatar" alt=""></a>
<div id="author_profile_detail" class="author_profile_info">
<a href="http://home.cnblogs.com/u/wupeiqi/">武沛齐</a><br>
<a href="http://home.cnblogs.com/u/wupeiqi/followees">关注 - 44</a><br>
<a href="http://home.cnblogs.com/u/wupeiqi/followers">粉丝 - 7475</a>
</div>
</div>
<div class="clear"></div>
<div id="author_profile_honor"></div>
<div id="author_profile_follow">
<a href="javascript:void(0);" onclick="follow('7208b24d-95c9-e111-aa3f-842b2b196315');return false;">+加关注</a>
</div>
</div>
<div id="div_digg">
<div class="diggit" onclick="votePost(4963027,'Digg')">
<span class="diggnum" id="digg_count">9</span>
</div>
<div class="buryit" onclick="votePost(4963027,'Bury')">
<span class="burynum" id="bury_count">0</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
<script type="text/javascript">
currentDiggType = 0;
</script></div>
<div class="clear"></div>
<div id="post_next_prev"><a href="https://www.cnblogs.com/wupeiqi/articles/4950799.html" class="p_n_p_prefix">« </a> 上一篇:<a href="https://www.cnblogs.com/wupeiqi/articles/4950799.html" title="发布于2015-11-09 18:56">s11 day3 作业详细</a><br><a href="https://www.cnblogs.com/wupeiqi/articles/4980620.html" class="p_n_p_prefix">» </a> 下一篇:<a href="https://www.cnblogs.com/wupeiqi/articles/4980620.html" title="发布于2015-11-20 14:23">python 装饰器</a><br></div>
</div>


</div>
<div class="postDesc">posted @ <span id="post-date">2015-11-13 18:28</span> <a href="https://www.cnblogs.com/wupeiqi/">武沛齐</a> 阅读(<span id="post_view_count">36141</span>) 评论(<span id="post_comment_count">12</span>) &nbsp;<a href="https://i.cnblogs.com/EditArticles.aspx?postid=4963027" rel="nofollow">编辑</a> <a href="#" onclick="AddToWz(4963027);return false;">收藏</a></div>
</div>
<script type="text/javascript">var allowComments=true,cb_blogId=133379,cb_entryId=4963027,cb_blogApp=currentBlogApp,cb_blogUserGuid='7208b24d-95c9-e111-aa3f-842b2b196315',cb_entryCreatedDate='2015/11/13 18:28:00';loadViewCount(cb_entryId);var cb_postType=2;var isMarkdown=false;</script>

</div><!--end: topics 文章、评论容器-->
</div><a name="!comments"></a><div id="blog-comments-placeholder"><div id="comments_pager_top"></div>
<!--done-->
<div class="feedback_area_title">评论列表</div>
<div class="feedbackNoItems"></div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3313550,'HT37vD+D9KHJXTEJkB1y+kX0LZZ4FuYygbZfXQaQKCo+8E+hDvo7tw==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3313550,'HT37vD+D9KHJXTEJkB1y+kX0LZZ4FuYygbZfXQaQKCo+8E+hDvo7tw==')">引用</a></span>
</div>
<a href="#3313550" class="layer">#1楼</a><a name="3313550" id="comment_anchor_3313550"></a> <span class="comment_date">2015-11-25 11:08</span> <a id="a_comment_author_3313550" href="http://home.cnblogs.com/u/741896/" target="_blank">雨沧海</a> <a href="http://msg.cnblogs.com/send/%E9%9B%A8%E6%B2%A7%E6%B5%B7" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3313550" class="blog_comment_body">牛牛牛~</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3313550,'Digg',this)">支持(1)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3313550,'Bury',this)">反对(0)</a></div>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3313551,'HT37vD+D9KHJXTEJkB1y+kX0LZZ4FuYygbZfXQaQKCo+8E+hDvo7tw==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3313551,'HT37vD+D9KHJXTEJkB1y+kX0LZZ4FuYygbZfXQaQKCo+8E+hDvo7tw==')">引用</a></span>
</div>
<a href="#3313551" class="layer">#2楼</a><a name="3313551" id="comment_anchor_3313551"></a> <span class="comment_date">2015-11-25 11:08</span> <a id="a_comment_author_3313551" href="http://home.cnblogs.com/u/741896/" target="_blank">雨沧海</a> <a href="http://msg.cnblogs.com/send/%E9%9B%A8%E6%B2%A7%E6%B5%B7" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3313551" class="blog_comment_body">66666666</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3313551,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3313551,'Bury',this)">反对(0)</a></div>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3352507,'c0o2wThEocSe8xXNLVW3XoE3dW8b4QZ89nHgtYa0+PZRG9ojuGyV6g==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3352507,'c0o2wThEocSe8xXNLVW3XoE3dW8b4QZ89nHgtYa0+PZRG9ojuGyV6g==')">引用</a></span>
</div>
<a href="#3352507" class="layer">#3楼</a><a name="3352507" id="comment_anchor_3352507"></a> <span class="comment_date">2016-01-22 14:55</span> <a id="a_comment_author_3352507" href="http://home.cnblogs.com/u/789310/" target="_blank">Eric_Young</a> <a href="http://msg.cnblogs.com/send/Eric_Young" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3352507" class="blog_comment_body">66666666666666666666666666666666</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3352507,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3352507,'Bury',this)">反对(0)</a></div>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3367007,'ZvJl15mrzzqoyI/DTG9+RRstnZWFrOMNsdg1GYdTXX8+nQa7PbKsLw==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3367007,'ZvJl15mrzzqoyI/DTG9+RRstnZWFrOMNsdg1GYdTXX8+nQa7PbKsLw==')">引用</a></span>
</div>
<a href="#3367007" class="layer">#4楼</a><a name="3367007" id="comment_anchor_3367007"></a> <span class="comment_date">2016-02-25 23:37</span> <a id="a_comment_author_3367007" href="http://home.cnblogs.com/u/875872/" target="_blank">cuiwenjuan</a> <a href="http://msg.cnblogs.com/send/cuiwenjuan" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3367007" class="blog_comment_body">写博客是一种习惯么,我怎么就没有这种习惯呢</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3367007,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3367007,'Bury',this)">反对(0)</a></div>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3367117,'9cszJ1gxd2GuUXWly6+ugmBtkQt2qDCRSz6OwsikquheZegiGFZfUQ==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3367117,'9cszJ1gxd2GuUXWly6+ugmBtkQt2qDCRSz6OwsikquheZegiGFZfUQ==')">引用</a></span>
</div>
<a href="#3367117" class="layer">#5楼</a><a name="3367117" id="comment_anchor_3367117"></a>[<span class="louzhu">楼主</span>] <span class="comment_date">2016-02-26 10:19</span> <a id="a_comment_author_3367117" href="https://www.cnblogs.com/wupeiqi/" target="_blank">武沛齐</a> <a href="http://msg.cnblogs.com/send/%E6%AD%A6%E6%B2%9B%E9%BD%90" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3367117" class="blog_comment_body"><a href="#3367007" title="查看所回复的评论" onclick="commentManager.renderComments(0,50,3367007);">@</a>
cuiwenjuan<br>这是好习惯,所以一直建议你们来写,慢慢培养咯</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3367117,'Digg',this)">支持(2)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3367117,'Bury',this)">反对(0)</a></div><span id="comment_3367117_avatar" style="display:none;">http://pic.cnblogs.com/face/425762/20130809170024.png</span>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3475449,'nDkDp+vr7cKsRhFzmBkyQhzyF1FvVYKqaZiUwz/eCB7ijAuTOTzZWg==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3475449,'nDkDp+vr7cKsRhFzmBkyQhzyF1FvVYKqaZiUwz/eCB7ijAuTOTzZWg==')">引用</a></span>
</div>
<a href="#3475449" class="layer">#6楼</a><a name="3475449" id="comment_anchor_3475449"></a> <span class="comment_date">2016-07-23 20:50</span> <a id="a_comment_author_3475449" href="https://www.cnblogs.com/zwei0227/" target="_blank">zwei0227</a> <a href="http://msg.cnblogs.com/send/zwei0227" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3475449" class="blog_comment_body">沛齐老师:你好!我看了你的51上的<a href="http://edu.51cto.com/course/course_id-5065.html" target="_blank">http://edu.51cto.com/course/course_id-5065.html</a><br><br>讲的挺好的,但是这个上面只有基础,找不到接下来的部分了。。。。<br><br>请问在哪里能看到啊???</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3475449,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3475449,'Bury',this)">反对(0)</a></div><span id="comment_3475449_avatar" style="display:none;">http://pic.cnblogs.com/face/996619/20160818235759.png</span>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3475901,'9cszJ1gxd2GuUXWly6+ugmBtkQt2qDCRSz6OwsikquheZegiGFZfUQ==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3475901,'9cszJ1gxd2GuUXWly6+ugmBtkQt2qDCRSz6OwsikquheZegiGFZfUQ==')">引用</a></span>
</div>
<a href="#3475901" class="layer">#7楼</a><a name="3475901" id="comment_anchor_3475901"></a>[<span class="louzhu">楼主</span>] <span class="comment_date">2016-07-25 10:14</span> <a id="a_comment_author_3475901" href="https://www.cnblogs.com/wupeiqi/" target="_blank">武沛齐</a> <a href="http://msg.cnblogs.com/send/%E6%AD%A6%E6%B2%9B%E9%BD%90" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3475901" class="blog_comment_body"><a href="#3475449" title="查看所回复的评论" onclick="commentManager.renderComments(0,50,3475449);">@</a>
zwei0227<br>python之路有目录</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3475901,'Digg',this)">支持(1)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3475901,'Bury',this)">反对(0)</a></div><span id="comment_3475901_avatar" style="display:none;">http://pic.cnblogs.com/face/425762/20130809170024.png</span>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3476534,'nDkDp+vr7cKsRhFzmBkyQhzyF1FvVYKqaZiUwz/eCB7ijAuTOTzZWg==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3476534,'nDkDp+vr7cKsRhFzmBkyQhzyF1FvVYKqaZiUwz/eCB7ijAuTOTzZWg==')">引用</a></span>
</div>
<a href="#3476534" class="layer">#8楼</a><a name="3476534" id="comment_anchor_3476534"></a> <span class="comment_date">2016-07-26 00:44</span> <a id="a_comment_author_3476534" href="https://www.cnblogs.com/zwei0227/" target="_blank">zwei0227</a> <a href="http://msg.cnblogs.com/send/zwei0227" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3476534" class="blog_comment_body">我想问 哪里还有这一期接下来的视频,因为我是在西安,去北京也不方便,花费还大。</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3476534,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3476534,'Bury',this)">反对(0)</a></div><span id="comment_3476534_avatar" style="display:none;">http://pic.cnblogs.com/face/996619/20160818235759.png</span>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3476546,'9cszJ1gxd2GuUXWly6+ugmBtkQt2qDCRSz6OwsikquheZegiGFZfUQ==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3476546,'9cszJ1gxd2GuUXWly6+ugmBtkQt2qDCRSz6OwsikquheZegiGFZfUQ==')">引用</a></span>
</div>
<a href="#3476546" class="layer">#9楼</a><a name="3476546" id="comment_anchor_3476546"></a>[<span class="louzhu">楼主</span>] <span class="comment_date">2016-07-26 07:37</span> <a id="a_comment_author_3476546" href="https://www.cnblogs.com/wupeiqi/" target="_blank">武沛齐</a> <a href="http://msg.cnblogs.com/send/%E6%AD%A6%E6%B2%9B%E9%BD%90" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3476546" class="blog_comment_body"><a href="#3476534" title="查看所回复的评论" onclick="commentManager.renderComments(0,50,3476534);">@</a>
zwei0227<br>有网络班的课程哦,详细咨询客服:<a href="http://www.oldboyedu.com/" target="_blank">http://www.oldboyedu.com/</a></div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3476546,'Digg',this)">支持(1)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3476546,'Bury',this)">反对(0)</a></div><span id="comment_3476546_avatar" style="display:none;">http://pic.cnblogs.com/face/425762/20130809170024.png</span>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3486726,'yeP1LrPa2oE/HS7nCHyY8ty6ziYzma4wraNtJSPU5kd8JkbyoSFYew==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3486726,'yeP1LrPa2oE/HS7nCHyY8ty6ziYzma4wraNtJSPU5kd8JkbyoSFYew==')">引用</a></span>
</div>
<a href="#3486726" class="layer">#10楼</a><a name="3486726" id="comment_anchor_3486726"></a> <span class="comment_date">2016-08-10 13:56</span> <a id="a_comment_author_3486726" href="http://home.cnblogs.com/u/1006734/" target="_blank">大牙兔</a> <a href="http://msg.cnblogs.com/send/%E5%A4%A7%E7%89%99%E5%85%94" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3486726" class="blog_comment_body">武老师,讲的大赞。</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3486726,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3486726,'Bury',this)">反对(0)</a></div>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3491434,'yeP1LrPa2oE/HS7nCHyY8ty6ziYzma4wraNtJSPU5kd8JkbyoSFYew==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3491434,'yeP1LrPa2oE/HS7nCHyY8ty6ziYzma4wraNtJSPU5kd8JkbyoSFYew==')">引用</a></span>
</div>
<a href="#3491434" class="layer">#11楼</a><a name="3491434" id="comment_anchor_3491434"></a> <span class="comment_date">2016-08-18 11:03</span> <a id="a_comment_author_3491434" href="http://home.cnblogs.com/u/1006734/" target="_blank">大牙兔</a> <a href="http://msg.cnblogs.com/send/%E5%A4%A7%E7%89%99%E5%85%94" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3491434" class="blog_comment_body">赞赞赞</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3491434,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3491434,'Bury',this)">反对(0)</a></div>
</div>
</div>

<div class="feedbackItem">
<div class="feedbackListSubtitle">
<div class="feedbackManage">
&nbsp;&nbsp;<span class="comment_actions"><a href="javascript:void(0);" onclick="return ReplyComment(3855095,'NO4LIPswXsiXjVejb/9Y3iqcf+cTIamvNeF4MMb9Wop9QaRWaqo1MQ==')">回复</a><a href="javascript:void(0);" onclick="return QuoteComment(3855095,'NO4LIPswXsiXjVejb/9Y3iqcf+cTIamvNeF4MMb9Wop9QaRWaqo1MQ==')">引用</a></span>
</div>
<a href="#3855095" class="layer">#12楼</a><a name="3855095" id="comment_anchor_3855095"></a><span id="comment-maxId" style="display:none;">3855095</span><span id="comment-maxDate" style="display:none;">2017/11/30 23:12:52</span> <span class="comment_date">2017-11-30 23:12</span> <a id="a_comment_author_3855095" href="https://www.cnblogs.com/xiashuai-future/" target="_blank">骨灰级帅锅</a> <a href="http://msg.cnblogs.com/send/%E9%AA%A8%E7%81%B0%E7%BA%A7%E5%B8%85%E9%94%85" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
</div>
<div class="feedbackCon">
<div id="comment_body_3855095" class="blog_comment_body">虽然我是个男的,但是我还是要说,爱死你了武老师,你的学习资料真滴大有用处,路转粉</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(3855095,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" onclick="return voteComment(3855095,'Bury',this)">反对(0)</a></div>
</div>
</div>
<div id="comments_pager_bottom"></div></div><script type="text/javascript">var commentManager = new blogCommentManager();commentManager.renderComments(0);</script>
<div id="comment_form" class="commentform">
<a name="commentform"></a>
<div id="divCommentShow"></div>
<div id="comment_nav"><span id="span_refresh_tips"></span><a href="javascript:void(0);" onclick="return RefreshCommentList();" id="lnk_RefreshComments" runat="server" clientidmode="Static">刷新评论</a><a href="#" onclick="return RefreshPage();">刷新页面</a><a href="#top">返回顶部</a></div>
<div id="comment_form_container"><script type="text/javascript" src="//mention.cnblogs.com/bundles/mention.js?id=20160615"></script>
<div id="commentform_title">发表评论</div>
<span id="tip_comment" style="color:Red"></span>
<p>
昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="*心向阳*">
</p>
<div class="commentbox_main">
<div class="commentbox_title">
<div class="commentbox_title_left">评论内容:</div>
<div class="commentbox_title_right">
<img id="ubb_quote" class="comment_icon" src="//static.cnblogs.com/images/ubb/quote.gif" alt="引用" title="添加引用" onclick="insertUBB('tbCommentBody','quote')">
<img id="ubb_bold" class="comment_icon" src="//static.cnblogs.com/images/ubb/b.png" alt="粗体" title="添加粗体" onclick="insertUBB('tbCommentBody','b')">
<img id="ubb_url" class="comment_icon" src="//static.cnblogs.com/images/ubb/lk.png" alt="链接" title="添加链接" onclick="insertUbbUrl('tbCommentBody')">
<img id="ubb_indent" class="comment_icon" src="//static.cnblogs.com/images/ubb/indent.png" alt="缩进" title="添加首行缩进" onclick="insertIndent('tbCommentBody')">
<img id="ubb_code" class="comment_icon" src="//static.cnblogs.com/images/ubb/InsertCode.gif" alt="代码" title="添加代码" onclick="insertUbbCode()">
<img id="ubb_img" class="comment_icon" src="//static.cnblogs.com/images/ubb/img.gif" alt="图片" title="上传图片" onclick="OpenImageUploadWindow();">
</div>
</div>
<div class="clear"></div>
<textarea id="tbCommentBody" class="comment_textarea"></textarea>
</div>
<p id="commentbox_opt">
<input id="btn_comment_submit" type="button" class="comment_btn" value="提交评论">
<span id="span_comment_canceledit" style="display:none"><a href="javascript:void(0);" onclick="return CancelCommentEdit()">不改了</a></span>
<a href="javascript:void(0);" onclick="return logout();">退出</a>
<a id="commentbox_opt_sub" href="javascript:void(0);" title="订阅后有新评论时会邮件通知您" onclick="commentManager.Subscribe()">订阅评论</a>
</p>
<div id="tip_comment2" style="color:Red"></div>
<p>
[Ctrl+Enter快捷键提交]
</p>
<div style="display:none">
<span id="comment_edit_id"></span><span id="span_parentcomment_id"></span>
<span id="span_parent_id"></span>
<span id="span_comment_replyto"></span>
<span id="span_comment_posted"></span>
</div>
</div>
<div class="ad_text_commentbox" id="ad_text_under_commentbox"></div>
<div id="ad_t2"><a href="http://www.ucancode.com/index.htm" target="_blank" onclick="ga('send', 'event', 'Link', 'click', 'T2-工控')">【推荐】超50万C++/C#源码: 大型实时仿真组态图形源码</a><br><a href="https://cloud.baidu.com/campaign/purchase-2019/index.html?track=cp:dsp|pf:pc|pp:chui-bokeyuan-huodong-19caigouji-BCC-neiyeCH-190311|pu:neiyeCH-wenzilian|ci:2019cgj|kw:2105959" target="_blank" onclick="ga('send', 'event', 'Link', 'click', 'T2-百度云')">【推荐】百度云“猪”你开年行大运,红包疯狂拿,低至1折</a><br><a href="https://gitee.com/enterprises?from=bky-2" target="_blank" onclick="ga('send', 'event', 'Link', 'click', 'T2-gitee')">【推荐】专业便捷的企业级代码托管服务 - Gitee 码云</a><br><a href="https://www.bagevent.com/event/2468856" target="_blank" onclick="ga('send', 'event', 'Link', 'click', 'T2-GAITC')">【活动】2019第四届全球人工技术大会解码“智能+时代”</a><br></div>
<div id="opt_under_post"></div>
<script async="async" src="https://www.googletagservices.com/tag/js/gpt.js"></script>
<script>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
</script>
<script>
googletag.cmd.push(function() {
googletag.defineSlot('/1090369/C1', [300, 250], 'div-gpt-ad-1546353474406-0').addService(googletag.pubads());
googletag.defineSlot('/1090369/C2', [468, 60], 'div-gpt-ad-1539008685004-0').addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>
<div id="cnblogs_c1" class="c_ad_block">
<div id="div-gpt-ad-1546353474406-0" style="height:250px; width:300px;" data-google-query-id="CPnOzNCds-ECFQdviwodQhkOjg"><div id="google_ads_iframe_/1090369/C1_0__container__" style="border: 0pt none;"><iframe id="google_ads_iframe_/1090369/C1_0" title="3rd party ad content" name="google_ads_iframe_/1090369/C1_0" width="300" height="250" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" srcdoc="" data-google-container-id="1" style="border: 0px; vertical-align: bottom;" data-load-complete="true"></iframe></div></div>
</div>
<div id="under_post_news"><div class="itnews c_ad_block"><b>相关博文:</b><br>· <a href="https://www.cnblogs.com/luotianshuai/p/5002110.html" target="_blank" onclick="clickRecomItmem(5002110)">Python之路【第四篇】:模块</a><br>· <a href="https://www.cnblogs.com/weiman3389/p/6224104.html" target="_blank" onclick="clickRecomItmem(6224104)">Python之路【第四篇】:模块</a><br>· <a href="https://www.cnblogs.com/ns500/p/5059539.html" target="_blank" onclick="clickRecomItmem(5059539)">Python之路(第四篇)</a><br>· <a href="https://www.cnblogs.com/cocoa-z/p/6424789.html" target="_blank" onclick="clickRecomItmem(6424789)">Python之路【第四篇】:Python基础4之常用模块</a><br>· <a href="https://www.cnblogs.com/guisheng/p/6036374.html" target="_blank" onclick="clickRecomItmem(6036374)">Python之路【第四篇】:模块</a><br></div></div>
<div id="cnblogs_c2" class="c_ad_block">
<div id="div-gpt-ad-1539008685004-0" style="height:60px; width:468px;" data-google-query-id="CPrOzNCds-ECFQdviwodQhkOjg"><div id="google_ads_iframe_/1090369/C2_0__container__" style="border: 0pt none;"><iframe id="google_ads_iframe_/1090369/C2_0" title="3rd party ad content" name="google_ads_iframe_/1090369/C2_0" width="468" height="60" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" srcdoc="" data-google-container-id="2" style="border: 0px; vertical-align: bottom;" data-load-complete="true"></iframe></div></div>
</div>
<div id="under_post_kb"><div class="itnews c_ad_block"><b>最新新闻</b>:<br> · <a href="https://news.cnblogs.com/n/623225/" target="_blank">医生利用5G远程操控脑部手术 比大片还科幻</a><br> · <a href="https://news.cnblogs.com/n/623224/" target="_blank">三部门发布13个新职业:含电子竞技员、无人机驾驶员</a><br> · <a href="https://news.cnblogs.com/n/623223/" target="_blank">全民冲刺科创板:一场盛宴已经拉开了序幕</a><br> · <a href="https://news.cnblogs.com/n/623222/" target="_blank">唯品会否认“北京分公司解散”:是正常架构调整</a><br> · <a href="https://news.cnblogs.com/n/623221/" target="_blank">多家共享单车宣布涨价:但愿调价是良性竞争的开始</a><br>» <a href="http://news.cnblogs.com/" title="IT新闻" target="_blank">更多新闻...</a></div></div>
<div id="HistoryToday" class="c_ad_block"></div>
<script type="text/javascript">
if(enablePostBottom()) {
codeHighlight();
fixPostBody();
setTimeout(function () { incrementViewCount(cb_entryId); }, 50);
deliverT2();
deliverC1();
deliverC2();
loadNewsAndKb();
loadBlogSignature();
LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid);
GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate, cb_postType);
loadOptUnderPost();
GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate);
}
</script>
</div>


</div>

猜你喜欢

转载自www.cnblogs.com/ALXB/p/10649051.html