第二模块:函数编程 第2章·常用模块

  • 01-常用模块学习-小鸡汤
  • 02-常用模块学习-模块种类和导入方法
  • 03-常用模块学习-模块的导入路径
  • 04-常用模块学习-开源模块学习的安装方式
  • 05-常用模块学习-使用国内源下载模块
  • 06-常用模块学习-包及跨模块导入
  • 07-常用模块学习-跨模块导入2
  • 08-常用模块学习-相对导入
  • 09-常用模块学习-time模块详解
  • 10-常用模块学习-datetime模块详解
  • 11-常用模块学习-random模块详解
  • 12-常用模块学习-os模块详解
  • 13-常用模块学习-sys模块详解
  • 14-常用模块学习-shutil模块详解
  • 15-常用模块学习-序列化模块详解
  • 16-常用模块学习-序列化json模块详解
  • 17-常用模块学习-序列化pickle模块详解
  • 18-常用模块学习-序列化shelve模块详解
  • 19-常用模块学习-xml处理模块详解
  • 20-常用模块学习-自动创建xml文档
  • 21-常用模块学习-configparser模块详解_batch
  • 22-常用模块学习-hashlib加密模块详解
  • 23-常用模块学习-subprocess模块详解
  • 24-常用模块学习-subprocess模块详解2
  • 25-常用模块学习-logging模块基础
  • 26-常用模块学习-logging模块进阶
  • 27-常用模块学习-logging日志过滤和日志文件自动截取
  • 28-常用模块学习-re正则表达式讲解
  • 29-常用模块学习-re匹配语法
  • 30-常用模块学习-re正则表达式公式讲解1
  • 31-常用模块学习-re正则表达式公式讲解2
  • 32-常用模块学习-re正则表达式公式讲解3
  • 33-常用模块学习-re正则表达式公式讲解4
  • 34-常用模块学习-re正则表达式公式讲解5
  • 35-常用模块学习-re正则表达式公式讲解6
  • 36-常用模块学习-re正则表达式公式讲解7
  • 37-常用模块学习-软件开发目录规范
  • 38-常用模块学习-软件开发目录规范2
  • 39-常用模块学习-作业需求

01-常用模块学习-小鸡汤

1、模块概念的引入——工具箱;

2、节目推荐-晓说;

  • 《晓说》是2012年3月高晓松开始主持的网络脱口秀节目;
  • 在每周30-40分钟一集的节目中,《晓说》每期由主持人高晓松谈论一个热门话题,打造视频化的“高晓松专栏文章”;
  • 2017年4月7日,停播了将近3年的《晓说》已在优酷重新开播;

02-常用模块学习-模块种类和导入方法

1、什么是模块?!

