- 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-經常使用模塊學習-小雞湯
一、模塊概念的引入——工具箱;
二、節目推薦-曉說;
- 《曉說》是2012年3月高曉鬆開始主持的網絡脫口秀節目;
- 在每週30-40分鐘一集的節目中,《曉說》每期由主持人高曉鬆談論一個熱門話題,打造視頻化的「高曉鬆專欄文章」;
- 2017年4月7日,停播了將近3年的《曉說》已在優酷從新開播;
02-經常使用模塊學習-模塊種類和導入方法
一、什麼是模塊?!
""" 一、什麼是模塊? 在計算機的開發過程當中,隨着程序代碼越寫越多,在一個文件裏代碼就會愈來愈長,愈來愈不容易維護。 爲了編寫可維護的代碼,咱們把不少函數分組,分別放到不一樣的文件裏,這樣,每一個文件包含的代碼就相對減小,不少編程語言都採用這樣組織代碼的方式。 在Python中,一個Py文件就能夠稱之爲一個模塊(Module) 二、使用模塊的好處: 大大提升了代碼的可維護性; 避免函數名和變量名的衝突; 三、模塊的分類: 內置標準模塊(又稱爲標準庫)執行help('modules')查看Python中全部自帶模塊列表; 第三方開源模塊,可經過pip install 模塊名進行聯網安裝;(即從公共倉庫下載的過程) 四、模塊的調用方式: 格式: 一、import module 二、from module import xx #從哪來,到哪去! 三、from module.xx.xx import xx as rename #起個別名; 四、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".
二、使用模塊的好處?
- 提升可維護性;
- 可重用;
- 避免函數名的衝突;
三、模塊的分類;
- 內置標準模塊(又稱標準庫),可經過執行help(‘modules’)查看全部Python自帶的模塊列表;
- 第三方開源模塊,能夠經過pip install 模塊名,聯網安裝;
- 自定義模塊;
四、模塊的調用;
- 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 "" """ 格式: 一、import module 二、from module import xx #從哪來,到哪去! 三、from module.xx.xx import xx as rename #起個別名; 四、from module.xx.xx import * #*表明全部,不建議使用,變量名容易衝突; """ import os import sys from os import rmdir from os import rmdir,rename,replace#逗號分隔,導入多個;不建議使用,不符合PEP8規範;
模塊一旦被調用,即至關於執行了另一個py文件裏的代碼;
03-經常使用模塊學習-模塊的導入路徑
一、模塊的導入路徑;
#!/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-經常使用模塊學習-開源模塊學習的安裝方式
一、開源模塊的介紹;
https://pypi.org/ 是python的開源模塊庫,截止2017年9.30日 ,已經收錄了118170個來自全世界python開發者貢獻的模塊,幾乎涵蓋了你想用python作的任何事情。 事實上每一個python開發者,只要註冊一個帳號就能夠往這個平臺上傳你本身的模塊,這樣全世界的開發者均可以容易的下載並使用你的模塊。css
二、開源模塊的安裝方法總結;
1)使用源碼包進行安裝;html
編譯源碼 python setup.py build
安裝源碼 python setup.py install(推薦使用哦!)
2)使用pip工具進行安裝;python
- pip3 install PyTyrion
- pip3 uninstall PyTyrion
- import Tyrion#使用它;
Pytion模塊的介紹:https://pypi.org/project/PyTyrion/mysql
05-經常使用模塊學習-使用國內源下載模塊
一、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.linux
(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.nginx
(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>git
06-經常使用模塊學習-包及跨模塊導入
一、包的概念引入;
. └── my_proj ├── crm #代碼目錄;此處就是包; │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── proj #配置文件目錄;此處也是包; ├── settings.py ├── urls.py └── wsgi.py
當咱們的模塊文件愈來愈多,爲了容易管理,就須要對模塊文件進行劃分,好比把負責跟數據庫交互的都放一個文件夾,把與頁面交互相關的放一個文件夾,其中,一個文件夾管理多個模塊文件,這個文件夾就被稱爲包;github
二、不一樣模塊;
07-經常使用模塊學習-跨模塊導入2
一、絕對路徑與相對路徑;
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-經常使用模塊學習-相對導入
一、相對導入(使用場景很少);
絕對導入&相對導入 在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模塊詳解
一、time模塊初識;
在日常的代碼中,咱們經常須要與時間打交道。在Python中,與時間處理有關的模塊就包括:time,datetime,calendar(不多用,不講),下面分別來介紹。web
在開始以前,首先要說明幾點:
1、在Python中,一般有這幾種方式來表示時間:
- 時間戳;
- 格式化的時間字符串;
- 元組(struct_time)共九個元素。因爲Python的time模塊實現主要調用C庫,因此各個平臺可能有所不一樣;
2、幾個定義
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)
字符串轉時間格式對應表 |
---|
Meaning | Notes | |
---|---|---|
%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模塊詳解
一、datetime模塊;
datetime模塊
相比於time模塊,datetime模塊的接口則更直觀、更容易調用
datetime模塊定義了下面這幾個類:
- datetime.date:表示日期的類。經常使用的屬性有year, month, day;
- datetime.time:表示時間的類。經常使用的屬性有hour, minute, second, microsecond;
- datetime.datetime:表示日期時間。
- datetime.timedelta:表示時間間隔,即兩個時間點之間的長度。
- datetime.tzinfo:與時區有關的相關信息。(這裏不詳細充分討論該類,感興趣的童鞋能夠參考python手冊)
咱們須要記住的方法僅如下幾個:
- 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模塊詳解
一、隨機數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模塊詳解
一、經過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模塊詳解
一、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模塊詳解
一、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")
武沛奇講師的博文:http://www.javashuo.com/article/p-xcsntggt-bn.html
15-經常使用模塊學習-序列化模塊詳解
一、序列化初識;
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}] """ 小結: 一、把內存數據轉成字符,叫作‘序列化’; 二、把字符轉成內存數據類型,叫作‘反序列化’; 三、相關模塊pickle和json; 用途:內存數據很容易存儲下來也很容易再轉化回去; """
16-經常使用模塊學習-序列化json模塊詳解
一、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 一、把內存中的數據,經過網絡,共享給遠程其餘人(學習到網絡編程後,就知道數據應該是bytes格式傳輸); 二、實現不一樣編程語言之間數據傳輸後能相互讀取,定義一個共同的規則,就是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模塊詳解
一、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屢次; """ 小結: 一、json支持的數據類型:str、int、tuple、list、dict,跨平臺; 二、pickle支持Python語言裏的全部數據類型,但只能在Python中使用,不跨平臺; 如何使用以上兩種序列化格式呢? 不一樣語言之間通常用json; 相同的Python語言之間用pickle; """
18-經常使用模塊學習-序列化shelve模塊詳解
一、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處理模塊詳解
一、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')
20-經常使用模塊學習-自動建立xml文檔
一、經過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"?>
#!/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
一、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'))
22-經常使用模塊學習-hashlib加密模塊詳解
一、安全知識初識;
加密算法介紹
HASH
Hash,通常翻譯作「散列」,也有直接音譯爲」哈希」的,就是把任意長度的輸入(又叫作預映射,pre-image),經過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間,不一樣的輸入可能會散列成相同的輸出,而不可能從散列值來惟一的肯定輸入值。
簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。
HASH主要用於信息安全領域中加密算法,他把一些不一樣長度的信息轉化成雜亂的128位的編碼裏,叫作HASH值.也能夠說,hash就是找到一種數據內容和數據存放地址之間的映射關係;
MD5
- 什麼是MD5算法
MD5訊息摘要演算法(英語:MD5 Message-Digest Algorithm),一種被普遍使用的密碼雜湊函數,能夠產生出一個128位的散列值(hash value),用於確保信息傳輸完整一致。MD5的前身有MD二、MD3和MD4。
MD5功能
輸入任意長度的信息,通過處理,輸出爲128位的信息(數字指紋);
不一樣的輸入獲得的不一樣的結果(惟一性);
- MD5算法的特色
- 壓縮性:任意長度的數據,算出的MD5值的長度都是固定的;
- 容易計算:從原數據計算出MD5值很容易;
- 抗修改性:對原數據進行任何改動,修改一個字節生成的MD5值區別也會很大;
- 強抗碰撞:已知原數據和MD5,想找到一個具備相同MD5值的數據(即僞造數據)是很是困難的。
- MD5算法是否可逆?
MD5不可逆的緣由是其是一種散列函數,使用的是hash算法,在計算過程當中原文的部分信息是丟失了的。
- MD5用途
-
防止被篡改:
-
好比發送一個電子文檔,發送前,我先獲得MD5的輸出結果a。而後在對方收到電子文檔後,對方也獲得一個MD5的輸出結果b。若是a與b同樣就表明中途未被篡改。
-
好比我提供文件下載,爲了防止不法分子在安裝程序中添加木馬,我能夠在網站上公佈由安裝文件獲得的MD5輸出結果。
-
SVN在檢測文件是否在CheckOut後被修改過,也是用到了MD5。
-
-
防止直接看到明文:
- 如今不少網站在數據庫存儲用戶的密碼的時候都是存儲用戶密碼的MD5值。這樣就算不法分子獲得數據庫的用戶密碼的MD5值,也沒法知道用戶的密碼。(好比在UNIX系統中用戶的密碼就是以MD5(或其它相似的算法)經加密後存儲在文件系統中。當用戶登陸的時候,系統把用戶輸入的密碼計算成MD5值,而後再去和保存在文件系統中的MD5值進行比較,進而肯定輸入的密碼是否正確。經過這樣的步驟,系統在並不知道用戶密碼的明碼的狀況下就能夠肯定用戶登陸系統的合法性。這不但能夠避免用戶的密碼被具備系統管理員權限的用戶知道,並且還在必定程度上增長了密碼被破解的難度。)
-
防止抵賴(數字簽名):
- 這須要一個第三方認證機構。例如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模塊詳解
一、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() #上面各類方法的底層封裝;
二、阿里雲CentOS7.X下安裝Python3;
三、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
一、subprocess.call方法;
二、subprocess.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模塊基礎
一、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
看一下這幾個日誌級別分別表明什麼意思
Level | When 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)s | Logger的名字 |
---|---|
%(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 | 用戶輸出的消息 |
26-經常使用模塊學習-logging模塊進階
一、日誌同時輸出到屏幕和文件
若是想同時把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:
- logging.StreamHandler 使用這個Handler能夠向相似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息。
- logging.FileHandler 和StreamHandler 相似,用於向一個文件輸出日誌信息。不過FileHandler會幫你打開這個文件
-
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並不會被改名,而是被刪除。
-
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模塊; #一、生成logger對象; logger = logging.getLogger("wechat") logger.setLevel(logging.DEBUG)#此處爲全局變量; #二、生成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) #三、生成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 """ 小結: 一、全局設置爲DEBUG後,console handler 設置爲INFO,若是輸出的日誌級別是debug,那就不會在屏幕上打印輸出; """
27-經常使用模塊學習-logging日誌過濾和日誌文件自動截取
一、文件自動截斷舉例;
#!/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正則表達式講解
一、引入「正則表達式」概念;
正則表達式就是字符串的匹配規則,在多數編程語言裏都有相應的支持,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匹配語法
一、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 #一、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
一、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
一、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
一、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
一、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
一、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'> """ 小結: 一、Python解釋器將公式轉換成邏輯的判斷語句,是須要時間的; 二、complie的做用是一次翻譯後,直接調用便可,提升效率; 三、fullmatch是每次須要單獨翻譯,會浪費時間; """
35-經常使用模塊學習-re正則表達式公式講解6
一、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
一、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)爲何要設計好目錄結構?
"設計項目目錄結構",就和"代碼編碼風格"同樣,屬於我的風格問題。對於這種風格上的規範,一直都存在兩種態度:
- 一類同窗認爲,這種我的風格問題"可有可無"。理由是能讓程序work就好,風格問題根本不是問題。
- 另外一類同窗認爲,規範化能更好的控制程序結構,讓程序具備更高的可讀性。
我是比較偏向於後者的,由於我是前一類同窗思想行爲下的直接受害者。我曾經維護過一個很是很差讀的項目,其實現的邏輯並不複雜,可是卻耗費了我很是長的時間去理解它想表達的意思。今後我我的對於提升項目可讀性、可維護性的要求就很高了。"項目目錄結構"其實也是屬於"可讀性和可維護性"的範疇,咱們設計一個層次清晰的目錄結構,就是爲了達到如下兩點:
- 可讀性高: 不熟悉這個項目的代碼的人,一眼就能看懂目錄結構,知道程序啓動腳本是哪一個,測試目錄在哪兒,配置文件在哪兒等等。從而很是快速的瞭解這個項目。
- 可維護性高: 定義好組織規則後,維護者就能很明確地知道,新增的哪一個文件和代碼應該放在什麼目錄之下。這個好處是,隨着時間的推移,代碼/配置的規模增長,項目結構不會混亂,仍然可以組織良好。
因此,我認爲,保持一個層次清晰的目錄結構是有必要的。更況且組織一個良好的工程目錄,實際上是一件很簡單的事兒。
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的內容
這個我以爲是每一個項目都應該有的一個文件,目的是能簡要描述該項目的信息,讓讀者快速瞭解這個項目。
它須要說明如下幾個事項:
- 軟件定位,軟件的基本功能;
- 運行代碼的方法: 安裝環境、啓動命令等;
- 簡要的使用說明;
- 代碼目錄結構說明,更詳細點能夠說明軟件的基本原理;
- 常見問題說明;
4)關於requirements.txt和setup.py
setup.py
通常來講,用setup.py
來管理代碼的打包、安裝、部署問題。業界標準的寫法是用Python流行的打包工具setuptools來管理這些事情。這種方式廣泛應用於開源項目中。不過這裏的核心思想不是用標準化的工具來解決這些問題,而是說,一個項目必定要有一個安裝部署工具,能快速便捷的在一臺新機器上將環境裝好、代碼部署好和將程序運行起來。
這個我是踩過坑的。
我剛開始接觸Python寫項目的時候,安裝環境、部署代碼、運行程序這個過程全是手動完成,遇到過如下問題:
- 安裝環境時常常忘了最近又添加了一個新的Python包,結果一到線上運行,程序就出錯了。
- Python包的版本依賴問題,有時候咱們程序中使用的是一個版本的Python包,可是官方的已是最新的包了,經過手動安裝就可能裝錯了。
- 若是依賴的包不少的話,一個一個安裝這些依賴是很費時的事情。
- 新同窗開始寫項目的時候,將程序跑起來很是麻煩,由於可能常常忘了要怎麼安裝各類依賴。
setup.py
能夠將這些事情自動化起來,提升效率、減小出錯的機率。"複雜的東西自動化,能自動化的東西必定要自動化。"是一個很是好的習慣。
setuptools的文檔比較龐大,剛接觸的話,可能不太好找到切入點。學習技術的方式就是看他人是怎麼用的,能夠參考一下Python的一個Web框架,flask是如何寫的: setup.py
固然,簡單點本身寫個安裝腳本(deploy.sh
)替代setup.py
也何嘗不可。
requirements.txt
這個文件存在的目的是:
- 方便開發者維護軟件的包依賴。將開發過程當中新增的包添加進這個列表中,避免在
setup.py
安裝依賴時漏掉軟件包。 - 方便讀者明確項目使用了哪些Python包。
這個文件的格式是每一行包含一個包依賴的說明,一般是flask>=0.10
這種格式,要求是這個格式能被pip
識別,這樣就能夠簡單的經過 pip install -r requirements.txt
來把全部Python包依賴都裝好了。具體格式說明: 點這裏。
5)關於配置文件的使用方法
注意,在上面的目錄結構中,沒有將conf.py
放在源碼目錄下,而是放在docs/
目錄下。
不少項目對配置文件的使用作法是:
- 配置文件寫在一個或多個python文件中,好比此處的conf.py。
- 項目中哪一個模塊用到這個配置文件就直接經過
import conf
這種形式來在代碼中使用配置。
這種作法我不太贊同:
- 這讓單元測試變得困難(由於模塊內部依賴了外部配置);
- 另外一方面配置文件做爲用戶控制程序的接口,應當能夠由用戶自由指定該文件的路徑;
- 程序組件可複用性太差,由於這種貫穿全部模塊的代碼硬編碼方式,使得大部分模塊都依賴
conf.py
這個文件;
因此,我認爲配置的使用,更好的方式是,
- 模塊的配置都是能夠靈活配置的,不受外部配置文件的影響。
- 程序的配置也是能夠靈活控制的。
可以佐證這個思想的是,用過nginx和mysql的同窗都知道,nginx、mysql這些程序均可以自由的指定用戶配置。
因此,不該當在代碼中直接import conf
來使用配置文件。上面目錄結構中的conf.py
,是給出的一個配置樣例,不是在寫死在程序中直接引用的配置文件。能夠經過給main.py
啓動參數指定配置路徑的方式來讓程序讀取配置內容。固然,這裏的conf.py
你能夠換個相似的名字,好比settings.py
。或者你也可使用其餘格式的內容來編寫配置文件,好比settings.yaml
之類的。
可依據不一樣的環境,指定不一樣的配置,好比開發環境dev,測試環境test,預上線環境pre,生產環境prd;
39-經常使用模塊學習-做業需求
一、函數、模塊調用、Python基礎的綜合運用;
二、模擬實現一個ATM+購物車程序;
- 額度 15000或自定義;
- 實現購物商城,買東西加入 購物車,調用信用卡接口結帳;
- 能夠提現,手續費5%;
- 支持多帳戶登陸;
- 支持帳戶間轉帳;
- 記錄每個月平常消費流水;
- 提供還款接口;
- ATM記錄操做日誌;
- 提供管理接口,包括添加帳戶、用戶額度,凍結帳戶等;
- 用戶認證用裝飾器;
模擬實現一個ATM + 購物商城程序
示例代碼 https://github.com/triaquae/py3_training/tree/master/atm
簡易流程圖:https://www.processon.com/view/link/589eb841e4b0999184934329