"""
1、什么是模块?
在计算机的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对减少,很多编程语言都采用这样组织代码的方式。
在Python中,一个Py文件就可以称之为一个模块(Module)
2、使用模块的好处:
    大大提高了代码的可维护性;
    避免函数名和变量名的冲突;
3、模块的分类:
    内置标准模块(又称为标准库)执行help('modules')查看Python中所有自带模块列表;
    第三方开源模块,可通过pip install 模块名进行联网安装;(即从公共仓库下载的过程)
4、模块的调用方式:
格式:
1、import module
2、from module import xx #从哪来,到哪去!
3、from module.xx.xx import xx as rename #起个别名;
4、from module.xx.xx import *  #*代表所有,不建议使用,变量名容易冲突;
"""
import os
import sys
from os import rmdir
from os import rmdir,rename,replace#逗号分隔,导入多个;
print(help('modules'))
"""

 

C:\Users\Administrator\PycharmProjects\LFXC2018\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm 2018.1.3\helpers\pydev\pydevconsole.py" 58035 58036
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\Users\\Administrator\\PycharmProjects\\LFXC2018', 'C:/Users/Administrator/PycharmProjects/LFXC2018'])
PyDev console: starting.
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)] on win32
help('modules')
Please wait a moment while I gather a list of all available modules...
__future__          _winapi             imp                 selectors
_ast                abc                 importlib           setup
_asyncio            aifc                inspect             setup_cython
_bisect             antigravity         interpreterInfo     setuptools
_blake2             argparse            io                  shelve
_bootlocale         array               ipaddress           shlex
_bz2                ast                 itertools           shutil
_codecs             asynchat            json                signal
_codecs_cn          asyncio             keyword             site
_codecs_hk          asyncore            lib2to3             sitecustomize
_codecs_iso2022     atexit              linecache           smtpd
_codecs_jp          audioop             locale              smtplib
_codecs_kr          backend_interagg    logging             sndhdr
_codecs_tw          base64              lzma                socket
_collections        bdb                 macpath             socketserver
_collections_abc    binascii            macurl2path         sqlite3
_compat_pickle      binhex              mailbox             sre_compile
_compression        bisect              mailcap             sre_constants
_csv                builtins            marshal             sre_parse
_ctypes             bz2                 math                ssl
_ctypes_test        cProfile            mimetypes           stat
_datetime           calendar            mmap                statistics
_decimal            cgi                 modulefinder        string
_distutils_findvs   cgitb               msilib              stringprep
_dummy_thread       chardet             msvcrt              struct
_elementtree        chunk               multiprocessing     subprocess
_functools          cmath               netrc               sunau
_hashlib            cmd                 nntplib             symbol
_heapq              code                nt                  symtable
_imp                codecs              ntpath              sys
_io                 codeop              nturl2path          sysconfig
_json               collections         numbers             tabnanny
_locale             colorsys            opcode              tarfile
_lsprof             compileall          operator            telnetlib
_lzma               concurrent          optparse            tempfile
_markupbase         configparser        os                  test
_md5                contextlib          parser              test_pydevd_reload
_msi                copy                pathlib             tests_pydevd
_multibytecodec     copyreg             pdb                 tests_pydevd_mainloop
_multiprocessing    crypt               pickle              tests_pydevd_python
_opcode             csv                 pickletools         textwrap
_operator           ctypes              pip                 this
_osx_support        curses              pipes               threading
_overlapped         datetime            pkg_resources       time
_pickle             dbm                 pkgutil             timeit
_pydecimal          decimal             platform            tkinter
_pydev_bundle       difflib             plistlib            token
_pydev_imps         dis                 poplib              tokenize
_pydev_runfiles     distutils           posixpath           trace
_pydevd_bundle      doctest             pprint              traceback
_pydevd_frame_eval  dummy_threading     profile             tracemalloc
_pyio               easy_install        pstats              tty
_random             email               pty                 turtle
_sha1               encodings           py_compile          turtledemo
_sha256             ensurepip           pyclbr              types
_sha3               enum                pycompletionserver  typing
_sha512             errno               pydev_app_engine_debug_startup unicodedata
_signal             faulthandler        pydev_coverage      unittest
_sitebuiltins       filecmp             pydev_ipython       urllib
_socket             fileinput           pydev_pysrc         uu
_sqlite3            fnmatch             pydev_run_in_console uuid
_sre                formatter           pydevconsole        venv
_ssl                fractions           pydevd              warnings
_stat               ftplib              pydevd_concurrency_analyser wave
_string             functools           pydevd_file_utils   weakref
_strptime           gc                  pydevd_plugins      webbrowser
_struct             genericpath         pydoc               winreg
_symtable           getopt              pydoc_data          winsound
_testbuffer         getpass             pyexpat             wsgiref
_testcapi           gettext             queue               xdrlib
_testconsole        glob                quopri              xml
_testimportmultiple gzip                random              xmlrpc
_testmultiphase     hashlib             re                  xxsubtype
_thread             heapq               reprlib             zipapp
_threading_local    hmac                rlcompleter         zipfile
_tkinter            html                runfiles            zipimport
_tracemalloc        http                runpy               zlib
_warnings           idlelib             sched               
_weakref            imaplib             secrets             
_weakrefset         imghdr              select              
Enter any module name to get more help.  Or, type "modules spam" to search
for modules whose name or summary contain the string "spam".

2、使用模块的好处?

  • 提高可维护性;
  • 可重用;
  • 避免函数名的冲突;

3、模块的分类;

  • 内置标准模块(又称标准库),可通过执行help(‘modules’)查看所有Python自带的模块列表;
  • 第三方开源模块,可以通过pip install 模块名,联网安装;
  • 自定义模块;

4、模块的调用;

  • import module
  • from module import xx
  • from module.xx.xx import xx as rename
  • from module.xx.xx import *#不推荐使用;
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/27 0027 10:43
""
"""
格式:
1、import module
2、from module import xx #从哪来,到哪去!
3、from module.xx.xx import xx as rename #起个别名;
4、from module.xx.xx import *  #*代表所有,不建议使用,变量名容易冲突;
"""
import os
import sys
from os import rmdir
from os import rmdir,rename,replace#逗号分隔,导入多个;不建议使用,不符合PEP8规范;

模块一旦被调用,即相当于执行了另外一个py文件里的代码;

03-常用模块学习-模块的导入路径

1、模块的导入路径;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/27 0027 11:25
import sys
print(sys.path)
"""
[
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\文件操作&函数\\模块', 
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018', 
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv\\Scripts\\python36.zip', 
'C:\\Program Files\\Python36\\DLLs',
'C:\\Program Files\\Python36\\lib', 'C:\\Program Files\\Python36',
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv', 
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv\\lib\\site-packages',
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv\\lib\\site-packages\\setuptools-39.0.1-py3.6.egg', 
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv\\lib\\site-packages\\pip-9.0.3-py3.6.egg', 
'C:\\Program Files\\JetBrains\\PyCharm 2018.1.3\\helpers\\pycharm_matplotlib_backend'
]
"""
#注意使用转义字符\
#只是一次性有效;
sys.path.append('C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\文件操作&函数\\模块')
print(sys.path)
#import my_modules
#del my_modules
"""
小结:模块查找路径有顺序;
"""

04-常用模块学习-开源模块学习的安装方式

1、开源模块的介绍;

https://pypi.org/ 是python的开源模块库,截止2017年9.30日 ,已经收录了118170个来自全世界python开发者贡献的模块,几乎涵盖了你想用python做的任何事情。 事实上每个python开发者,只要注册一个账号就可以往这个平台上传你自己的模块,这样全世界的开发者都可以容易的下载并使用你的模块。

2、开源模块的安装方法总结;

1)使用源码包进行安装;

下载地址: https://files.pythonhosted.org/packages/c4/22/167ec8e203b0f930582a82a1bfcf7faf9d14af3a0d6abc807dbb22ed52f8/PyTyrion-1.0.1.tar.gz

  • 编译源码 python setup.py build
  • 安装源码 python setup.py install(推荐使用哦!)

2)使用pip工具进行安装;

  • pip3 install PyTyrion
  • pip3 uninstall PyTyrion
  • import Tyrion#使用它;

Pytion模块的介绍:https://pypi.org/project/PyTyrion/

05-常用模块学习-使用国内源下载模块

1、pip命令默认会连接在国外的python官方服务器下载,速度比较慢,你还可以使用国内的豆瓣源,数据会定期同步国外官网,速度快好多;

pip install -i http://pypi.douban.com/simple/ alex_sayhi --trusted-host pypi.douban.com   #alex_sayhi是模块名,注意alex_sayhi前面有空格;
Microsoft Windows [版本 10.0.16299.15]
(c) 2017 Microsoft Corporation。保留所有权利。

(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>pip3 install PyTyrion#安装
Collecting PyTyrion
  Using cached https://files.pythonhosted.org/packages/c4/22/167ec8e203b0f930582a82a1bfcf7faf9d14a
f3a0d6abc807dbb22ed52f8/PyTyrion-1.0.1.tar.gz
Installing collected packages: PyTyrion
  Running setup.py install for PyTyrion ... done
Successfully installed PyTyrion-1.0.1
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>pip3 uninstall PyTyrion#卸载
Uninstalling PyTyrion-1.0.1:
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\pytyrion-1.0.1-py3.6.egg-
info
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\__init__.py
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\__pycache__\__init
__.cpython-36.pyc
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\__pycache__\fields
.cpython-36.pyc
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\__pycache__\forms.
cpython-36.pyc
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\__pycache__\framew
ork.cpython-36.pyc
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\__pycache__\widget
.cpython-36.pyc
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\fields.py
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\forms.py
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\framework.py
  c:\users\administrator\pycharmprojects\lfxc2018\venv\lib\site-packages\tyrion\widget.py
Proceed (y/n)? y
  Successfully uninstalled PyTyrion-1.0.1
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>pip3 install PyTyrion
Collecting PyTyrion
  Using cached https://files.pythonhosted.org/packages/c4/22/167ec8e203b0f930582a82a1bfcf7faf9d14a
f3a0d6abc807dbb22ed52f8/PyTyrion-1.0.1.tar.gz
Installing collected packages: PyTyrion
  Running setup.py install for PyTyrion ... done
Successfully installed PyTyrion-1.0.1
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>pip3 install -i http://pypi.douban.com/simp
le/alex_sayhi --trusted-host pypi.douban.com
You must give at least one requirement to install (see "pip help install")
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>pip3 install -i http://pypi.douban.com/simp
le/ alex_sayhi --trusted-host pypi.douban.com#注意alex_sayhi前面有一空格;
Collecting alex_sayhi
  Downloading http://pypi.doubanio.com/packages/84/14/b59d93276c86f6ab556cfa7c2d860b742c1611b601cc
4c7743d129b4b52a/alex_sayhi-1.0.0.tar.gz
Installing collected packages: alex-sayhi
  Running setup.py install for alex-sayhi ... done
Successfully installed alex-sayhi-1.0.0
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>
 1 (venv) C:\Users\Administrator\PycharmProjects\LFXC2018>pip3 install paramiko
 2 Collecting paramiko
 3   Downloading https://files.pythonhosted.org/packages/3e/db/cb7b6656e0e7387637ce850689084dc0b94b44
 4 df31cc52e5fc5c2c4fd2c1/paramiko-2.4.1-py2.py3-none-any.whl (194kB)
 5     94% |██████████████████████████████▎ | 184kB 313kB/s eta 0:00:0
 6     100% |████████████████████████████████| 194kB 295kB/s
 7 Collecting pynacl>=1.0.1 (from paramiko)
 8   Downloading https://files.pythonhosted.org/packages/35/ae/5cd8eb69f9341ebb4964faac5f5a00589fbf5d
 9 5f02d84a811c6abcc4f882/PyNaCl-1.2.1-cp36-cp36m-win_amd64.whl (165kB)
10     93% |█████████████████████████████▉  | 153kB 626kB/s eta 0:00:01
11     99% |███████████████████████████████▊| 163kB 626kB/s eta 0:00:
12     100% |████████████████████████████████| 174kB 583kB/s
13 Collecting bcrypt>=3.1.3 (from paramiko)
14   Downloading https://files.pythonhosted.org/packages/4b/c0/c0550e4b98e0536d3a8b8753b68aa0d3c03af6
15 54c43a58328d0bf2c06747/bcrypt-3.1.4-cp36-cp36m-win_amd64.whl
16 Collecting cryptography>=1.5 (from paramiko)
17   Downloading https://files.pythonhosted.org/packages/67/62/67faef32908026e816a74b4b97491f8b9ff393
18 d2951820573599c105cc32/cryptography-2.2.2-cp36-cp36m-win_amd64.whl (1.3MB)
19     91% |█████████████████████████████▍  | 1.2MB 1.2MB/s eta 0:00:01
20     92% |█████████████████████████████▋  | 1.2MB 1.2MB/s eta 0:00:01
21     93% |█████████████████████████████▉  | 1.2MB 1.2MB/s eta 0:00:01
22     94% |██████████████████████████████  | 1.2MB 6.5MB/s eta 0:00:01
23     94% |██████████████████████████████▎ | 1.3MB 6.5MB/s eta 0:00:0
24     95% |██████████████████████████████▋ | 1.3MB 6.7MB/s eta 0:00:0
25     96% |██████████████████████████████▉ | 1.3MB 5.6MB/s eta 0:00:0
26     97% |███████████████████████████████ | 1.3MB 6.5MB/s eta 0:00:0
27     97% |███████████████████████████████▎| 1.3MB 6.6MB/s eta 0:00:
28     98% |███████████████████████████████▋| 1.3MB 6.0MB/s eta 0:00:
29     99% |███████████████████████████████▉| 1.3MB 6.4MB/s eta 0:00:
30     100% |████████████████████████████████| 1.3MB 977kB/s
31 Collecting pyasn1>=0.1.7 (from paramiko)
32   Downloading https://files.pythonhosted.org/packages/a0/70/2c27740f08e477499ce19eefe05dbcae6f19fd
33 c49e9e82ce4768be0643b9/pyasn1-0.4.3-py2.py3-none-any.whl (72kB)
34     98% |███████████████████████████████▋| 71kB 8.8MB/s eta 0:00:0
35     100% |████████████████████████████████| 81kB 3.7MB/s
36 Collecting six (from pynacl>=1.0.1->paramiko)
37   Downloading https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca
38 43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
39 Collecting cffi>=1.4.1 (from pynacl>=1.0.1->paramiko)
40   Downloading https://files.pythonhosted.org/packages/2f/85/a9184548ad4261916d08a50d9e272bf6f93c54
41 f3735878fbfc9335efd94b/cffi-1.11.5-cp36-cp36m-win_amd64.whl (166kB)
42     92% |█████████████████████████████▌  | 153kB 6.7MB/s eta 0:00:01
43     98% |███████████████████████████████▍| 163kB 6.5MB/s eta 0:00:
44     100% |████████████████████████████████| 174kB 3.1MB/s
45 Collecting asn1crypto>=0.21.0 (from cryptography>=1.5->paramiko)
46   Downloading https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8
47 ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl (101kB)
48     100% |████████████████████████████████| 102kB 3.5MB/s
49 Collecting idna>=2.1 (from cryptography>=1.5->paramiko)
50   Downloading https://files.pythonhosted.org/packages/27/cc/6dd9a3869f15c2edfab863b992838277279ce9
51 2663d334df9ecf5106f5c6/idna-2.6-py2.py3-none-any.whl (56kB)
52     100% |████████████████████████████████| 61kB 3.5MB/s
53 Collecting pycparser (from cffi>=1.4.1->pynacl>=1.0.1->paramiko)
54   Downloading https://files.pythonhosted.org/packages/8c/2d/aad7f16146f4197a11f8e91fb81df177adcc20
55 73d36a17b1491fd09df6ed/pycparser-2.18.tar.gz (245kB)
56     91% |█████████████████████████████▎  | 225kB 7.0MB/s eta 0:00:01
57     95% |██████████████████████████████▋ | 235kB 6.8MB/s eta 0:00:0
58     99% |████████████████████████████████| 245kB 6.8MB/s eta 0:00:
59     100% |████████████████████████████████| 256kB 2.7MB/s
60 Installing collected packages: six, pycparser, cffi, pynacl, bcrypt, asn1crypto, idna, cryptograph
61 y, pyasn1, paramiko
62   Running setup.py install for pycparser ... done
63 Successfully installed asn1crypto-0.24.0 bcrypt-3.1.4 cffi-1.11.5 cryptography-2.2.2 idna-2.6 para
64 miko-2.4.1 pyasn1-0.4.3 pycparser-2.18 pynacl-1.2.1 six-1.11.0
65 You are using pip version 9.0.3, however version 10.0.1 is available.
66 You should consider upgrading via the 'python -m pip install --upgrade pip' command.
##########################################################使用国内豆瓣源下载速度对比###########################################

(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>pip3 install -i http://pypi.douban.com/simp
le/ paramiko
Collecting paramiko
The repository located at pypi.douban.com is not a trusted or secure host and is being ignored.
If this repository is available via HTTPS it is recommended to use HTTPS instead, otherwise you ma
y silence this warning and allow it anyways with '--trusted-host pypi.douban.com'.
Could not find a version that satisfies the requirement paramiko (from versions: )
No matching distribution found for paramiko
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>pip3 install -i http://pypi.douban.com/simp
le/ paramiko --trusted-host pypi.douban.com
Collecting paramiko
Downloading http://pypi.doubanio.com/packages/3e/db/cb7b6656e0e7387637ce850689084dc0b94b44df31cc
52e5fc5c2c4fd2c1/paramiko-2.4.1-py2.py3-none-any.whl (194kB)
94% |██████████████████████████████▎ | 184kB 1.3MB/s eta 0:00:0
100% |████████████████████████████████| 194kB 1.4MB/s
Requirement already satisfied: cryptography>=1.5 in c:\users\administrator\pycharmprojects\lfxc201
8\venv\lib\site-packages (from paramiko)
Requirement already satisfied: bcrypt>=3.1.3 in c:\users\administrator\pycharmprojects\lfxc2018\ve
nv\lib\site-packages (from paramiko)
Requirement already satisfied: pyasn1>=0.1.7 in c:\users\administrator\pycharmprojects\lfxc2018\ve
nv\lib\site-packages (from paramiko)
Requirement already satisfied: pynacl>=1.0.1 in c:\users\administrator\pycharmprojects\lfxc2018\ve
nv\lib\site-packages (from paramiko)
Requirement already satisfied: cffi>=1.7; platform_python_implementation != "PyPy" in c:\users\adm
inistrator\pycharmprojects\lfxc2018\venv\lib\site-packages (from cryptography>=1.5->paramiko)
Requirement already satisfied: idna>=2.1 in c:\users\administrator\pycharmprojects\lfxc2018\venv\l
ib\site-packages (from cryptography>=1.5->paramiko)
Requirement already satisfied: six>=1.4.1 in c:\users\administrator\pycharmprojects\lfxc2018\venv\
lib\site-packages (from cryptography>=1.5->paramiko)
Requirement already satisfied: asn1crypto>=0.21.0 in c:\users\administrator\pycharmprojects\lfxc20
18\venv\lib\site-packages (from cryptography>=1.5->paramiko)
Requirement already satisfied: pycparser in c:\users\administrator\pycharmprojects\lfxc2018\venv\l
ib\site-packages (from cffi>=1.7; platform_python_implementation != "PyPy"->cryptography>=1.5->par
amiko)
Installing collected packages: paramiko
Successfully installed paramiko-2.4.1
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>

06-常用模块学习-包及跨模块导入

1、包的概念引入;

.
└── my_proj
    ├── crm #代码目录;此处就是包;
    │   ├── admin.py
    │   ├── apps.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── manage.py
    └── proj #配置文件目录;此处也是包;
        ├── settings.py
        ├── urls.py
        └── wsgi.py

当我们的模块文件越来越多,为了容易管理,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹,其中,一个文件夹管理多个模块文件,这个文件夹就被称为包;

2、不同模块;

07-常用模块学习-跨模块导入2

1、绝对路径与相对路径;

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 # __Author__:Administrator
 4 # Version:python3.6.5
 5 # Date:2018/5/27 0027 13:51
 6 import sys,os
 7 print(dir())#['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'os', 'sys']
 8 print(__file__)#C:/Users/Administrator/PycharmProjects/LFXC2018/文件操作&函数/模块/packages/my_proj/crm/views.py
 9 #BASE_DIR = os.path.dirname(os.path.dirname(__file__))#相对路径;
10 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#绝对路径;abspath
11 print("BASE_DIR",BASE_DIR)
12 sys.path.append(BASE_DIR)
13 #sys.path.append("C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\文件操作&函数\\模块\\packages\\my_proj")
14 print(sys.path)
15 from proj import settings
16 def sayhi():
17     print('Hello World.')
18 #一出手就是专业的!
19 
20 
21 def sayhi():
22     print('hello world!')

08-常用模块学习-相对导入

1、相对导入(使用场景不多);

绝对导入&相对导入
在linux里可以通过cd ..回到上一层目录 ,cd ../.. 往上回2层,这个..就是指相对路径,在python里,导入也可以通过..

例如:

.
├── __init__.py
├── crm
│   ├── __init__.py#必须存在,声明crm是一个包;
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── tests.py
│   ├── views.py  #from ..proj import settings 
├── manage.py   
└── proj
    ├── __init__.py
    ├── settings.py #from .import urls  
    ├── urls.py
    └── wsgi.py
views.py里代码

from ..proj import settings
def sayhi():
    print('hello world!')

print(settings.DATABASES)
执行结果报错了

Traceback (most recent call last):
File "my_proj/crm/views.py", line 4, in <module>
 from ..proj import settings
SystemError: Parent module '' not loaded, cannot perform relative import
或者有人会看到这个错

ValueError: attempted relative import beyond top-level package
其实这两个错误的原因归根结底是一样的:在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入。

文件夹被python解释器视作package需要满足两个条件:

文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。
不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)。
所以这个问题的解决办法就是,既然你在views.py里执行了相对导入,那就不要把views.py当作入口程序,可以通过上一级的manage.py调用views.py

.
├── __init__.py
├── crm
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── tests.py
│   ├── views.py  #from ..proj import settings 
├── manage.py  #from crm import views 
└── proj
    ├── __init__.py
    ├── settings.py #from .import urls  
    ├── urls.py
    └── wsgi.py
事实证明还是不行,报错

ValueError: attempted relative import beyond top-level package
但把from ..proj import settings 改成from . import models 后却执行成功了,为什么呢?

from .. import models会报错的原因是,这句代码会把manage.py所在的这一层视作package,但实际上它不是,因为package不能是顶层入口代码,若想不出错,只能把manage.py往上再移一层。

正确的代码目录结构如下

    packages/
    ├── __init__.py
    ├── manage.py #from my_proj.crm  import views
    └── my_proj
        ├── crm
        │   ├── admin.py
        │   ├── apps.py
        │   ├── models.py
        │   ├── tests.py
        │   ├── views.py  #from . import models;  from ..proj import settings 
        └── proj
            ├── __init__.py
            ├── settings.py
            ├── urls.py
            └── wsgi.py
再执行manage.py就不会报错了。

注:虽然python支持相对导入,但对模块间的路径关系要求比较严格,处理不当就容易出错,so并不建议在项目里经常使用。

09-常用模块学习-time模块详解

1、time模块初识;

在平常的代码中,我们常常需要与时间打交道。在Python中,与时间处理有关的模块就包括:time,datetime,calendar(很少用,不讲),下面分别来介绍。

在开始之前,首先要说明几点:

一、在Python中,通常有这几种方式来表示时间:

  1. 时间戳;
  2. 格式化的时间字符串;
  3. 元组(struct_time)共九个元素。由于Python的time模块实现主要调用C库,所以各个平台可能有所不同;

二、几个定义

UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8。DST(Daylight Saving Time)即夏令时。

时间戳(timestamp)的方式:通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。

元组(struct_time)方式:struct_time元组共有9个元素,返回struct_time的函数主要有gmtime(),localtime(),strptime()。下面列出这种方式元组中的几个元素:

索引(Index)    属性(Attribute)    值(Values)
0     tm_year(年)                 比如2011 
1     tm_mon(月)             1 - 12
2     tm_mday(日)                 1 - 31
3     tm_hour(时)                 0 - 23
4     tm_min(分)             0 - 59
5     tm_sec(秒)             0 - 61
6     tm_wday(weekday)            0 - 6(0表示周日)
7     tm_yday(一年中的第几天)    1 - 366
8     tm_isdst(是否是夏令时)            默认为-1

time模块的方法

  • time.localtime([secs]):将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
  • time.gmtime([secs]):和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
  • time.time():返回当前时间的时间戳。
  • time.mktime(t):将一个struct_time转化为时间戳。
  • time.sleep(secs):线程推迟指定的时间运行。单位为秒。
  • time.asctime([t]):把一个表示时间的元组或者struct_time表示为这种形式:'Sun Oct 1 12:04:38 2017'。如果没有参数,将会将time.localtime()作为参数传入。
  • time.ctime([secs]):把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
  • time.strftime(format[, t]):把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。

    • 举例:time.strftime("%Y-%m-%d %X", time.localtime()) #输出'2017-10-01 12:14:23'
  • time.strptime(string[, format]):把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。

    • 举例:time.strptime('2017-10-3 17:54',"%Y-%m-%d %H:%M") #输出 time.struct_time(tm_year=2017, tm_mon=10, tm_mday=3, tm_hour=17, tm_min=54, tm_sec=0, tm_wday=1, tm_yday=276, tm_isdst=-1)
字符串转时间格式对应表
 
 MeaningNotes
%a Locale’s abbreviated weekday name.  
%A Locale’s full weekday name.  
%b Locale’s abbreviated month name.  
%B Locale’s full month name.  
%c Locale’s appropriate date and time representation.  
%d Day of the month as a decimal number [01,31].  
%H Hour (24-hour clock) as a decimal number [00,23].  
%I Hour (12-hour clock) as a decimal number [01,12].  
%j Day of the year as a decimal number [001,366].  
%m Month as a decimal number [01,12].  
%M Minute as a decimal number [00,59].  
%p Locale’s equivalent of either AM or PM. (1)
%S Second as a decimal number [00,61]. (2)
%U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
%w Weekday as a decimal number [0(Sunday),6].  
%W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
%x Locale’s appropriate date representation.  
%X Locale’s appropriate time representation.  
%y Year without century as a decimal number [00,99].  
%Y Year with century as a decimal number.  
%z Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].  
%Z Time zone name (no characters if no time zone exists).  
  %% A literal '%'character.

最后为了容易记住转换关系,看下图

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/27 0027 15:24
import time
print("从1970年1月1日00:00:00:00起,返回当前时间的时间戳:",time.time())#从1970年1月1日 00:00:00起;
print("将一个时间戳转换为当前时区的struct_time:",time.localtime())#time.struct_time(tm_year=2018, tm_mon=5, tm_mday=27, tm_hour=15, tm_min=29, tm_sec=50, tm_wday=6, tm_yday=147, tm_isdst=0)
print("打印当前时区(北京时区)的struct_time:",time.localtime(1527406435.9800334))#将一个时间戳转换为当前时区的stuct_time。
#time.gmtime()和localtime()方法类似,不过gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time

a = time.localtime()
print("打印自定义格式的时间:",'%s-%s-%s'%(a.tm_year,a.tm_mon,a.tm_mday))#2018-5-27
print("打印0时区的struct_time:",time.gmtime())#time.struct_time(tm_year=2018, tm_mon=5, tm_mday=27, tm_hour=7, tm_min=32, tm_sec=35, tm_wday=6, tm_yday=147, tm_isdst=0)
print("将struct_time转换为时间戳显示:",time.mktime(a))#1527407076.0

print("线程推迟指定的是时间运行,就是让'程序'睡一会儿再运行:",time.sleep(1))
print("time.asctime([t]):把一个表示时间的元组或者struct_time表示为这种形式:'Sun Oct 1 12:04:38 2017'。如果没有参数,将会将time.localtime()作为参数传入。",time.asctime())
print(time.ctime())#Sun May 27 15:50:54 2018
print(time.ctime(0))#Thu Jan  1 08:00:00 1970
print(time.ctime(1232123))#Thu Jan 15 14:15:23 1970

#print(help(time.strftime()))
"""
time.strftime(format[, t]):把一个代表时间的元组
或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。
如果t未指定,将传入time.localtime()。
"""
print(time.strftime('2017'))
print(time.strftime('2017-8'))
print(time.strftime('%Y-%m-%d'))#2018-05-27
print(time.strftime('%Y-%m-%d %H:%M:%S'))#2018-05-27 15:58:32
b = time.localtime(1898908909)
print(time.strftime('%Y-%m-%d %H:%M:%S',b))#2030-03-05 10:41:49
print(time.strftime('%Y-%m-%d %H:%M:%S  %U '))#2018-05-27 16:04:38  21
print(time.strftime('%Y-%m-%d %H:%M:%S %w'))#2018-05-27 16:04:38 0
print(time.strftime('%Y-%m-%d %H:%M:%S %z '))#2018-05-27 16:04:38 +0800
print(time.strftime('%Y-%m-%d %H:%M:%S %Z'))#2030-03-05 10:41:49
print("-------------------内容太多了,打个断点吧!--------------")
s = time.strftime('%Y-%m-%d %H:%M:%S')
print(time.strptime(s,'%Y-%m-%d %H:%M:%S'))#与time.strftime('%Y-%m-%d %H:%M:%S')互为逆操作

10-常用模块学习-datetime模块详解

1、datetime模块;

datetime模块

相比于time模块,datetime模块的接口则更直观、更容易调用

datetime模块定义了下面这几个类:

  • datetime.date:表示日期的类。常用的属性有year, month, day;
  • datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond;
  • datetime.datetime:表示日期时间。
  • datetime.timedelta:表示时间间隔,即两个时间点之间的长度。
  • datetime.tzinfo:与时区有关的相关信息。(这里不详细充分讨论该类,感兴趣的童鞋可以参考python手册)

我们需要记住的方法仅以下几个:

  1. d=datetime.datetime.now() 返回当前的datetime日期类型
d.timestamp(),d.today(), d.year,d.timetuple()等方法可以调用

2.datetime.date.fromtimestamp(322222) 把一个时间戳转为datetime日期类型

3.时间运算

>>> datetime.datetime.now()

datetime.datetime(2017, 10, 1, 12, 53, 11, 821218)

>>> datetime.datetime.now() + datetime.timedelta(4) #当前时间 +4天

datetime.datetime(2017, 10, 5, 12, 53, 35, 276589)

>>> datetime.datetime.now() + datetime.timedelta(hours=4) #当前时间+4小时

datetime.datetime(2017, 10, 1, 16, 53, 42, 876275)

4.时间替换

>>> d.replace(year=2999,month=11,day=30)

datetime.date(2999, 11, 30)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/27 0027 16:14
import datetime,time
print(datetime.datetime)#<class 'datetime.datetime'>
print(datetime.datetime.now())#2018-05-27 16:15:02.575789#尾部是毫秒;
a = datetime.datetime.now()
print(a)
print(a.year)
print(a.month)
print(a.day)
print(a.hour)
print(a.minute)
print(a.second)
print(a.microsecond)

print(datetime.datetime(2017,10,12,20,8,25,59782))#2017-10-12 20:08:25.059782
print(datetime.date.fromtimestamp(time.time()))#将时间戳快速的转换为“年月日”格式;

d = datetime.date.fromtimestamp(time.time())
print(d.year)#2018
print("打个断点吧!----------------------------------------------")
print(datetime.timedelta(1))#1 day, 0:00:00
print(datetime.datetime.now())#2018-05-27 16:24:18.928623
print("------------------------------")
t = datetime.timedelta(1)
print(datetime.datetime.now() -t)#2018-05-26 16:25:28.727510
print(datetime.datetime.now() - datetime.timedelta(days=3))#2018-05-24 16:25:28.727510
print(datetime.datetime.now() - datetime.timedelta(hours=4))#2018-05-24 12:25:28.727510
print(datetime.datetime.now() + datetime.timedelta(hours=4))#2018-05-24 20:25:28.727510
print(datetime.datetime.now() + datetime.timedelta(minutes=10))#2018-05-24 16:35:28.727510


d=datetime.datetime.now()
print(d)#2018-05-27 16:34:05.117929
print(d.replace(year=2006))#2006-05-27 16:34:38.694003
print(d.replace(year=2006,month=8,day=20,hour=18,minute=45))#2006-08-20 18:45:04.031477

11-常用模块学习-random模块详解

1、随机数random模块初识;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/28 0028 6:25
import random
print("顾头又顾尾:",random.randint(1,100))#78,顾头又顾尾;
print("顾头又顾尾:",random.randint(1,3))#3,顾头又顾尾;
print("顾头不顾尾:",random.randrange(1,3))#1,顾头不顾尾;
print("顾头不顾尾:",random.randrange(1,3))#2,顾头不顾尾;
print("顾头不顾尾,随机选取1~100之间的奇数:",random.randrange(1,100,2))#17,顾头不顾尾;
print("顾头不顾尾,随机选取0~100之间的偶数:",random.randrange(0,100,2))#28,顾头不顾尾;
print("生成随机浮点数:",random.random())#0.31159629694637025;
print("返回给定数据集合中的1个随机字符:",random.choice('fdsajkl!#@!@#!1232132'))# 2
print("返回给定数据集合中的N个随机字符:",random.sample('fdsajkl!#@!@#!1232132',3))#['!', 'k', '3']
print(''.join(random.sample('fdsajkl!#@!@#!1232132',8)))#s!j@!k2a

import string
print("生成包含'大小写'的字符串:",string.ascii_letters)#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print("生成只包含'所有大写[A-Z]'的字母字符串:",string.ascii_uppercase)#ABCDEFGHIJKLMNOPQRSTUVWXYZ
print("生成只包含'所有小写[a-z]'的字母字符串:",string.ascii_lowercase)#abcdefghijklmnopqrstuvwxyz
print("生成包含'所有叔子[0-9]'的数字字符串:",string.digits)#0123456789
print(string.ascii_lowercase + string.digits)#abcdefghijklmnopqrstuvwxyz0123456789
print(''.join(random.sample(string.ascii_lowercase + string.digits,6)))#7g8jrs
print("生成特殊字符",string.punctuation)#!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
print(''.join(random.sample(string.ascii_lowercase + string.digits+string.punctuation,18)))#d4}5c+/m|97e@"16]s

s = string.ascii_lowercase + string.digits+string.punctuation
print("生成15位随机验证码",''.join(random.sample(s,15)))#"%}l#?t,8c{ei/'
d = list(range(0,20))#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print(d)
random.shuffle(d)#洗牌;
print(d)#[5, 15, 12, 14, 9, 6, 1, 11, 0, 10, 13, 17, 18, 19, 4, 3, 7, 8, 2, 16]
names = ('cxz','cxs','cxl','cql')
print(names)#['cxz', 'cxs', 'cxl', 'cql']
#random.shuffle(names)#洗牌元组
#print(names)#TypeError: 'tuple' object does not support item assignment
s = 'fdsaklfdjsakl;fdsa'
#random.shuffle(s)#
#print(s)#TypeError: 'str' object does not support item assignment
#实际运用场景:将员工的姓名全部放到一个list中,年会的时候就可以用来随机抽奖;

12-常用模块学习-os模块详解

1、通过os模块完成跟操作系统的交互;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/28 0028 7:08
import os
print("获取当前的工作目录:",os.getcwd())#C:\Users\Administrator\PycharmProjects\LFXC2018\文件操作&函数\模块
#print("返回指定目录下的所有文件和目录名:",os.listdir('指定目录'))
#print("删除指定文件:",os.remove('remov.txt'))
#print("删除指定目录:",os.removedirs('指定目录'))
print("判断是否为文件:",os.path.isfile('isfile.txt'))
print("判断是否为目录:",os.path.isdir('isdir'))
print("判断是否为链接文件(快捷方式):",os.path.islink('my_modules.lnk'))
print("判断是否为绝对路径:",os.path.isabs('C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\文件操作&函数\\模块\\指定目录'))
print("检验给出的路径是否真实存在:",os.path.exists('C:\\Users\\Administrator\\PycharmProjects\\LFXC2018'))
print("返回一个文件的目录名和文件名:",os.path.split('01-常用模块学习-小鸡汤.py'))
print("分离文件的拓展名:",os.path.splitext('my_modules.lnk'))
print("获取路径名:",os.path.dirname('05-常用模块学习-使用国内源下载模块.py'))
print("获取绝对路径:",os.path.abspath('05-常用模块学习-使用国内源下载模块.py'))
print("运行Shell命令:",os.system('dir'))#DOS命令;
#print("运行Shell命令:",os.system('df -h'))#Linux下执行命令正确返回0,不正确返回非0;
print("读取操作系统环境变量HOME的值:",os.getenv('HOME'))
print("返回操作系统中所有的环境变量:",os.environ)
print("设置系统环境变量,仅程序运行时有效:",os.environ.setdefault('HOME','xxxx'))
print("给出当前平台使用的行终止符:",os.linesep)# Windows使用'\r\n',Linux and MAC使用'\n'
print("指示我们正在使用的平台:",os.name)
#print("重命名:",os.rename('old.txt','new.txt'))
#print("创建多级目录:",os.makedirs('c:\\d\\e\\ff'))
#print("创建单个目录:",os.mkdir('c:\\a'))
print("获取文件属性:",os.stat('my_modules.lnk'))
#print("修改文件权限与时间戳:",os.chmod())
print("获取文件大小:",os.path.getsize('10-常用模块学习-datetime模块详解.py'))
print("结合目录名与文件名:",os.path.join('new.txt','isdir'))
print("改变工作目录到dirname:",os.chdir('work'))
#print("获取当前终端的大小:",os.get_terminal_size())
#print("杀死进程:",os.kill(10884,signal.SIGKILL))

 

[BEGIN] 2018/7/4 19:20:01
[c:\~]$ clear
[c:\~]$ 
Connecting to 47.94.220.79:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

Last login: Wed Jul  4 18:47:50 2018 from 223.72.55.222

Welcome to Alibaba Cloud Elastic Compute Service !

[root@iZ2ze3eaa380cnnuepvyrwZ ~]# python3
Python 3.6.5 (default, Apr 10 2018, 17:08:37) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> os.getcwd()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> import os
>>> os.getcwd()
'/root'
>>> os.remove('/root/cxz')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IsADirectoryError: [Errno 21] Is a directory: '/root/cxz'
>>> os.remove('/root/cxz/man.txt')
>>> os.system('ls /root')
cxz
0
>>> os.system('ls /root/cxz')
0
>>> os.system('ls /root/cxz')
man.txt
0
>>> os.remove('/root/cxz/man.txt')
>>> os.system('ls /root/cxz')
0
>>> os.makedirs('/root/tqtl/docs/work{intcube,eking}')
>>> os.system('ls /root/tqtl/docs')
work{intcube,eking}
0
>>> os.removedirs('/root/tqtl/docs/work{intcube,eking}')
>>> os.system('ls /root/tqtl/docs')
ls: cannot access /root/tqtl/docs: No such file or directory
512
>>> os.system('ls /root')
cxz
0
>>> os.system('ls /root')
cxz
0
>>> os.system('ls /root/cxz')
man.txt
0
>>> os.path.isfile('/root/cxz/man.txt')
True
>>> os.path.isdir('/root/cxz/')
True
>>> os.path.isabs('/root/cxz/')
True
>>> os.path.exists('/root/cxz/pictures')
False
>>> os.path.issplit('/root/cxz/man.txt')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'posixpath' has no attribute 'issplit'
>>> os.path.split('/root/cxz/man.txt')
('/root/cxz', 'man.txt')
>>> os.path.splitext('/root/cxz/man.txt')
('/root/cxz/man', '.txt')
>>> os.path.dirname('/root/cxz/man.txt')
'/root/cxz'
>>> os.path.abspath('/root/cxz/man.txt')
'/root/cxz/man.txt'
>>> os.path.basename('/root/cxz/man.txt')
'man.txt'
>>> os.system('uname -a')
Linux iZ2ze3eaa380cnnuepvyrwZ 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
0
>>> os.system('uname -r')
3.10.0-693.2.2.el7.x86_64
0
>>> os.system('man /etc/redhat-release')
0
>>> os.system('cat /etc/redhat-release')
CentOS Linux release 7.4.1708 (Core) 
0
>>> os.system('systemctl status redis')
● redis.service - Redis persistent key-value database
   Loaded: loaded (/usr/lib/systemd/system/redis.service; disabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/redis.service.d
           └─limit.conf
   Active: inactive (dead)

Jul 04 19:29:10 iZ2ze3eaa380cnnuepvyrwZ systemd[1]: Started Redis persistent key-value database.
Jul 04 19:29:10 iZ2ze3eaa380cnnuepvyrwZ systemd[1]: Starting Redis persistent key-value database...
Jul 04 19:29:19 iZ2ze3eaa380cnnuepvyrwZ systemd[1]: Stopping Redis persistent key-value database...
Jul 04 19:29:20 iZ2ze3eaa380cnnuepvyrwZ systemd[1]: Stopped Redis persistent key-value database.
768
>>> os.system('systemctl start redis')
0
>>> os.system('systemctl status redis')
● redis.service - Redis persistent key-value database
   Loaded: loaded (/usr/lib/systemd/system/redis.service; disabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/redis.service.d
           └─limit.conf
   Active: active (running) since Wed 2018-07-04 19:29:30 CST; 2s ago
 Main PID: 10898 (redis-server)
   CGroup: /system.slice/redis.service
           └─10898 /usr/bin/redis-server 127.0.0.1:6379

Jul 04 19:29:30 iZ2ze3eaa380cnnuepvyrwZ systemd[1]: Started Redis persistent key-value database.
Jul 04 19:29:30 iZ2ze3eaa380cnnuepvyrwZ systemd[1]: Starting Redis persistent key-value database...
0
>>> os.system('systemctl enable redis')
Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service.
0
>>> os.getenv('HOME')
'/root'
>>> os.system('env')
XDG_SESSION_ID=9
HOSTNAME=iZ2ze3eaa380cnnuepvyrwZ
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
SSH_CLIENT=223.72.55.222 26919 22
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
COLUMNS=230
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
MAIL=/var/spool/mail/root
_=/usr/bin/env
PWD=/root
LANG=en_US.UTF-8
LINES=50
HISTCONTROL=ignoredups
HOME=/root
SHLVL=2
LOGNAME=root
SSH_CONNECTION=223.72.55.222 26919 172.17.36.71 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
0
>>> os.getenv('LANG')
'en_US.UTF-8'
>>> os.getenv('PWD')
'/root'
>>> os.getenv('LOGNAME')
'root'
>>> os.getenv('PATH')
'/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin'
>>> os.getenv('PATH')
KeyboardInterrupt
>>> os.environ
environ({'XDG_SESSION_ID': '9', 'HOSTNAME': 'iZ2ze3eaa380cnnuepvyrwZ', 'TERM': 'xterm', 'SHELL': '/bin/bash', 'HISTSIZE': '1000', 'SSH_CLIENT': '223.72.55.222 26919 22', 'SSH_TTY': '/dev/pts/0', 'USER': 'root', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:', 'MAIL': '/var/spool/mail/root', 'PATH': '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin', 'PWD': '/root', 'LANG': 'en_US.UTF-8', 'HISTCONTROL': 'ignoredups', 'SHLVL': '1', 'HOME': '/root', 'LOGNAME': 'root', 'SSH_CONNECTION': '223.72.55.222 26919 172.17.36.71 22', 'LESSOPEN': '||/usr/bin/lesspipe.sh %s', 'XDG_RUNTIME_DIR': '/run/user/0', '_': '/usr/bin/python3'})
>>> os.environ.setdefault('HOME','/home/tqtl')
'/root'
>>> os.getenv('HOME')
'/root'
>>> os.linesep
'\n'
>>> os.name
'posix'
>>> os.rename('/root/cxz/man.txt','/root/cxz/man_new.txt')
>>> os.rename('/root/cxz/man.txt','/root/cxz/man_new.txt')
KeyboardInterrupt
>>> os.system('ll /root/cxz/')
sh: ll: command not found
32512
>>> os.system('ls -l /root/cxz/')
total 36
-rw-r--r-- 1 root root 33405 Jul  4 19:24 man_new.txt
0
>>> os.mkdir(/root/tqtl)
  File "<stdin>", line 1
    os.mkdir(/root/tqtl)
             ^
SyntaxError: invalid syntax
>>> os.mkdir('/root/tqtl')
>>> os.mkdirs('/root/cuixiaozhao/company/docs')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'os' has no attribute 'mkdirs'
>>> os.makedirs('/root/cuixiaozhao/company/docs')
>>> os.system('ls -l /root/')
total 12
drwxr-xr-x 3 root root 4096 Jul  4 19:33 cuixiaozhao
drwxr-xr-x 2 root root 4096 Jul  4 19:32 cxz
drwxr-xr-x 2 root root 4096 Jul  4 19:33 tqtl
0
>>> os.stat('/root/cxz/man_new.txt')
os.stat_result(st_mode=33188, st_ino=393374, st_dev=64769, st_nlink=1, st_uid=0, st_gid=0, st_size=33405, st_atime=1530703494, st_mtime=1530703494, st_ctime=1530703926)
>>> os.stat('/root/cxz')
os.stat_result(st_mode=16877, st_ino=393342, st_dev=64769, st_nlink=2, st_uid=0, st_gid=0, st_size=4096, st_atime=1530703954, st_mtime=1530703926, st_ctime=1530703926)
>>> os.stat('/root/tqtl/')
os.stat_result(st_mode=16877, st_ino=393414, st_dev=64769, st_nlink=2, st_uid=0, st_gid=0, st_size=4096, st_atime=1530703984, st_mtime=1530703984, st_ctime=1530703984)
>>> os.stat('/root/cuixiaozhao/')
os.stat_result(st_mode=16877, st_ino=393415, st_dev=64769, st_nlink=3, st_uid=0, st_gid=0, st_size=4096, st_atime=1530704022, st_mtime=1530704022, st_ctime=1530704022)
>>> os.chmod('/root/cxz/man_new.txt',755)
>>> os.stat('/root/cxz/man_new.txt')
os.stat_result(st_mode=33523, st_ino=393374, st_dev=64769, st_nlink=1, st_uid=0, st_gid=0, st_size=33405, st_atime=1530703494, st_mtime=1530703494, st_ctime=1530704112)
>>> os.system('ls -l /root/')
total 12
drwxr-xr-x 3 root root 4096 Jul  4 19:33 cuixiaozhao
drwxr-xr-x 2 root root 4096 Jul  4 19:32 cxz
drwxr-xr-x 2 root root 4096 Jul  4 19:33 tqtl
0
>>> os.system('ls -l /root/cxz')
total 36
--wxrw--wt 1 root root 33405 Jul  4 19:24 man_new.txt
0
>>> os.chmod('/root/cxz/man_new.txt',777)
>>> os.system('ls -l /root/cxz')
total 36
-r----x--t 1 root root 33405 Jul  4 19:24 man_new.txt
0
>>> os.chmod('/root/cxz/man_new.txt',755)
>>> os.system('ls -l /root/cxz')
total 36
--wxrw--wt 1 root root 33405 Jul  4 19:24 man_new.txt
0
>>> os.path.getsize('root/cxz/man_new.txt')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/genericpath.py", line 50, in getsize
    return os.stat(filename).st_size
FileNotFoundError: [Errno 2] No such file or directory: 'root/cxz/man_new.txt'
>>> os.path.getsize('/root/cxz/man_new.txt')
33405
>>> os.path.join('/root/cuixiaozhao','person.txt')
'/root/cuixiaozhao/person.txt'
>>> os.system('ls -l /root/cuixiaozhao')
total 4
drwxr-xr-x 3 root root 4096 Jul  4 19:33 company
0
>>> os.chdir('root/cxz')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'root/cxz'
>>> os.chdir('root/cxz/')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'root/cxz/'
>>> os.chdir('/root/cxz/')
>>> os.system('cd')
0
>>> os.system('pwd')
/root/cxz
0
>>> os.chdir('/root/')
>>> os.system('pwd')
/root
0
>>> os.get_terminal_size()
os.terminal_size(columns=230, lines=50)
>>> os.get_terminal_size()
os.terminal_size(columns=56, lines=16)
>>> os.system('ps -ef|grep redis')
redis    10898     1  0 19:29 ?        00:00:00 /usr/bin/redis-server 127.0.0.1:6379
root     10946 10687  0 19:40 pts/0    00:00:00 sh -c ps -ef|grep redis
root     10948 10946  0 19:40 pts/0    00:00:00 sh -c ps -ef|grep redis
0
>>> os.system('ps -ef|grep redis')
KeyboardInterrupt
>>> os.kill(10899,signal.SIGKILL)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'signal' is not defined
>>> os.kill(10899,signal.SIGKILL)
KeyboardInterrupt
>>> import signal
>>> os.system('ps -ef|grep redis')
redis    10898     1  0 19:29 ?        00:00:00 /usr/bin/redis-server 127.0.0.1:6379
root     10949 10687  0 19:41 pts/0    00:00:00 sh -c ps -ef|grep redis
root     10951 10949  0 19:41 pts/0    00:00:00 sh -c ps -ef|grep redis
0
>>> os.kill(10899,signal.SIGKILL)
>>> os.system('ps -ef|grep redis')
root     10968 10687  0 19:41 pts/0    00:00:00 sh -c ps -ef|grep redis
root     10970 10968  0 19:41 pts/0    00:00:00 sh -c ps -ef|grep redis
0
>>> os.system('systemctl start redis')
0
>>> os.system('ps -ef|grep redis')
redis    10977     1  0 19:41 ?        00:00:00 /usr/bin/redis-server 127.0.0.1:6379
root     10980 10687  0 19:41 pts/0    00:00:00 sh -c ps -ef|grep redis
root     10982 10980  0 19:41 pts/0    00:00:00 sh -c ps -ef|grep redis
0
>>> os.kill(10977,signal.SIGKILL)
>>> os.system('ps -ef|grep redis')
root     10999 10687  0 19:41 pts/0    00:00:00 sh -c ps -ef|grep redis
root     11001 10999  0 19:41 pts/0    00:00:00 sh -c ps -ef|grep redis
0
>>> os.system('systemctl start redis')
0
>>> os.system('systemctl status redis')
● redis.service - Redis persistent key-value database
   Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/redis.service.d
           └─limit.conf
   Active: active (running) since Wed 2018-07-04 19:41:36 CST; 6s ago
  Process: 10983 ExecStop=/usr/libexec/redis-shutdown (code=exited, status=1/FAILURE)
 Main PID: 11008 (redis-server)
   CGroup: /system.slice/redis.service
           └─11008 /usr/bin/redis-server 127.0.0.1:6379

Jul 04 19:41:36 iZ2ze3eaa380cnnuepvyrwZ systemd[1]: Started Redis persistent key-value database.
Jul 04 19:41:36 iZ2ze3eaa380cnnuepvyrwZ systemd[1]: Starting Redis persistent key-value database...
0

13-常用模块学习-sys模块详解

1、sys模块初识;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/31 0031 5:10
import sys
#print(sys.argv)#命令行参数list,第一个元素是程序本身路径
#['13-常用模块学习-sys模块详解.py', 'run', 'web']
#print(sys.exit('退出程序,正常退出时exit(0)'))#退出程序,正常退出时exit(0),不会继续往下执行;
print("打印Python的版本信息:",sys.version)#3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)]
print("在Python3中,打印最大的Int值:",sys.maxsize)#打印最大的Int值:9223372036854775807
#print("打印最大的Int值:",sys.maxint)#在Python2中,打印最大的Int值:9223372036854775807
print("返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值:",sys.path)
"""
返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值:
['C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\文件操作&函数\\模块', 
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018',
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv\\Scripts\\python36.zip', 
'C:\\Program Files\\Python36\\DLLs', 'C:\\Program Files\\Python36\\lib', 'C:\\Program Files\\Python36',
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv',
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv\\lib\\site-packages', 
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv\\lib\\site-packages\\setuptools-39.0.1-py3.6.egg', 
'C:\\Users\\Administrator\\PycharmProjects\\LFXC2018\\venv\\lib\\site-packages\\pip-9.0.3-py3.6.egg', 
'C:\\Program Files\\JetBrains\\PyCharm 2018.1.3\\helpers\\pycharm_matplotlib_backend']
"""
print("返回操作系统平台名称:",sys.platform)#win32,Mac为darwin;
print("返回标准输出:",sys.stdout)#<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
print("返回标准输出:",sys.stdout.write('hey3'))#hey3返回标准输出: 4
print("返回标准输入:",sys.stdin)#返回标准输出: <_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
#print("返回标准输入:",sys.stdin.read())#等待用户输入n行;
#print("返回标准输入:",sys.stdin.readline())#等待用户输入一行;
print("设置最大递归层数:",sys.getrecursionlimit())#设置最大递归层数: 默认1000,递归本身效率不高,不建议修改默认值;
print("获取解释器默认编码:",sys.getdefaultencoding())#utf-8
print("获取内存数据存到文件里的默认编码:",sys.getfilesystemencoding())#utf-8

 

[BEGIN] 2018/7/4 19:47:51
>>> 
KeyboardInterrupt
>>> exit()
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# logout
Connection closing...Socket close.
Connection closed by foreign host.
Disconnected from remote host(47.94.220.79) at 19:47:34.
Type `help' to learn how to use Xshell prompt.
[c:\~]$ 
Connecting to 47.94.220.79:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Last login: Wed Jul  4 19:20:09 2018 from 223.72.55.222
Welcome to Alibaba Cloud Elastic Compute Service !
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# uname -a
Linux iZ2ze3eaa380cnnuepvyrwZ 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# uname -r
3.10.0-693.2.2.el7.x86_64
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# pwd
/root
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# l
-bash: l: command not found
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# ll
total 12
drwxr-xr-x 3 root root 4096 Jul  4 19:33 cuixiaozhao
drwxr-xr-x 2 root root 4096 Jul  4 19:32 cxz
drwxr-xr-x 2 root root 4096 Jul  4 19:33 tqtl
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# vim test.py
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# python3 test.py 
['test.py']
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# python3 test.py run web
['test.py', 'run', 'web']
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# vim test.py 
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# python3 test.py run web
['test.py', 'run', 'web']
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print(bye)
NameError: name 'bye' is not defined
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# vim test.py 
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# python3 test.py run web
['test.py', 'run', 'web']
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print(exit(n))
NameError: name 'n' is not defined
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# vim test.py 
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# python3 test.py run web
['test.py', 'run', 'web']
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# vim test.py 
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# python3 test.py run web
['test.py', 'run', 'web']
by
[root@iZ2ze3eaa380cnnuepvyrwZ ~]# python3
Python 3.6.5 (default, Apr 10 2018, 17:08:37) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version
'3.6.5 (default, Apr 10 2018, 17:08:37) \n[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]'
>>> sys.maxsize
9223372036854775807
>>> sys.maxint
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'sys' has no attribute 'maxint'
>>> sys.maxsize
9223372036854775807
>>> sys.path
['', '/usr/lib64/python36.zip', '/usr/lib64/python3.6', '/usr/lib64/python3.6/lib-dynload', '/usr/lib64/python3.6/site-packages', '/usr/lib/python3.6/site-packages']
>>> sys.platform
'linux'
>>> sys.stdout
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
>>> sys.stdout.write('hello world')
hello world11
>>> sys.stdin.readline()[:-1]
ifconfig
'ifconfig'
>>> cat
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'cat' is not defined
>>> ls
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'ls' is not defined
>>> ll
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'll' is not defined
>>> ls -l
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'ls' is not defined
>>> 
KeyboardInterrupt
>>> 
KeyboardInterrupt
>>> sys.getrecursionlimit()
1000
>>> sys.getrecursionlimit(1200)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: getrecursionlimit() takes no arguments (1 given)
>>> sys.setrecursionlimit(1200)
>>> sys.getrecursionlimit(1200)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: getrecursionlimit() takes no arguments (1 given)
>>> sys.getrecursionlimit()
1200
>>> sys.getdefaultencoding()
'utf-8'
>>> sys.getfilesystemencoding()
'utf-8'

[END] 2018/7/4 21:52:18

 

14-常用模块学习-shutil模块详解

1、shutil模块初识;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/31 0031 5:38
#高级的文件、文件包、压缩包处理模块;
import shutil
# f1 = open(file='sheve_test.py',mode='r',encoding='utf-8')
# f2 = open(file='sheve_test_new.py',mode='w',encoding='utf-8')
# shutil.copyfileobj(f1,f2)#AttributeError: module 'shutil' has no attribute 'copyfileobj'注意不要将文件名设置成模块相同的名称;
# shutil.copyfileobj(f1,f2,length=10)#默认每次读10个;
# shutil.copyfile()#拷贝文件;
# shutil.copymode()#仅拷贝权限,内容、组别、用户均不变;
# shutil.copystat()#拷贝状态的信息,包括mode bits\atime\mtime\flags
# shutil.copy()#拷贝文件和权限;
# shutil.copy2()#拷贝文件和状态信息;
#shutil.ignore_patterns()
#shutil.copytree("packages","packages_copytree")#递归拷贝文件;
#shutil.copytree("packages","pack3",ignore=shutil.ignore_patterns("__init__.py","views.py"))
#shutil.rmtree("pack3")#递归删除文件;
#shutil.move("pack3","py3")#递归删除文件;
#shutil.make_archive()#创建压缩包并返回文件路径,例如zip、tar;
"""
shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar;
base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:www                        =>保存至当前路径
如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
format:    压缩包种类,“zip”, “tar”, “bztar”,“gztar”;
root_dir:    要压缩的文件夹路径(默认当前目录);
owner:    用户,默认当前用户;
group:    组,默认当前组;
logger:    用于记录日志,通常是logging.Logger对象;
"""
#shutil.make_archive("pack3","zip","pack3",owner='administrator')
import zipfile
#压缩;
z = zipfile.ZipFile("zipfiletest.zip","w")
z.write("my_modules.py")
z.write("my_modules.lnk")
z.write("13-常用模块学习-sys模块详解.py")
z.close()
#解压缩;
z = zipfile.ZipFile("zipfiletest.zip","r")
z.extractall()
z.close()
#打包;
import tarfile
t = tarfile.open("zipfiletest.tar","w")
#t.add("sheve_test_new.py")
t.add("sheve_test_new.py",arcname="zipfiletest6")
t.add("pack3.zip")
t.add("pack3.zip")
t.add("01-常用模块学习-小鸡汤.py")

武沛奇讲师的博文:https://www.cnblogs.com/wupeiqi/p/4963027.html 

15-常用模块学习-序列化模块详解

1、序列化初识;

1)什么叫序列化?

序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes;

2)为什么要序列化?

你打游戏过程中,打累了,停下来,关掉游戏、想过2天再玩,2天之后,游戏又从你上次停止的地方继续运行,你上次游戏的进度肯定保存在硬盘上了,是以何种形式呢?游戏过程中产生的很多临时数据是不规律的,可能在你关掉游戏时正好有10个列表,3个嵌套字典的数据集合在内存里,需要存下来?你如何存?把列表变成文件里的多行多列形式?那嵌套字典呢?根本没法存。所以,若是有种办法可以直接把内存数据存到硬盘上,下次程序再启动,再从硬盘上读回来,还是原来的格式的话,那是极好的。

用于序列化的两个模块

  • json,用于字符串 和 python数据类型间进行转换;
  • pickle,用于python特有的类型 和 python的数据类型间进行转换;

Json模块提供了四个功能:dumps、dump、loads、load;

pickle模块提供了四个功能:dumps、dump、loads、load;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/31 0031 6:46
# data = {
#     'roles':[
#         {'role':'monster','type':'pig','life':50},
#         {'role':'hero','type':'关羽','life':80},
#     ]
# }
# f = open(file='game_status',mode='w',encoding='utf-8')
#f.write(str(data))#将数据写入game_status文件;
f = open(file='game_status',mode='r',encoding='utf-8')
d = f.read()
#print(d['roles'])#TypeError: string indices must be integers
#print(dict(d))#print(dict(d))#
d = eval(d)
print(d['roles'])#出现返回值:[{'role': 'monster', 'type': 'pig', 'life': 50}, {'role': 'hero', 'type': '关羽', 'life': 80}]
"""
小结:
1、把内存数据转成字符,叫做‘序列化’;
2、把字符转成内存数据类型,叫做‘反序列化’;
3、相关模块pickle和json;
用途:内存数据很容易存储下来也很容易再转化回去;
"""

16-常用模块学习-序列化json模块详解

1、json详解;

Json模块提供了四个功能:dumps、dump、loads、load;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/31 0031 7:00
# import json
# data = {
#     'roles':[
#         {'role':'monster','type':'pig','life':50},
#         {'role':'hero','type':'关羽','life':80},
#     ]
#}
#dumps
#d = json.dumps(data)
#print(d,type(d))#{"roles": [{"role": "monster", "type": "pig", "life": 50}, {"role": "hero", "type": "\u5173\u7fbd", "life": 80}]} <class 'str'>
#dump不但能变成字符串,还能存储到文件里
# f = open(file='test.json',mode='w',encoding='utf-8')
# json.dump(data,f)#json格式的文件,以json为拓展名;
#f.close()

#d = json.dumps(data)
#d2 = json.loads(d)
#print(d2['roles'])#有返回值,[{'role': 'monster', 'type': 'pig', 'life': 50}, {'role': 'hero', 'type': '关羽', 'life': 80}]


#从文件中加载回来;
import json
# data = {
#     'roles':[
#         {'role':'monster','type':'pig','life':50},
#         {'role':'hero','type':'关羽','life':80},
#     ]
# }
# f = open(file='test.json',mode='r',encoding='utf-8')
# data = json.load(f)
# print(data['roles'])#[{'role': 'monster', 'type': 'pig', 'life': 50}, {'role': 'hero', 'type': '关羽', 'life': 80}]
# f.close()
"""
只是把数据类型转换成字符串存到内存里的意义?
json.dumps json.loads
1、把内存中的数据,通过网络,共享给远程其他人(学习到网络编程后,就知道数据应该是bytes格式传输);
2、实现不同编程语言之间数据传输后能相互读取,定义一个共同的规则,就是json;
纯文本格式读取,不能共享复杂的数据类型;
xml格式存储,但是占用空间大;
json简单,占用空间小,可读性也好;
"""
#dump多次
#f = open(file='json_file',mode='w',encoding='utf-8')
# d = {'name':'fdsjklfjdklas','age':22}
# l = [1,2,3,4,'rain']
# json.dump(d,f)
# json.dump(l,f)
#json_file内容:{"name": "fdsjklfjdklas", "age": 22}[1, 2, 3, 4, "rain"]

#load多次
f2 = open(file='json_file',mode='r',encoding='utf-8')
print(json.load(f2))
'''
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
'''
#JSONDecodeError,json反序列化错误;
#为了避免各种不必要的问题,建议不要使用多次dump;使用一次dump一次load,能对应上;
<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

17-常用模块学习-序列化pickle模块详解

1、pickle详解;(用法与json一模一样,是否跨平台)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/31 0031 7:36
""
"""
import pickle
d = {'name':'fdsjklfjdklas','age':22}
l = [1,2,3,4,'rain']
#pk = open(file='data.pkl',mode='w')#
pk = open(file='data.pkl',mode='wb')#
#print(pickle.dumps(d))
"""
#b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\r\x00\x00\x00fdsjklfjdklasq\x02X\x03\x00\x00\x00ageq\x03K\x16u.'
"""
#pickle.dump(d,pk)#TypeError: write() argument must be str, not bytes
pickle.dump(d,pk)
"""
#加载之硬盘后,再次取回来;
import pickle
f = open(file='data.pkl',mode='rb')#二进制格式读取;
d = pickle.load(f)
print(d)#{'name': 'fdsjklfjdklas', 'age': 22}
#与json一样,不能多次dump和load多次;
"""
小结:
1、json支持的数据类型:str、int、tuple、list、dict,跨平台;
2、pickle支持Python语言里的所有数据类型,但只能在Python中使用,不跨平台;
如何使用以上两种序列化格式呢?
不同语言之间一般用json;
相同的Python语言之间用pickle;
"""

18-常用模块学习-序列化shelve模块详解

1、shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式;


序列化:
import shelve
f = shelve.open('shelve_test')  # 打开一个文件
names = ["alex", "rain", "test"]
info = {'name':'alex','age':22}
f["names"] = names  # 持久化列表;
f['info_dic'] = info
f.close()
反序列化:
import shelve
d = shelve.open('shelve_test')  # 打开一个文件;
print(d['names'])
print(d['info_dic'])
#del d['test'] #还可以删除;

19-常用模块学习-xml处理模块详解

1、xml初识;

xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

xml的格式如下,就是通过<>节点来区别数据结构的:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/5/31 0031 21:35
""
"""
import xml.etree.ElementTree as ET#导入后,起个别名
tree = ET.parse("xml_test")#open文件
root = tree.getroot()#相当于f.seek(0)
#print(root)#<Element 'data' at 0x000002094A2B7868>
#print(dir(root))#['__class__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'attrib', 'clear', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'insert', 'items', 'iter', 'iterfind', 'itertext', 'keys', 'makeelement', 'remove', 'set', 'tag', 'tail', 'text']
print(root.tag)#data,标签的名称叫做data;
#遍历xml文档;
for child in root:
    print('-------------------',child.tag, child.attrib)
    for i in child:#嵌套循环;
        print(i.tag,i.text)

#只遍历year 节点;
for node in root.iter('year'):#过滤year
    print(node.tag,node.text)#先找到tag标签,再找到text的值;
"""
#遍历即循环的意思;
import xml.etree.ElementTree as ET#导入xm了模块后,起个别名
tree = ET.parse("xml_test")#打开文件
root = tree.getroot()#相当于f.seek(0)
# #修改xml文档
# for node in root.iter('year'):
#     new_year = int(node.text)+1
#     node.text = str(new_year)
#     node.set("attr_test","yes")
# tree.write("xml_test")#向文件中循环写入数据
#删除
for country in root.findall('country'):
    rank = int(country.find('rank').text)
    if rank > 50:
        root.remove(country)
tree.write('output.xml')
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year attr_test="yes">2009</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year attr_test="yes">2012</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year attr_test="yes">2012</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
    <state>
        <name>德州</name>
        <population>1000000</population>
    </state>
</data>
xml_test
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year attr_test="yes">2009</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year attr_test="yes">2012</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <state>
        <name>&#24503;&#24030;</name>
        <population>1000000</population>
    </state>
</data>
output.xml

20-常用模块学习-自动创建xml文档

1、通过Python程序,自动创建xml文档;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/2 0002 8:54
#自动创建xml文档;
import xml.etree.ElementTree as ET
root = ET.Element('namelist')#创建namelist节点;

name = ET.SubElement(root,'name',attrib={"enrolled":"yes"})
age = ET.SubElement(name,'age',attrib={"checked":"no"})
sex = ET.SubElement(name,'sex')
sex.text = 'male'
n =ET.SubElement(name,'name')
n.text = 'Alex Li'

name2 = ET.SubElement(root,'name',attrib={"enrolled":"no"})
age2 = ET.SubElement(name2,'age')
age2.text = '19'
et = ET.ElementTree(root)#生成文档对象;
et.write('build_out.xml',encoding='utf-8',xml_declaration=True)
#xml_declaration=True,是否开启xml声明:<?xml version="1.0"?>
<?xml version='1.0' encoding='utf-8'?>
<namelist>
    <name enrolled="yes">
        <age checked="no" />
        <sex>male</sex>
        <name>Alex Li</name>
    </name>
    <name enrolled="no">
        <age>19</age>
    </name>
</namelist>
build_out.xml

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/2 0002 8:54
#自动创建xml文档;
import xml.etree.ElementTree as ET

root = ET.Element('data')#data;

name = ET.SubElement(root,'country',attrib={"name":"Liechtenstein"})
rank = ET.SubElement(name,'rank',attrib={"updated":"yes"})
rank.text = '2'
year = ET.SubElement(name,'year',attrib={"attr_test":"yes"})
year.text = '2009'
gdppc = ET.SubElement(name,'gdppc')
gdppc.text = '141100'
neighbor1 = ET.SubElement(name,'neighbor',attrib={"direction":"E","name":"Austria"})
neighbor2 = ET.SubElement(name,'neighbor',attrib={"direction":"W","name":"Switzerland"})

name = ET.SubElement(root,'country',attrib={'name':'Singapore'})
rank = ET.SubElement(name,'rank',attrib={'updated':'yes'})
rank.text = '5'
year = ET.SubElement(name,'year',attrib={'attr_test':'yes'})
year.text = '2012'
gdppc = ET.SubElement(name,'gdppc')
gdppc.text = '59900'
neighbor3 = ET.SubElement(name,'neighbor',attrib={'direction':'N','name':'Malaysia'})

name = ET.SubElement(root,'country',attrib={'name':'Panama'})
rank = ET.SubElement(name,'updated',attrib={'updated':'yes'})
rank.text = '69'
year = ET.SubElement(name,'year',attrib={'attr_test':'yes'})
year.text = '2012'
gdppc = ET.SubElement(name,'gdppc')
gdppc.text = '13600'
neighbor4 = ET.SubElement(name,'neighbor',attrib={'direction':'W','name':'Costa Rica'})
neighbor5 = ET.SubElement(name,'neighbor',attrib={'direction':'E','name':'Colombia'})

et = ET.ElementTree(root)#生成文档对象;
et.write('build_out_practice.xml',encoding='utf-8',xml_declaration=True)
#xml_declaration=True,是否开启xml声明:<?xml version="1.0"?>

 

 

<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year attr_test="yes">2009</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year attr_test="yes">2012</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <updated updated="yes">69</updated>
        <year attr_test="yes">2012</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>

 

21-常用模块学习-configparser模块详解_batch

1、configparset模块初识;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/2 0002 9:18
#解析配置文件模块,Configparser
#MySQL数据库的配置文件my.cnf;
# import configparser #在Python2中是大写ConfigParser
# conf = configparser.ConfigParser()
# #print(conf.sections())
# conf.read('conf.ini')
# print(conf.sections())#每一个配置文件里都有一个DEFAULT,['bitbucket.org', 'topsecret.server.com']
# print(conf.default_section)#DEFAULT,单独列出;
# print(conf['bitbucket.org'])#<Section: bitbucket.org>
# print(dir(conf['bitbucket.org']))#['_MutableMapping__marker', '__abstractmethods__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__setitem__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', '_abc_registry', '_name', '_options', '_parser', 'clear', 'get', 'getboolean', 'getfloat', 'getint', 'items', 'keys', 'name', 'parser', 'pop', 'popitem', 'setdefault', 'update', 'values']
# print(list(conf['bitbucket.org'].keys()))#['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
# print(conf['bitbucket.org']['User'])#User
# for k in conf['bitbucket.org']:
#     print(k)#默认还会打印DEAULT下的内容;
#     """
#     user
# serveraliveinterval
# compression
# compressionlevel
# forwardx11
#     """
# #做判断的参数;
# if 'user' in conf['bitbucket.org']:
#     print('Yes,in it')#Yes,in it
# else:
#     print('No,not in it')
import  configparser
conf = configparser.ConfigParser()
conf.read('conf_test.ini')
print(dir(conf))
"""
['BOOLEAN_STATES', 'NONSPACECRE', 'OPTCRE', 'OPTCRE_NV', 'SECTCRE',
 '_DEFAULT_INTERPOLATION', '_MutableMapping__marker', '_OPT_NV_TMPL', 
 '_OPT_TMPL', '_SECT_TMPL', '__abstractmethods__', '__class__', '__contains__',
  '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__',
   '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', 
   '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', 
   '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
    '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__setitem__', 
    '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', 
    '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', 
    '_abc_registry', '_allow_no_value', '_comment_prefixes', '_convert_to_boolean',
     '_converters', '_defaults', '_delimiters', '_dict', '_empty_lines_in_values', 
     '_get', '_get_conv', '_handle_error', '_inline_comment_prefixes',
      '_interpolation', '_join_multiline_values', '_optcre', '_proxies',
       '_read', '_sections', '_strict', '_unify_values', '_validate_value_types',
        '_write_section', 'add_section', 'clear', 'converters', 'default_section', 
        'defaults', 'get', 'getboolean', 'getfloat', 'getint', 'has_option', 
        'has_section', 'items', 'keys', 'options', 'optionxform', 'pop', 'popitem',
         'read', 'read_dict', 'read_file', 'read_string', 'readfp', 'remove_option',
          'remove_section', 'sections', 'set', 'setdefault', 'update', 'values', 'write']
"""
print(conf.options('group1'))#['k1', 'k2']
print(conf['group1']['k2'])#v2
conf.add_section('group3')
conf['group3']['name']="Alex Li"
#conf['group3']['age']=22,不能写成整型数字;
conf['group3']['age']="22"
conf.write(open('conf_test_new.ini','w'))
conf.remove_option('group1','k2')

#删除,删除之后,要重新写入;
conf.remove_option('group1','k2')
conf.write(open('conf_test_remove.ini','w'))
[group1]
k1=v1
k2:v2
[group2]
k1=v1
conf_test.ini
[group1]
k1 = v1
k2 = v2

[group2]
k1 = v1

[group3]
name = Alex Li
age = 22
conf_test_new.ini
[group1]
k1 = v1

[group2]
k1 = v1

[group3]
name = Alex Li
age = 22
conf_test_remove.ini

22-常用模块学习-hashlib加密模块详解

1、安全知识初识;

加密算法介绍

HASH

Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。

简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

HASH主要用于信息安全领域中加密算法,他把一些不同长度的信息转化成杂乱的128位的编码里,叫做HASH值.也可以说,hash就是找到一种数据内容和数据存放地址之间的映射关系;

MD5

  • 什么是MD5算法

MD5讯息摘要演算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码杂凑函数,可以产生出一个128位的散列值(hash value),用于确保信息传输完整一致。MD5的前身有MD2、MD3和MD4。

MD5功能

输入任意长度的信息,经过处理,输出为128位的信息(数字指纹)
不同的输入得到的不同的结果(唯一性);

  • MD5算法的特点
  1. 压缩性:任意长度的数据,算出的MD5值的长度都是固定的;
  2. 容易计算:从原数据计算出MD5值很容易;
  3. 抗修改性:对原数据进行任何改动,修改一个字节生成的MD5值区别也会很大;
  4. 强抗碰撞:已知原数据和MD5,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
  • MD5算法是否可逆?

MD5不可逆的原因是其是一种散列函数,使用的是hash算法,在计算过程中原文的部分信息是丢失了的。

  • MD5用途
  1. 防止被篡改:

    • 比如发送一个电子文档,发送前,我先得到MD5的输出结果a。然后在对方收到电子文档后,对方也得到一个MD5的输出结果b。如果a与b一样就代表中途未被篡改。

    • 比如我提供文件下载,为了防止不法分子在安装程序中添加木马,我可以在网站上公布由安装文件得到的MD5输出结果。

    • SVN在检测文件是否在CheckOut后被修改过,也是用到了MD5。

  2. 防止直接看到明文:

    • 现在很多网站在数据库存储用户的密码的时候都是存储用户密码的MD5值。这样就算不法分子得到数据库的用户密码的MD5值,也无法知道用户的密码。(比如在UNIX系统中用户的密码就是以MD5(或其它类似的算法)经加密后存储在文件系统中。当用户登录的时候,系统把用户输入的密码计算成MD5值,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道,而且还在一定程度上增加了密码被破解的难度。)
  3. 防止抵赖(数字签名):

    • 这需要一个第三方认证机构。例如A写了一个文件,认证机构对此文件用MD5算法产生摘要信息并做好记录。若以后A说这文件不是他写的,权威机构只需对此文件重新产生摘要信息,然后跟记录在册的摘要信息进行比对,相同的话,就证明是A写的了。这就是所谓的“数字签名”。

SHA-1

安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。

SHA是美国国家安全局设计的,由美国国家标准和技术研究院发布的一系列密码散列函数。

由于MD5和SHA-1于2005年被山东大学的教授王小云破解了,科学家们又推出了SHA224, SHA256, SHA384, SHA512,当然位数越长,破解难度越大,但同时生成加密的消息摘要所耗时间也更长。目前最流行的是加密算法是SHA-256 。

MD5与SHA-1的比较

由于MD5与SHA-1均是从MD4发展而来,它们的结构和强度等特性有很多相似之处,SHA-1与MD5的最大区别在于其摘要比MD5摘要长32 比特。对于强行攻击,产生任何一个报文使之摘要等于给定报文摘要的难度:MD5是2128数量级的操作,SHA-1是2160数量级的操作。产生具有相同摘要的两个报文的难度:MD5是264是数量级的操作,SHA-1 是280数量级的操作。因而,SHA-1对强行攻击的强度更大。但由于SHA-1的循环步骤比MD5多80:64且要处理的缓存大160比特:128比特,SHA-1的运行速度比MD5慢。

Python的 提供的相关模块

用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法;

#!/usr/bin/env python
# -*- coding:utf8 -*-
#__author__:TQTL
#date: 2018/6/2 12:11 
# Author:TQTL
# E-mail:tqtl911@163.com
print(hash('cuixiaozhao'))#132578110972320087,绝大多数情况下,保证在当前程序西下是唯一的,但有重复的可能性;
print(len(str(hash('cuixiaozhao'))))#19位字符长度;
import hashlib
m = hashlib.md5()
m.update(b'alex')
print(m)#<md5 HASH object @ 0x000001B271227968>
print(m.hexdigest())#534b44a19bf18d20b71ecc4eb77c572f,永远不会变化,是唯一值;可以用作数字签名;
print(len(m.hexdigest()))#32位字符长度;
#通过撞库的方案,破解简单的md5值;

网站参考: http://www.cmd5.com/ 

23-常用模块学习-subprocess模块详解

1、subprocess初识;

我们经常需要通过Python去执行一条系统命令或脚本,系统的shell命令是独立于我们的python进程之外的,每执行一条命令,就是发起一个新进程,通过python调用系统命令或脚本的模块在python2有os.system,

[root@iZqmo9i3j77p7eZ ~]# python3
Python 3.6.5 (default, Apr 10 2018, 17:08:37)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system('uname -a ')
Linux iZqmo9i3j77p7eZ 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
0
>>>

这条命令的实现原理是什么呢?(视频中讲,解释进程间通信的问题...)

除了os.system可以调用系统命令,commands,popen2等也可以,比较乱,于是官方推出了subprocess,目地是提供统一的模块来实现对系统命令或脚本的调用;

三种执行命令的方法

  • subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs) #官方推荐;

  • subprocess.call(*popenargs, timeout=None, **kwargs) #跟上面实现的内容差不多,另一种写法;

  • subprocess.Popen() #上面各种方法的底层封装;

2、阿里云CentOS7.X下安装Python3;

Last failed login: Fri Jun  1 17:56:36 CST 2018 from 59.63.166.104 on ssh:notty
There were 3 failed login attempts since the last successful login.
Last login: Fri Jun  1 17:45:27 2018 from 117.119.97.51

Welcome to Alibaba Cloud Elastic Compute Service !

[root@iZqmo9i3j77p7eZ ~]# yum install epel-release -y
Loaded plugins: fastestmirror
base                                                                                                                                                                                                                 | 3.6 kB  00:00:00     
epel                                                                                                                                                                                                                 | 3.2 kB  00:00:00     
extras                                                                                                                                                                                                               | 3.4 kB  00:00:00     
nginx                                                                                                                                                                                                                | 2.9 kB  00:00:00     
updates                                                                                                                                                                                                              | 3.4 kB  00:00:00     
(1/3): extras/7/x86_64/primary_db                                                                                                                                                                                    | 147 kB  00:00:00     
(2/3): epel/x86_64/primary                                                                                                                                                                                           | 3.5 MB  00:00:00     
(3/3): epel/x86_64/updateinfo                                                                                                                                                                                        | 933 kB  00:00:00     
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * epel: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
epel                                                                                                                                                                                                                            12584/12584
Resolving Dependencies
--> Running transaction check
---> Package epel-release.noarch 0:7-11 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================================================================================================
 Package                                                       Arch                                                    Version                                                  Repository                                             Size
============================================================================================================================================================================================================================================
Installing:
 epel-release                                                  noarch                                                  7-11                                                     epel                                                   15 k

Transaction Summary
============================================================================================================================================================================================================================================
Install  1 Package

Total download size: 15 k
Installed size: 24 k
Downloading packages:
epel-release-7-11.noarch.rpm                                                                                                                                                                                         |  15 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : epel-release-7-11.noarch                                                                                                                                                                                                 1/1 
warning: /etc/yum.repos.d/epel.repo created as /etc/yum.repos.d/epel.repo.rpmnew
  Verifying  : epel-release-7-11.noarch                                                                                                                                                                                                 1/1 

Installed:
  epel-release.noarch 0:7-11                                                                                                                                                                                                                

Complete!
[root@iZqmo9i3j77p7eZ ~]# yum install https://centos7.iuscommunity.org/ius-release.rpm -y
Loaded plugins: fastestmirror
ius-release.rpm                                                                                                                                                                                                      | 8.1 kB  00:00:00     
Examining /var/tmp/yum-root-c8qWEb/ius-release.rpm: ius-release-1.0-15.ius.centos7.noarch
Marking /var/tmp/yum-root-c8qWEb/ius-release.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package ius-release.noarch 0:1.0-15.ius.centos7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================================================================================================
 Package                                                 Arch                                               Version                                                          Repository                                                Size
============================================================================================================================================================================================================================================
Installing:
 ius-release                                             noarch                                             1.0-15.ius.centos7                                               /ius-release                                             8.5 k

Transaction Summary
============================================================================================================================================================================================================================================
Install  1 Package

Total size: 8.5 k
Installed size: 8.5 k
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : ius-release-1.0-15.ius.centos7.noarch                                                                                                                                                                                    1/1 
  Verifying  : ius-release-1.0-15.ius.centos7.noarch                                                                                                                                                                                    1/1 

Installed:
  ius-release.noarch 0:1.0-15.ius.centos7                                                                                                                                                                                                   

Complete!
[root@iZqmo9i3j77p7eZ ~]# yum install python36u -y
Loaded plugins: fastestmirror
ius                                                                                                                                                                                                                  | 2.3 kB  00:00:00     
ius/x86_64/primary_db                                                                                                                                                                                                | 250 kB  00:00:00     
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * epel: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * ius: mirrors.tuna.tsinghua.edu.cn
 * updates: mirrors.aliyun.com
Resolving Dependencies
--> Running transaction check
---> Package python36u.x86_64 0:3.6.5-1.ius.centos7 will be installed
--> Processing Dependency: python36u-libs(x86-64) = 3.6.5-1.ius.centos7 for package: python36u-3.6.5-1.ius.centos7.x86_64
--> Processing Dependency: libpython3.6m.so.1.0()(64bit) for package: python36u-3.6.5-1.ius.centos7.x86_64
--> Running transaction check
---> Package python36u-libs.x86_64 0:3.6.5-1.ius.centos7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================================================================================================
 Package                                                     Arch                                                Version                                                             Repository                                        Size
============================================================================================================================================================================================================================================
Installing:
 python36u                                                   x86_64                                              3.6.5-1.ius.centos7                                                 ius                                               57 k
Installing for dependencies:
 python36u-libs                                              x86_64                                              3.6.5-1.ius.centos7                                                 ius                                              8.7 M

Transaction Summary
============================================================================================================================================================================================================================================
Install  1 Package (+1 Dependent package)

Total download size: 8.8 M
Installed size: 40 M
Downloading packages:
warning: /var/cache/yum/x86_64/7/ius/packages/python36u-3.6.5-1.ius.centos7.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 9cd4953f: NOKEY
Public key for python36u-3.6.5-1.ius.centos7.x86_64.rpm is not installed
(1/2): python36u-3.6.5-1.ius.centos7.x86_64.rpm                                                                                                                                                                      |  57 kB  00:00:00     
(2/2): python36u-libs-3.6.5-1.ius.centos7.x86_64.rpm                                                                                                                                                                 | 8.7 MB  00:00:00     
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                        16 MB/s | 8.8 MB  00:00:00     
Retrieving key from file:///etc/pki/rpm-gpg/IUS-COMMUNITY-GPG-KEY
Importing GPG key 0x9CD4953F:
 Userid     : "IUS Community Project <coredev@iuscommunity.org>"
 Fingerprint: 8b84 6e3a b3fe 6462 74e8 670f da22 1cdf 9cd4 953f
 Package    : ius-release-1.0-15.ius.centos7.noarch (installed)
 From       : /etc/pki/rpm-gpg/IUS-COMMUNITY-GPG-KEY
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python36u-libs-3.6.5-1.ius.centos7.x86_64                                                                                                                                                                                1/2 
  Installing : python36u-3.6.5-1.ius.centos7.x86_64                                                                                                                                                                                     2/2 
  Verifying  : python36u-3.6.5-1.ius.centos7.x86_64                                                                                                                                                                                     1/2 
  Verifying  : python36u-libs-3.6.5-1.ius.centos7.x86_64                                                                                                                                                                                2/2 

Installed:
  python36u.x86_64 0:3.6.5-1.ius.centos7                                                                                                                                                                                                    

Dependency Installed:
  python36u-libs.x86_64 0:3.6.5-1.ius.centos7                                                                                                                                                                                               

Complete!
[root@iZqmo9i3j77p7eZ ~]# ln -s /bin/python3.6 /bin/python3
[root@iZqmo9i3j77p7eZ ~]# yum install python36u-pip -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * epel: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * ius: mirrors.tongji.edu.cn
 * updates: mirrors.aliyun.com
Resolving Dependencies
--> Running transaction check
---> Package python36u-pip.noarch 0:9.0.1-1.ius.centos7 will be installed
--> Processing Dependency: python36u-setuptools for package: python36u-pip-9.0.1-1.ius.centos7.noarch
--> Running transaction check
---> Package python36u-setuptools.noarch 0:39.0.1-1.ius.centos7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================================================================================================
 Package                                                          Arch                                               Version                                                          Repository                                       Size
============================================================================================================================================================================================================================================
Installing:
 python36u-pip                                                    noarch                                             9.0.1-1.ius.centos7                                              ius                                             1.8 M
Installing for dependencies:
 python36u-setuptools                                             noarch                                             39.0.1-1.ius.centos7                                             ius                                             642 k

Transaction Summary
============================================================================================================================================================================================================================================
Install  1 Package (+1 Dependent package)

Total download size: 2.4 M
Installed size: 13 M
Downloading packages:
(1/2): python36u-setuptools-39.0.1-1.ius.centos7.noarch.rpm                                                                                                                                                          | 642 kB  00:00:00     
(2/2): python36u-pip-9.0.1-1.ius.centos7.noarch.rpm                                                                                                                                                                  | 1.8 MB  00:00:00     
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                       4.7 MB/s | 2.4 MB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python36u-setuptools-39.0.1-1.ius.centos7.noarch                                                                                                                                                                         1/2 
  Installing : python36u-pip-9.0.1-1.ius.centos7.noarch                                                                                                                                                                                 2/2 
  Verifying  : python36u-setuptools-39.0.1-1.ius.centos7.noarch                                                                                                                                                                         1/2 
  Verifying  : python36u-pip-9.0.1-1.ius.centos7.noarch                                                                                                                                                                                 2/2 

Installed:
  python36u-pip.noarch 0:9.0.1-1.ius.centos7                                                                                                                                                                                                

Dependency Installed:
  python36u-setuptools.noarch 0:39.0.1-1.ius.centos7                                                                                                                                                                                        

Complete!
[root@iZqmo9i3j77p7eZ ~]# ln -s /bin/pip3.6 /bin/pip3
[root@iZqmo9i3j77p7eZ ~]# python3
Python 3.6.5 (default, Apr 10 2018, 17:08:37) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
View Code

3、subprocess.run方法实际演练;

[root@iZqmo9i3j77p7eZ ~]# python3
Python 3.6.5 (default, Apr 10 2018, 17:08:37) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> subprocess.run(['df','-h'])
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  2.1G   36G   6% /
devtmpfs        911M     0  911M   0% /dev
tmpfs           920M     0  920M   0% /dev/shm
tmpfs           920M  340K  920M   1% /run
tmpfs           920M     0  920M   0% /sys/fs/cgroup
tmpfs           184M     0  184M   0% /run/user/0
CompletedProcess(args=['df', '-h'], returncode=0)
>>> a = subprocess.run(['df','-h'])
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  2.1G   36G   6% /
devtmpfs        911M     0  911M   0% /dev
tmpfs           920M     0  920M   0% /dev/shm
tmpfs           920M  340K  920M   1% /run
tmpfs           920M     0  920M   0% /sys/fs/cgroup
tmpfs           184M     0  184M   0% /run/user/0
>>> a
CompletedProcess(args=['df', '-h'], returncode=0)
>>> a.stdout.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'read'
>>> a.returncode
0
>>> a.args
['df', '-h']
>>> a.check_returncode()
>>> a.stdout.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'read'
>>> a = subprocess.run(['df','-h'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> a.stdout
b'Filesystem      Size  Used Avail Use% Mounted on\n/dev/vda1        40G  2.1G   36G   6% /\ndevtmpfs        911M     0  911M   0% /dev\ntmpfs           920M     0  920M   0% /dev/shm\ntmpfs           920M  340K  920M   1% /run\ntmpfs           920M     0  920M   0% /sys/fs/cgroup\ntmpfs           184M     0  184M   0% /run/user/0\n'
>>> a.stderr
b''
>>> a = subprocess.run(['df','-fdsfh'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> a.stdout
b''
>>> a.stderr
b"df: invalid option -- 'f'\nTry 'df --help' for more information.\n"
>>> a = subprocess.run(['df','-fdsfh'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/subprocess.py", line 418, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['df', '-fdsfh']' returned non-zero exit status 1.
>>> a = subprocess.run(['df','-fdsfh'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
KeyboardInterrupt
>>> exit()
[root@iZqmo9i3j77p7eZ ~]# df 
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/vda1       41151808 2199444  36838932   6% /
devtmpfs          932240       0    932240   0% /dev
tmpfs             941748       0    941748   0% /dev/shm
tmpfs             941748     340    941408   1% /run
tmpfs             941748       0    941748   0% /sys/fs/cgroup
tmpfs             188352       0    188352   0% /run/user/0
[root@iZqmo9i3j77p7eZ ~]# df -h |grep vda1
/dev/vda1        40G  2.1G   36G   6% /
[root@iZqmo9i3j77p7eZ ~]# 
[root@iZqmo9i3j77p7eZ ~]# 
[root@iZqmo9i3j77p7eZ ~]# python3
Python 3.6.5 (default, Apr 10 2018, 17:08:37) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = subprocess.run(['df','-h','|','grep','vda1'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'subprocess' is not defined
>>> import subprocess
>>> a.stdout.read()     
KeyboardInterrupt
>>> a = subprocess.run(['df','-h','|','grep','vda1'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,check=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/subprocess.py", line 418, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['df', '-h', '|', 'grep', 'vda1']' returned non-zero exit status 1.
>>> a = subprocess.run(['df','-h','|','grep','vda1'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)           
>>> a.stderr
b'df: \xe2\x80\x98|\xe2\x80\x99: No such file or directory\ndf: \xe2\x80\x98grep\xe2\x80\x99: No such file or directory\ndf: \xe2\x80\x98vda1\xe2\x80\x99: No such file or directory\n'
>>> a = subprocess.run('df -h |grep vda1',stdout=subprocess.PIPE,stderr=subprocess.PIPE)           
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/subprocess.py", line 403, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib64/python3.6/subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.6/subprocess.py", line 1344, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'df -h |grep vda1': 'df -h |grep vda1'
>>> a = subprocess.run('df -h |grep vda1',stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)#添加shell声明;
>>> 

24-常用模块学习-subprocess模块详解2

1、subprocess.call方法;

[root@iZqmo9i3j77p7eZ ~]# python3
Python 3.6.5 (default, Apr 10 2018, 17:08:37) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system('uname -a ')
Linux iZqmo9i3j77p7eZ 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
0
>>> import subprocess              
>>> subprocess.call(['ls','-lsh'])
total 0
0
>>> subprocess.check_call(['ls','-lsh'])
total 0
0
>>> subprocess.check_call(['ls','-lsh'])
total 4.0K
   0 srwxr-xr-x 1 root root    0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>
4.0K drwx------ 3 root root 4.0K May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R
0
>>> subprocess.getoutput(['ls','-lsh']) 
'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\nsystemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R'
>>> subprocess.getoutput(['ls /bin/ls'])
'/bin/ls'
>>> res = subprocess.checkoutput(['ls','-l'])       
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'subprocess' has no attribute 'checkoutput'
>>> res = subprocess.check_output(['ls','-l'])
>>> res
b'total 4\nsrwxr-xr-x 1 root root    0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\ndrwx------ 3 root root 4096 May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R\n'
>>> help(subprocess.check_output)
Help on function check_output in module subprocess:

check_output(*popenargs, timeout=None, **kwargs)
    Run command with arguments and return its output.
    
    If the exit code was non-zero it raises a CalledProcessError.  The
    CalledProcessError object will have the return code in the returncode
    attribute and output in the output attribute.
    
    The arguments are the same as for the Popen constructor.  Example:
    
    >>> check_output(["ls", "-l", "/dev/null"])
    b'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
    
    The stdout argument is not allowed as it is used internally.
    To capture standard error in the result, use stderr=STDOUT.
    
    >>> check_output(["/bin/sh", "-c",
    ...               "ls -l non_existent_file ; exit 0"],
    ...              stderr=STDOUT)
    b'ls: non_existent_file: No such file or directory\n'
    
    There is an additional optional argument, "input", allowing you to
    pass a string to the subprocess's stdin.  If you use this argument
    you may not also use the Popen constructor's "stdin" argument, as
    it too will be used internally.  Example:
    
    >>> check_output(["sed", "-e", "s/foo/bar/"],
    ...              input=b"when in the course of fooman events\n")
    b'when in the course of barman events\n'
    
    If universal_newlines=True is passed, the "input" argument must be a
    string and the return value will be a string rather than bytes.

>>> 
>>> 
call方法

2、subprocess.Popen方法;

[root@iZqmo9i3j77p7eZ ~]# python3
Python 3.6.5 (default, Apr 10 2018, 17:08:37) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system('uname -a ')
Linux iZqmo9i3j77p7eZ 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
0
>>> import subprocess              
>>> subprocess.call(['ls','-lsh'])
total 0
0
>>> subprocess.check_call(['ls','-lsh'])
total 0
0
>>> subprocess.check_call(['ls','-lsh'])
total 4.0K
   0 srwxr-xr-x 1 root root    0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>
4.0K drwx------ 3 root root 4.0K May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R
0
>>> subprocess.getoutput(['ls','-lsh']) 
'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\nsystemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R'
>>> subprocess.getoutput(['ls /bin/ls'])
'/bin/ls'
>>> res = subprocess.checkoutput(['ls','-l'])       
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'subprocess' has no attribute 'checkoutput'
>>> res = subprocess.check_output(['ls','-l'])
>>> res
b'total 4\nsrwxr-xr-x 1 root root    0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\ndrwx------ 3 root root 4096 May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R\n'
>>> help(subprocess.check_output)
Help on function check_output in module subprocess:

check_output(*popenargs, timeout=None, **kwargs)
    Run command with arguments and return its output.
    
    If the exit code was non-zero it raises a CalledProcessError.  The
    CalledProcessError object will have the return code in the returncode
    attribute and output in the output attribute.
    
    The arguments are the same as for the Popen constructor.  Example:
    
    >>> check_output(["ls", "-l", "/dev/null"])
    b'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
    
    The stdout argument is not allowed as it is used internally.
    To capture standard error in the result, use stderr=STDOUT.
    
    >>> check_output(["/bin/sh", "-c",
    ...               "ls -l non_existent_file ; exit 0"],
    ...              stderr=STDOUT)
    b'ls: non_existent_file: No such file or directory\n'
    
    There is an additional optional argument, "input", allowing you to
    pass a string to the subprocess's stdin.  If you use this argument
    you may not also use the Popen constructor's "stdin" argument, as
    it too will be used internally.  Example:
    
    >>> check_output(["sed", "-e", "s/foo/bar/"],
    ...              input=b"when in the course of fooman events\n")
    b'when in the course of barman events\n'
    
    If universal_newlines=True is passed, the "input" argument must be a
    string and the return value will be a string rather than bytes.

>>> 
>>> a = subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE)
>>> subprocess.Popen()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'args'
>>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)   
>>> a.poll()
0
>>> a.poll()
0
>>> a.poll()
0
>>> a.poll()
0
>>> a.poll()
0
>>> a.poll()
0
>>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
>>> a.poll()
0
>>> a.poll()
0
>>> a.poll()
0
>>> a.poll()
0
>>> a.poll()
0
>>> def sayhi():
... print('run...hahahah')
  File "<stdin>", line 2
    print('run...hahahah')
        ^
IndentationError: expected an indented block
>>> def sayhi():          
...     print('run...hahahah')
... a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
  File "<stdin>", line 3
    a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
    ^
SyntaxError: invalid syntax
>>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sayhi' is not defined
>>> def sayhi():              
...     print('run...hahahah')
... a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
  File "<stdin>", line 3
    a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
    ^
SyntaxError: invalid syntax
>>> import subprocess
>>> def sayhi():              
...     print('run...hahahah')
... 
>>> 
>>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
>>> a.stdout
<_io.BufferedReader name=3>
>>> a.stdout.read()
b'run...hahahah\n'
>>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,cwd="/tmp",stdout=subprocess.PIPE,preexec_fn=sayhi)  
>>> a.stdout.read()
b'run...hahahah\n/tmp\n'
>>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)           
>>> a.stdout.read()
b'run...hahahah\n/root\n'
>>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
>>> a.wait()
0
>>> a = subprocess.Popen('echo $PWD;sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi)
>>> a.wait()
0
>>> a = subprocess.Popen('sleep 100',shell=True,stdout=subprocess.PIPE)                          
>>> a.pid
32476
>>> a.terminate()
>>> a.pid
32476
>>> a.pid
32476
>>> a.pid
32476
>>> a.terminate()
>>> a = subprocess.Popen('sleep 100',shell=True,stdout=subprocess.PIPE)
>>> a.pid
32493
>>> a.kill()
>>> a.pid   
32493
>>> a = subprocess.Popen('for i in $(seq 1 100);do sleep 1;echo $i >>sleep.log;done',shell=True,stdout=subprocess.PIPE)
>>> a = subprocess.Popen('for i in $(seq 1 100);do sleep 1;echo $i >>sleep.log;done',shell=True,stdout=subprocess.PIPE)
KeyboardInterrupt
>>> a.pid
32494
>>> a.kill()
KeyboardInterrupt
>>> help(os.kill)
Help on built-in function kill in module posix:

kill(pid, signal, /)
    Kill a process with a signal.

>>> 
Popen方法

常用参数:

  • args:shell命令,可以是字符串或者序列类型(如:list,元组);
  • stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄;
  • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用;
  • shell:同上;
  • cwd:用于设置子进程的当前目录;
  • env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承;

下面这2条语句执行会有什么区别?

a=subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE)
a=subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)

区别是Popen会在发起命令后立刻返回,而不等命令执行结果。这样的好处是什么呢?

如果你调用的命令或脚本 需要执行10分钟,你的主程序不需卡在这里等10分钟,可以继续往下走,干别的事情,每过一会,通过一个什么方法来检测一下命令是否执行完成就好了。

Popen调用后会返回一个对象,可以通过这个对象拿到命令执行结果或状态等,该对象有以下方法

poll()

Check if child process has terminated. Returns returncode

wait()

Wait for child process to terminate. Returns returncode attribute.

terminate()终止所启动的进程Terminate the process with SIGTERM

kill() 杀死所启动的进程 Kill the process with SIGKILL

communicate()与启动的进程交互,发送数据到stdin,并从stdout接收输出,然后等待任务结束;

>>> a = subprocess.Popen('python3 guess_age.py',stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,shell=True)

>>> a.communicate(b'22')

(b'your guess:try bigger\n', b'')

send_signal(signal.xxx)发送系统信号;

pid 拿到所启动进程的进程号;

25-常用模块学习-logging模块基础

1、logging模块初识;

很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,我们可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical()5个级别,下面我们看一下怎么用。

最简单用法

import logging

logging.warning("user [alex] attempted wrong password more than 3 times")
logging.critical("server is down")

输出

WARNING:root:user [alex] attempted wrong password more than 3 times
CRITICAL:root:server is down

看一下这几个日志级别分别代表什么意思

LevelWhen it’s used
DEBUG Detailed information, typically of interest only when diagnosing problems.
INFO Confirmation that things are working as expected.
WARNING An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected.
ERROR Due to a more serious problem, the software has not been able to perform some function.
CRITICAL A serious error, indicating that the program itself may be unable to continue running.

如果想把日志写到文件里,也很简单

import logging

logging.basicConfig(filename='example.log',level=logging.INFO)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

其中下面这句中的level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。

logging.basicConfig(filename='example.log',level=logging.INFO)

自定义日志格式

感觉上面的日志格式忘记加上时间啦,日志不知道时间怎么行呢,下面就来加上!

import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')

#输出
12/12/2010 11:46:36 AM is when this event was logged.

除了加时间,还可以自定义一大堆格式,下表就是所有支持的格式

%(name)sLogger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s 用户输出的消息
#!/usr/bin/env python
# -*- coding:utf8 -*-
#__author__:TQTL
#date: 2018/6/2 14:17 
# Author:TQTL
# E-mail:tqtl911@163.com
#Python的日志模块
import logging
# logging.warning("user [alex] attempted wrong password more than 3 times")
# logging.critical("Server is down")
"""
WARNING:root:user [alex] attempted wrong password more than 3 times
CRITICAL:root:Server is down
"""
# logging.basicConfig(filename='log_test.log',level=logging.INFO)#指定日志的级别为INFO或比INFO级别更高的;
#
# logging.debug("This message should go to log file.")#此行,无法打印至日志文件中;
# logging.info("So should this.")
# logging.warning("And this,too.")
#自定义日志格式;
logging.basicConfig(filename='log_test.log',
                    level=logging.DEBUG,
                    #format='%(asctime)s %(message)s',
                    #format='%(asctime)s-%(levelno)s- %(message)s',
                    #format='%(asctime)s-%(levelname)s- %(message)s',
                    #format='%(asctime)s-%(levelname)s-%(pathname)s-%(message)s',
                    #format='%(asctime)s-%(levelname)s-%(filename)s-%(message)s',
                    #format='%(asctime)s-%(levelname)s-%(funcName)s-%(message)s',
                    format='%(asctime)s-%(levelname)s-%(funcName)s-%(lineno)s-%(message)s',
                    datefmt='%m/%d/%Y %I:%M:%S %p')
def sayhi():
    logging.error("from sayhi;")
sayhi()
logging.debug("This message should go to log file.")#此行,无法打印至日志文件中;
logging.info("So should this.")
logging.warning("And this,too.")
logging.warning("-------------------------------------------")
logging模块基础
06/02/2018 02:40:58 PM-ERROR-sayhi-from sayhi;
06/02/2018 02:40:58 PM-DEBUG-<module>-This message should go to log file.
06/02/2018 02:40:58 PM-INFO-<module>-So should this.
06/02/2018 02:40:58 PM-WARNING-<module>-And this,too.
06/02/2018 02:40:58 PM-WARNING-<module>--------------------------------------------
06/02/2018 02:41:36 PM-ERROR-sayhi-32-from sayhi;
06/02/2018 02:41:36 PM-DEBUG-<module>-34-This message should go to log file.
06/02/2018 02:41:36 PM-INFO-<module>-35-So should this.
06/02/2018 02:41:36 PM-WARNING-<module>-36-And this,too.
06/02/2018 02:41:36 PM-WARNING-<module>-37--------------------------------------------
log_test.log

26-常用模块学习-logging模块进阶

1、日志同时输出到屏幕和文件

如果想同时把log打印在屏幕和文件日志里,就需要了解一点复杂的知识 了

Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:

  • logger提供了应用程序可以直接使用的接口;
  • handler将(logger创建的)日志记录发送到合适的目的输出;
  • filter提供了细度设备来决定输出哪条日志记录;
  • formatter决定日志记录的最终输出格式;

他们之间的关系是这样的每个组件的主要功能

logger

每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:

LOG=logging.getLogger(”chat.gui”)

而核心模块可以这样:

LOG=logging.getLogger(”chat.kernel”)

还可以绑定handler和filters

Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高;
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter;
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler;

Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

handler

handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Handler可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler

Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:

  1. logging.StreamHandler 使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。
  2. logging.FileHandler 和StreamHandler 类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件
  3. logging.handlers.RotatingFileHandler

    这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的函数是:

     RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
    

    其中filename和mode两个参数和FileHandler一样。

    • maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
    • backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
  4. logging.handlers.TimedRotatingFileHandler

    这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的函数是:

    TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
    

    其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。

    interval是时间间隔。

    when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:

    • S 秒
    • M 分
    • H 小时
    • D 天
    • W 每星期(interval==0时代表星期一)
    • midnight 每天凌晨

formatter 组件

日志的formatter是个独立的组件,可以跟handler组合;

fh = logging.FileHandler("access.log")
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

fh.setFormatter(formatter) #把formmater绑定到fh上
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/2 0002 21:45
#试问:如何日志同时输出到屏幕和文件?
import logging#导入logging模块;
#1、生成logger对象;
logger = logging.getLogger("wechat")
logger.setLevel(logging.DEBUG)#此处为全局变量;
#2、生成handler对象;
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)#设置日志级别;
fh = logging.FileHandler("web.log")
fh.setLevel(logging.WARNING)#设置日志级别;
#2.1 把handler对象绑定到logger;
logger.addHandler(ch)
logger.addHandler(fh)
#3、生成formatter对象
#3.1 把formatter对象绑定handler对象
file_formatter =logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
console_formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(lineno)d-%(message)s')

ch.setFormatter(console_formatter)
fh.setFormatter(file_formatter)
#进行打印日志;
logger.warning("test_log_1")
logger.info("test_log_2")
logger.debug("test_log_3")
#logger.error("test_log")
#logger.warning("test_log")


#console:INFO
#globale:DEBUG ,默认级别是warning
#file:WARNING
"""
小结:
1、全局设置为DEBUG后,console handler 设置为INFO,如果输出的日志级别是debug,那就不会在屏幕上打印输出;
"""

27-常用模块学习-logging日志过滤和日志文件自动截取

1、文件自动截断举例;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/2 0002 22:34
#一个同时输出到屏幕、文件、带filter的完成例子;
import logging
class IgnoreBackupLogFilter(logging.Filter):
    """忽略带db backup 的日志"""
    def filter(self, record):#固定写法
        return "db backup" not in record.getMessage()
#console handler
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
#file handler
fh = logging.FileHandler('MySQL.log')
#formatter
formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
#bind formatter to ch
ch.setFormatter(formatter)
fh.setFormatter(formatter)

logger = logging.getLogger("MySQL")
logger.setLevel(logging.DEBUG)#logger优先级高于其他输出途径的

#add handler to logger instance
logger.addHandler(ch)
logger.addHandler(fh)

#add filter
logger.addFilter(IgnoreBackupLogFilter)

logger.debug("test......")
logger.info("test info ....")
logger.warning("start to run bd backup job")
logger.error("test error......")

#文件自动截断的例子
import logging
from logging import handlers

logger = logging.getLogger()
log_file = "timelog.log"
fh2 = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
fh3 = handlers.TimedRotatingFileHandler(filename=log_file,when="5",interval=5,backupCount=3)
formatter = logging.Formatter("%(asctime)s-%(module)s-%(lineno)-%(message)s")
fh3.setFormatter(formatter)
logger.addHandler(fh3)

logger.warning("test1")
logger.warning("test2")
logger.warning("test3")
logger.warning("test4")

28-常用模块学习-re正则表达式讲解

1、引入“正则表达式”概念;

正则表达式就是字符串的匹配规则,在多数编程语言里都有相应的支持,python里对应的模块是re;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 9:43
#什么是正则表达式;
#Req:查找文件中的手机号,引出“正则表达式”;
import re#导入正则表达式模块;
f = open("模特的联系方式",mode="r",encoding="utf-8")
# contacts = []
# for line in f:
#     name,region,height,weight,phone = line.split()
#     if phone.isdigit():
#         #print(phone)
#         contacts.append(phone)
# print(phone)
data = f.read()
#print(re.search("[0-9]{11}",data))#<_sre.SRE_Match object; span=(58, 69), match='13651054608'>
print(re.findall("[0-9]{11}",data))#['13651054608', '13813234424', '13744234523', '15823423525', '18623423421', '18623423765', '18835324553', '18933434452', '18042432324', '13324523342']
print(re.findall("1[0-9]{10}",data))#['13651054608', '13813234424', '13744234523', '15823423525', '18623423421', '18623423765', '18835324553', '18933434452', '18042432324']

29-常用模块学习-re匹配语法

1、re的匹配语法;

  • re.match#从“头部”开始匹配;
  • re.search#匹配包含;
  • re.findall#把所有匹配到的字符放到以列表中的元素返回;
  • re.split#以匹配到的字符当做列表分隔符;
  • re.sub#匹配字符并替换;
  • re.fullmatch#全部匹配;
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 9:59
#1、re的匹配语法
import re
s= 'abc1d3e'
print(re.match('[0-9]',s))#None,match方法从头开始匹配;
print(re.search('[0-9]',s))#None,search方法全局匹配;<_sre.SRE_Match object; span=(3, 4), match='1'>
print(re.findall('[0-9]',s))#findall方法全局匹配;生成列表['1', '3']
match_res = re.search('[0]',s)
if match_res:
    print(match_res.group())#返回值为空;

30-常用模块学习-re正则表达式公式讲解1

1、re之公式1;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 10:11
import re
#'.' #默认匹配任意字符;
print(re.search('.','1abd'))#<_sre.SRE_Match object; span=(0, 1), match='1'>
print(re.search('.','^abd'))#<_sre.SRE_Match object; span=(0, 1), match='^'>
print(re.search('..','*abd'))#<_sre.SRE_Match object; span=(0, 1), match='*a'>
print(re.match('..','*abd'))#<_sre.SRE_Match object; span=(0, 1), match='*a'>
#'^',匹配“开头”;
print(re.search('^a*','abd'))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.search('^ab*','abd'))#<_sre.SRE_Match object; span=(0, 1), match='ab'>
#'$',匹配“结尾”;
print(re.search('b$','123b123'))#None
print(re.search('b$','123b'))#<_sre.SRE_Match object; span=(3, 4), match='b'>
print(re.match('b$','b'))#精确匹配,以b开头,以b结尾;<_sre.SRE_Match object; span=(0, 1), match='b'>
print(re.match('b$','b123'))#None;

31-常用模块学习-re正则表达式公式讲解2

1、re之公式2;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 10:24
# '.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行;
# '^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE);
# '$'     匹配字符结尾, 若指定flags MULTILINE ,re.search('foo.$','foo1\nfoo2\n',re.MULTILINE).group() 会匹配到foo1;
# '*'     匹配*号前的字符0次或多次, re.search('a*','aaaabac')  结果'aaaa';
import re
print(re.search('a*','Alex'))#<_sre.SRE_Match object; span=(0, 0), match=''>
print(re.search('a*','alex'))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.search('a*','aaaaaaalex'))#<_sre.SRE_Match object; span=(0, 1), match='aaaaaaa'>
print("0",re.search('ab*','aaaalex'))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print("1",re.search('ab*','abab123lex'))#<_sre.SRE_Match object; span=(0, 2), match='ab'>
print("2",re.search('ab*','abb123lex'))#<_sre.SRE_Match object; span=(0, 3), match='abb'>
print("3",re.search('ab*','a1bb123lex'))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print("4",re.search('ab*','abab123lex'))#<_sre.SRE_Match object; span=(0, 2), match='ab'>
# '+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
print(re.search('a+','abbaalex'))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.search('a+','sdg'))#None;
print(re.search('a+','aaab'))#<_sre.SRE_Match object; span=(0, 3), match='aaa'>
print(re.search('.+','aaab'))#<_sre.SRE_Match object; span=(0, 4), match='aaab'>
print(re.search('ab+','aaabab'))#<_sre.SRE_Match object; span=(2, 4), match='ab'>
print(re.search('ab+','aaab'))#<_sre.SRE_Match object; span=(2, 4), match='ab'>
print(re.search('ab+','abbbbbb'))#<_sre.SRE_Match object; span=(0, 7), match='abbbbbb'>
# '?'     匹配前一个字符1次或0次 ,re.search('b?','alex').group() 匹配b 0次
print(re.search('a?','aaabbb'))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.search('a?','dddd'))#<_sre.SRE_Match object; span=(0, 0), match=''>
# '{m}'   匹配前一个字符m次 ,re.search('b{3}','alexbbbs').group()  匹配到'bbb'
print(re.search('a{2}','addaad'))#<_sre.SRE_Match object; span=(3, 5), match='aa'>
print(re.search('a{2}','addaaaaad'))#<_sre.SRE_Match object; span=(3, 5), match='aa'>
print(re.search('.{2}','addaaaaad'))#<_sre.SRE_Match object; span=(0, 2), match='ad'>
print(re.search('[0-9]{2}','adda1'))#None
print(re.search('[0-9]{2}','adda12'))#<_sre.SRE_Match object; span=(4, 6), match='12'>
# '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
print(re.search('[a-z]{1,2}','a2lex'))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.search('[a-z]{1,10}','2lex'))#<_sre.SRE_Match object; span=(1, 4), match='lex'>
# '|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
print(re.search('alex|Alex','Alex'))#<_sre.SRE_Match object; span=(0, 4), match='Alex'>
print(re.search('alex|Alex','alex'))#<_sre.SRE_Match object; span=(0, 4), match='alex'>
print(re.search('[a|A]lex','alex'))#<_sre.SRE_Match object; span=(0, 4), match='alex'>
print(re.search('[a|A]lex','Alex'))#<_sre.SRE_Match object; span=(0, 4), match='Alex'>
print(re.search('^[a|A]lex','fdsAlex'))#None
print(re.search('^[a|A]lex','fdsalex'))#None

32-常用模块学习-re正则表达式公式讲解3

1、re公式3;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 11:09
import re
# '(...)' 分组匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 结果为'abcabca45'
print(re.search('[a-z]+[0-9]+','alex123'))#print(re.search('[a-z]+[0-9]+','alex123'))#
print(re.search('[a-z]+[0-9]+','alex123').group())#alex123;

print(re.search('([a-z]+)([0-9]+)','alex123'))#<_sre.SRE_Match object; span=(0, 7), match='alex123'>
print(re.search('([a-z]+)([0-9]+)','alex123').group())#alex123
print(re.search('([a-z]+)([0-9]+)','alex123').groups())#('alex', '123')
#
# '\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的,相当于re.match('abc',"alexabc") 或^
print(re.search('\Aalex','alex'))#<_sre.SRE_Match object; span=(0, 4), match='alex'>
print(re.search('\AAalex','Aalex'))#<_sre.SRE_Match object; span=(0, 5), match='Aalex'>
# '\Z'    匹配字符结尾,同$
print(re.search('CXZ\Z','19930911CXZ'))#<_sre.SRE_Match object; span=(8, 11), match='CXZ'>
print(re.search('CXz\Z','19930911CXz'))#<_sre.SRE_Match object; span=(8, 11), match='CXz'>
# '\d'    匹配数字0-9
print(re.search('\d','13811221893'))#<_sre.SRE_Match object; span=(0, 11), match='1'>
print(re.search('\d+','13811221893'))#<_sre.SRE_Match object; span=(0, 11), match='13811221893'>
print(re.search('d\d+','\d1'))#<_sre.SRE_Match object; span=(1, 3), match='d1'>

# '\D'    匹配非数字
print(re.search('\D','YzD!@#$)^20170817'))#<_sre.SRE_Match object; span=(0, 1), match='Y'>
print(re.search('\D+','YzD!@#$)^20170817'))#<_sre.SRE_Match object; span=(0, 9), match='YzD!@#$)^'>
# '\w'    匹配[A-Za-z0-9]
print(re.search('\w','YzD519!@#)^20170817.'))#<_sre.SRE_Match object; span=(0, 1), match='Y'>
print(re.search('\w+','YzD519!@#)^20170817.'))#<_sre.SRE_Match object; span=(0, 6), match='YzD519'>
# '\W'    匹配非[A-Za-z0-9]
print(re.search('\W','YzD519!@#)^20170817.'))#<_sre.SRE_Match object; span=(6, 7), match='!'>
print(re.search('\W+','YzD519!@#)^20170817.'))#<_sre.SRE_Match object; span=(6, 11), match='!@#)^'>
# '\s'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
s = 'alex\njack'
print(re.search('\s',s))#<_sre.SRE_Match object; span=(4, 5), match='\n'>
print(re.findall('\s','alex\njack\nmike\train\tmary'))#['\n', '\n', '\t', '\t']
# '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
s = '130704200005250613'#某ID;
print(s)
print(re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<born_year>\d{4})',s).groups())#('130', '704', '2000')
print(re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<born_year>\d{4})',s).groupdict())#{'province': '130', 'city': '704', 'born_year': '2000'}

33-常用模块学习-re正则表达式公式讲解4

1、re公式4;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 16:39
import re
s='alex22jack23rain31jinxing50'
#print(s.split([0-9]))#TypeError: must be str or None, not list
print(re.split('\d',s))#['alex', '', 'jack', '', 'rain', '', 'jinxing', '', '']
print(re.split('\d+',s))#['alex', 'jack', 'rain', 'jinxing', '']
print(re.findall('\d+',s))#['22', '23', '31', '50']

s1='alex22jack23rain31jinxing50|mack-oldboy'
print(re.split('\d+||',s1))#C:\Program Files\Python36\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
#转义概念'\'的引入;
print(re.split('\|',s1))#['alex22jack23rain31jinxing50', 'mack-oldboy']
s2='alex22jack23rain31jinxing50#mack-oldboy'
print(re.split('\d+|#|-',s2))#['alex', 'jack', 'rain', 'jinxing', '', 'mack', 'oldboy']
#模糊匹配下的替换;
s3 = 'alex22jack23rain31\\jinxing50|mack-oldboy'
print(re.sub('\d+','*',s3))#alex*jack*rain*\jinxing*|mack-oldboy
print(re.sub('\d+','*',s3,count=3))#alex*jack*rain*\jinxing50|mack-oldboy#count指定次数;
#re.split(pattern=,string=,maxsplit=,flags=)用法;
s5= '9-2*5/3+7/3*99/4*2998+10+568/14'
print(re.split('[\+\-\*/]',s5))#['9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']
print(re.split('[\+\-\*/]',s5,3))#['9', '2', '5', '3+7/3*99/4*2998+10+568/14']
print(re.split('[\+\-\*/]',s5,maxsplit=3))#['9', '2', '5', '3+7/3*99/4*2998+10+568/14']

34-常用模块学习-re正则表达式公式讲解5

1、re公式5;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 17:06
import re
print(re.fullmatch('alex','alex123'))#None
print(re.fullmatch('alex1234','alex123'))#None
print(re.fullmatch('alex123','alex123'))#<_sre.SRE_Match object; span=(0, 7), match='alex123'>
#做一个匹配邮箱的练习;
print(re.fullmatch('\\w+@\\w+\\.(com|cn|edu)','alex@oldboyedu.cn'))#<_sre.SRE_Match object; span=(0, 17), match='alex@oldboyedu.cn'>
print(re.fullmatch('\\w+@\\w+\\.(com|cn|edu)','alex@oldboyedu.com'))#<_sre.SRE_Match object; span=(0, 17), match='alex@oldboyedu.com'>
print(re.fullmatch('\\w+@\\w+\\.(com|cn|edu)','alex@oldboyedu.edu'))#<_sre.SRE_Match object; span=(0, 18), match='alex@oldboyedu.edu'>
#河北沃克医疗科技有限公司的邮箱匹配规则;
print(re.fullmatch('\\w+@\\w+\\.(com|cn|mobi|org)','cxz@wokeyl.com'))#<_sre.SRE_Match object; span=(0, 14), match='cxz@wokeyl.com'>

#re.compile(pattern,flags=0)
#语法
pattern = re.compile('\\w+@\\w+\\.(com|cn|edu)')#compile的作用是先写入到内存中,当大量调用的时候,会节省时间;
print(pattern)#re.compile('\\w+@\\w+\\.(com|cn|edu)')
print(pattern.fullmatch('alex@oldboyedu.edu'))#<_sre.SRE_Match object; span=(0, 18), match='alex@oldboyedu.edu'>
"""
小结:
1、Python解释器将公式转换成逻辑的判断语句,是需要时间的;
2、complie的作用是一次翻译后,直接调用即可,提高效率;
3、fullmatch是每次需要单独翻译,会浪费时间;
"""

35-常用模块学习-re正则表达式公式讲解6

1、re公式6;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 17:26
import re
""
"""
Flags标志符
re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同);
M(MULTILINE): 多行模式,改变'^'和'$'的行为;
S(DOTALL): 改变'.'的行为,make the '.' special character match any character at all, including a newline; without this flag, '.' will match anything except a newline.
X(re.VERBOSE) 可以给你的表达式写注释,使其更可读,下面这2个意思一样;
"""
print(re.search('a','Alex'))#None
print(re.search('a','alex'))#<_sre.SRE_Match object; span=(0, 1), match='a'>
print(re.search('a','Alex',re.I))#<_sre.SRE_Match object; span=(0, 1), match='A'>
print(re.search('foo.$','foo1\nfoo2\n',re.M))#<_sre.SRE_Match object; span=(0, 4), match='foo1'>

36-常用模块学习-re正则表达式公式讲解7

1、re公式7;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/3 0003 17:43
#Flags标志符;
import re
print(re.search('.','\n'))#None
print(re.search('.','\n',re.S))#<_sre.SRE_Match object; span=(0, 1), match='\n'>
#re.X,可以给我们的表达式写注释,使其更可读;
print(re.search('.  #test','alex'))#None;
print(re.search('.  #test','alex',re.X))#<_sre.SRE_Match object; span=(0, 1), match='a'>

37-常用模块学习-软件开发目录规范

1、软件开发目录规范初识;

1)为什么要设计好目录结构?

"设计项目目录结构",就和"代码编码风格"一样,属于个人风格问题。对于这种风格上的规范,一直都存在两种态度:

  1. 一类同学认为,这种个人风格问题"无关紧要"。理由是能让程序work就好,风格问题根本不是问题。
  2. 另一类同学认为,规范化能更好的控制程序结构,让程序具有更高的可读性。

我是比较偏向于后者的,因为我是前一类同学思想行为下的直接受害者。我曾经维护过一个非常不好读的项目,其实现的逻辑并不复杂,但是却耗费了我非常长的时间去理解它想表达的意思。从此我个人对于提高项目可读性、可维护性的要求就很高了。"项目目录结构"其实也是属于"可读性和可维护性"的范畴,我们设计一个层次清晰的目录结构,就是为了达到以下两点:

  1. 可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。
  2. 可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。

所以,我认为,保持一个层次清晰的目录结构是有必要的。更何况组织一个良好的工程目录,其实是一件很简单的事儿。

38-常用模块学习-软件开发目录规范2

2)目录组织方式

关于如何组织一个较好的Python工程目录结构,已经有一些得到了共识的目录结构。在Stackoverflow的这个问题上,能看到大家对Python目录结构的讨论。

这里面说的已经很好了,我也不打算重新造轮子列举各种不同的方式,这里面我说一下我的理解和体会。

假设我们的项目名为Foo, 我比较建议的最方便快捷目录结构这样就足够了:

Foo/
|-- bin/
|   |-- foo
|
|-- foo/
|   |-- tests/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |
|   |-- __init__.py
|   |-- main.py
|
|-- docs/
|   |-- conf.py
|   |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README

简要解释一下:

  • bin/: 存放项目的一些可执行文件,当然我们可以起名script/之类的也行。
  • foo/: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py。
  • docs/: 存放一些文档。
  • setup.py: 安装、部署、打包的脚本。
  • requirements.txt: 存放软件依赖的外部Python包列表。
  • README: 项目说明文件。

除此之外,有一些方案给出了更加多的内容。比如LICENSE.txt,ChangeLog.txt文件等,我没有列在这里,因为这些东西主要是项目开源的时候需要用到。如果你想写一个开源软件,目录该如何组织,可以参考这篇文章

下面,再简单讲一下我对这些目录的理解和个人要求吧。

3)关于README的内容

这个我觉得是每个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。

它需要说明以下几个事项:

  1. 软件定位,软件的基本功能;
  2. 运行代码的方法: 安装环境、启动命令等;
  3. 简要的使用说明;
  4. 代码目录结构说明,更详细点可以说明软件的基本原理;
  5. 常见问题说明;

4)关于requirements.txt和setup.py

setup.py

一般来说,用setup.py来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools来管理这些事情。这种方式普遍应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目一定要有一个安装部署工具,能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。

这个我是踩过坑的。

我刚开始接触Python写项目的时候,安装环境、部署代码、运行程序这个过程全是手动完成,遇到过以下问题:

  1. 安装环境时经常忘了最近又添加了一个新的Python包,结果一到线上运行,程序就出错了。
  2. Python包的版本依赖问题,有时候我们程序中使用的是一个版本的Python包,但是官方的已经是最新的包了,通过手动安装就可能装错了。
  3. 如果依赖的包很多的话,一个一个安装这些依赖是很费时的事情。
  4. 新同学开始写项目的时候,将程序跑起来非常麻烦,因为可能经常忘了要怎么安装各种依赖。

setup.py可以将这些事情自动化起来,提高效率、减少出错的概率。"复杂的东西自动化,能自动化的东西一定要自动化。"是一个非常好的习惯。

setuptools的文档比较庞大,刚接触的话,可能不太好找到切入点。学习技术的方式就是看他人是怎么用的,可以参考一下Python的一个Web框架,flask是如何写的: setup.py

当然,简单点自己写个安装脚本(deploy.sh)替代setup.py也未尝不可。

requirements.txt

这个文件存在的目的是:

  1. 方便开发者维护软件的包依赖。将开发过程中新增的包添加进这个列表中,避免在 setup.py 安装依赖时漏掉软件包。
  2. 方便读者明确项目使用了哪些Python包。

这个文件的格式是每一行包含一个包依赖的说明,通常是flask>=0.10这种格式,要求是这个格式能被pip识别,这样就可以简单的通过 pip install -r requirements.txt来把所有Python包依赖都装好了。具体格式说明: 点这里

5)关于配置文件的使用方法

注意,在上面的目录结构中,没有将conf.py放在源码目录下,而是放在docs/目录下。

很多项目对配置文件的使用做法是:

  1. 配置文件写在一个或多个python文件中,比如此处的conf.py。
  2. 项目中哪个模块用到这个配置文件就直接通过import conf这种形式来在代码中使用配置。

这种做法我不太赞同:

  1. 这让单元测试变得困难(因为模块内部依赖了外部配置);
  2. 另一方面配置文件作为用户控制程序的接口,应当可以由用户自由指定该文件的路径;
  3. 程序组件可复用性太差,因为这种贯穿所有模块的代码硬编码方式,使得大部分模块都依赖conf.py这个文件;

所以,我认为配置的使用,更好的方式是,

  1. 模块的配置都是可以灵活配置的,不受外部配置文件的影响。
  2. 程序的配置也是可以灵活控制的。

能够佐证这个思想的是,用过nginx和mysql的同学都知道,nginx、mysql这些程序都可以自由的指定用户配置。

所以,不应当在代码中直接import conf来使用配置文件。上面目录结构中的conf.py,是给出的一个配置样例,不是在写死在程序中直接引用的配置文件。可以通过给main.py启动参数指定配置路径的方式来让程序读取配置内容。当然,这里的conf.py你可以换个类似的名字,比如settings.py。或者你也可以使用其他格式的内容来编写配置文件,比如settings.yaml之类的。

可依据不同的环境,指定不同的配置,比如开发环境dev,测试环境test,预上线环境pre,生产环境prd;

39-常用模块学习-作业需求

1、函数、模块调用、Python基础的综合运用;

2、模拟实现一个ATM+购物车程序;

  1. 额度 15000或自定义;
  2. 实现购物商城,买东西加入 购物车,调用信用卡接口结账;
  3. 可以提现,手续费5%;
  4. 支持多账户登录;
  5. 支持账户间转账;
  6. 记录每月日常消费流水;
  7. 提供还款接口;
  8. ATM记录操作日志;
  9. 提供管理接口,包括添加账户、用户额度,冻结账户等;
  10. 用户认证用装饰器;

模拟实现一个ATM + 购物商城程序

示例代码 https://github.com/triaquae/py3_training/tree/master/atm

简易流程图:https://www.processon.com/view/link/589eb841e4b0999184934329

posted @ 2018-05-28 08:09  天晴天朗  阅读(2857)  评论(0编辑  收藏  举报