""" 一、什么是模块? 在计算机的开发过程当中,随着程序代码越写越多,在一个文件里代码就会愈来愈长,愈来愈不容易维护。 为了编写可维护的代码,咱们把不少函数分组,分别放到不一样的文件里,这样,每一个文件包含的代码就相对减小,不少编程语言都采用这样组织代码的方式。 在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".
#!/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规范;
#!/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 """ 小结:模块查找路径有顺序; """
https://pypi.org/ 是python的开源模块库,截止2017年9.30日 ,已经收录了118170个来自全世界python开发者贡献的模块,几乎涵盖了你想用python作的任何事情。 事实上每一个python开发者,只要注册一个帐号就能够往这个平台上传你本身的模块,这样全世界的开发者均可以容易的下载并使用你的模块。html
1)使用源码包进行安装;node
编译源码 python setup.py build
安装源码 python setup.py install(推荐使用哦!)
2)使用pip工具进行安装;mysql
Pytion模块的介绍:https://pypi.org/project/PyTyrion/linux
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.nginx
(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.git
(venv) C:\Users\Administrator\PycharmProjects\LFXC2018>github
. └── my_proj ├── crm #代码目录;此处就是包; │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── proj #配置文件目录;此处也是包; ├── settings.py ├── urls.py └── wsgi.py
当咱们的模块文件愈来愈多,为了容易管理,就须要对模块文件进行划分,好比把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹,其中,一个文件夹管理多个模块文件,这个文件夹就被称为包;web
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!')
绝对导入&相对导入 在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并不建议在项目里常用。
在日常的代码中,咱们经常须要与时间打交道。在Python中,与时间处理有关的模块就包括:time,datetime,calendar(不多用,不讲),下面分别来介绍。正则表达式
在开始以前,首先要说明几点:
1、在Python中,一般有这几种方式来表示时间:
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.strftime(format[, t]):把一个表明时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。若是t未指定,将传入time.localtime()。
time.strptime(string[, format]):把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操做。
字符串转时间格式对应表 |
---|
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')互为逆操做
相比于time模块,datetime模块的接口则更直观、更容易调用
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
#!/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中,年会的时候就能够用来随机抽奖;
#!/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
#!/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
#!/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
序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或经过网络传输到远程,由于硬盘或网络传输时只能接受bytes;
你打游戏过程当中,打累了,停下来,关掉游戏、想过2天再玩,2天以后,游戏又从你上次中止的地方继续运行,你上次游戏的进度确定保存在硬盘上了,是以何种形式呢?游戏过程当中产生的不少临时数据是不规律的,可能在你关掉游戏时正好有10个列表,3个嵌套字典的数据集合在内存里,须要存下来?你如何存?把列表变成文件里的多行多列形式?那嵌套字典呢?根本无法存。因此,如果有种办法能够直接把内存数据存到硬盘上,下次程序再启动,再从硬盘上读回来,仍是原来的格式的话,那是极好的。
用于序列化的两个模块
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; 用途:内存数据很容易存储下来也很容易再转化回去; """
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>
#!/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; """
序列化: 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'] #还能够删除;
xml是实现不一样语言或程序之间进行数据交换的协议,跟json差很少,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,你们只能选择用xml呀,至今不少传统公司如金融行业的不少系统的接口还主要是xml。
xml的格式以下,就是经过<>节点来区别数据结构的:
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/5/31 0031 21:35 "" """ import xml.etree.ElementTree as ET#导入后,起个别名 tree = ET.parse("xml_test")#open文件 root = tree.getroot()#至关于f.seek(0) #print(root)#<Element 'data' at 0x000002094A2B7868> #print(dir(root))#['__class__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'attrib', 'clear', 'extend', 'find', 'findall', 'findtext', 'get', 'getchildren', 'getiterator', 'insert', 'items', 'iter', 'iterfind', 'itertext', 'keys', 'makeelement', 'remove', 'set', 'tag', 'tail', 'text'] print(root.tag)#data,标签的名称叫作data; #遍历xml文档; for child in root: print('-------------------',child.tag, child.attrib) for i in child:#嵌套循环; print(i.tag,i.text) #只遍历year 节点; for node in root.iter('year'):#过滤year print(node.tag,node.text)#先找到tag标签,再找到text的值; """ #遍历即循环的意思; import xml.etree.ElementTree as ET#导入xm了模块后,起个别名 tree = ET.parse("xml_test")#打开文件 root = tree.getroot()#至关于f.seek(0) # #修改xml文档 # for node in root.iter('year'): # new_year = int(node.text)+1 # node.text = str(new_year) # node.set("attr_test","yes") # tree.write("xml_test")#向文件中循环写入数据 #删除 for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml')
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year attr_test="yes">2009</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year attr_test="yes">2012</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <country name="Panama"> <rank updated="yes">69</rank> <year attr_test="yes">2012</year> <gdppc>13600</gdppc> <neighbor direction="W" name="Costa Rica" /> <neighbor direction="E" name="Colombia" /> </country> <state> <name>德州</name> <population>1000000</population> </state> </data>
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year attr_test="yes">2009</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year attr_test="yes">2012</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <state> <name>德州</name> <population>1000000</population> </state> </data>
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/2 0002 8:54 #自动建立xml文档; import xml.etree.ElementTree as ET root = ET.Element('namelist')#建立namelist节点; name = ET.SubElement(root,'name',attrib={"enrolled":"yes"}) age = ET.SubElement(name,'age',attrib={"checked":"no"}) sex = ET.SubElement(name,'sex') sex.text = 'male' n =ET.SubElement(name,'name') n.text = 'Alex Li' name2 = ET.SubElement(root,'name',attrib={"enrolled":"no"}) age2 = ET.SubElement(name2,'age') age2.text = '19' et = ET.ElementTree(root)#生成文档对象; et.write('build_out.xml',encoding='utf-8',xml_declaration=True) #xml_declaration=True,是否开启xml声明:<?xml version="1.0"?>
<?xml version='1.0' encoding='utf-8'?> <namelist> <name enrolled="yes"> <age checked="no" /> <sex>male</sex> <name>Alex Li</name> </name> <name enrolled="no"> <age>19</age> </name> </namelist>
#!/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>
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/2 0002 9:18 #解析配置文件模块,Configparser #MySQL数据库的配置文件my.cnf; # import configparser #在Python2中是大写ConfigParser # conf = configparser.ConfigParser() # #print(conf.sections()) # conf.read('conf.ini') # print(conf.sections())#每个配置文件里都有一个DEFAULT,['bitbucket.org', 'topsecret.server.com'] # print(conf.default_section)#DEFAULT,单独列出; # print(conf['bitbucket.org'])#<Section: bitbucket.org> # print(dir(conf['bitbucket.org']))#['_MutableMapping__marker', '__abstractmethods__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__setitem__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', '_abc_registry', '_name', '_options', '_parser', 'clear', 'get', 'getboolean', 'getfloat', 'getint', 'items', 'keys', 'name', 'parser', 'pop', 'popitem', 'setdefault', 'update', 'values'] # print(list(conf['bitbucket.org'].keys()))#['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11'] # print(conf['bitbucket.org']['User'])#User # for k in conf['bitbucket.org']: # print(k)#默认还会打印DEAULT下的内容; # """ # user # serveraliveinterval # compression # compressionlevel # forwardx11 # """ # #作判断的参数; # if 'user' in conf['bitbucket.org']: # print('Yes,in it')#Yes,in it # else: # print('No,not in it') import configparser conf = configparser.ConfigParser() conf.read('conf_test.ini') print(dir(conf)) """ ['BOOLEAN_STATES', 'NONSPACECRE', 'OPTCRE', 'OPTCRE_NV', 'SECTCRE', '_DEFAULT_INTERPOLATION', '_MutableMapping__marker', '_OPT_NV_TMPL', '_OPT_TMPL', '_SECT_TMPL', '__abstractmethods__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__setitem__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', '_abc_registry', '_allow_no_value', '_comment_prefixes', '_convert_to_boolean', '_converters', '_defaults', '_delimiters', '_dict', '_empty_lines_in_values', '_get', '_get_conv', '_handle_error', '_inline_comment_prefixes', '_interpolation', '_join_multiline_values', '_optcre', '_proxies', '_read', '_sections', '_strict', '_unify_values', '_validate_value_types', '_write_section', 'add_section', 'clear', 'converters', 'default_section', 'defaults', 'get', 'getboolean', 'getfloat', 'getint', 'has_option', 'has_section', 'items', 'keys', 'options', 'optionxform', 'pop', 'popitem', 'read', 'read_dict', 'read_file', 'read_string', 'readfp', 'remove_option', 'remove_section', 'sections', 'set', 'setdefault', 'update', 'values', 'write'] """ print(conf.options('group1'))#['k1', 'k2'] print(conf['group1']['k2'])#v2 conf.add_section('group3') conf['group3']['name']="Alex Li" #conf['group3']['age']=22,不能写成整型数字; conf['group3']['age']="22" conf.write(open('conf_test_new.ini','w')) conf.remove_option('group1','k2') #删除,删除以后,要从新写入; conf.remove_option('group1','k2') conf.write(open('conf_test_remove.ini','w'))
[group1]
k1=v1
k2:v2
[group2]
k1=v1
[group1]
k1 = v1
k2 = v2
[group2]
k1 = v1
[group3]
name = Alex Li
age = 22
[group1]
k1 = v1
[group2]
k1 = v1
[group3]
name = Alex Li
age = 22
Hash,通常翻译作“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫作预映射,pre-image),经过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间一般远小于输入的空间,不一样的输入可能会散列成相同的输出,而不可能从散列值来惟一的肯定输入值。
简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
HASH主要用于信息安全领域中加密算法,他把一些不一样长度的信息转化成杂乱的128位的编码里,叫作HASH值.也能够说,hash就是找到一种数据内容和数据存放地址之间的映射关系;
MD5讯息摘要演算法(英语:MD5 Message-Digest Algorithm),一种被普遍使用的密码杂凑函数,能够产生出一个128位的散列值(hash value),用于确保信息传输完整一致。MD5的前身有MD二、MD3和MD4。
MD5功能
输入任意长度的信息,通过处理,输出为128位的信息(数字指纹);
不一样的输入获得的不一样的结果(惟一性);
MD5不可逆的缘由是其是一种散列函数,使用的是hash算法,在计算过程当中原文的部分信息是丢失了的。
防止被篡改:
好比发送一个电子文档,发送前,我先获得MD5的输出结果a。而后在对方收到电子文档后,对方也获得一个MD5的输出结果b。若是a与b同样就表明中途未被篡改。
好比我提供文件下载,为了防止不法分子在安装程序中添加木马,我能够在网站上公布由安装文件获得的MD5输出结果。
SVN在检测文件是否在CheckOut后被修改过,也是用到了MD5。
防止直接看到明文:
防止抵赖(数字签名):
安全哈希算法(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均是从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慢。
用于加密相关的操做,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/
咱们常常须要经过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() #上面各类方法的底层封装;
Last failed login: Fri Jun 1 17:56:36 CST 2018 from 59.63.166.104 on ssh:notty There were 3 failed login attempts since the last successful login. Last login: Fri Jun 1 17:45:27 2018 from 117.119.97.51 Welcome to Alibaba Cloud Elastic Compute Service ! [root@iZqmo9i3j77p7eZ ~]# yum install epel-release -y Loaded plugins: fastestmirror base | 3.6 kB 00:00:00 epel | 3.2 kB 00:00:00 extras | 3.4 kB 00:00:00 nginx | 2.9 kB 00:00:00 updates | 3.4 kB 00:00:00 (1/3): extras/7/x86_64/primary_db | 147 kB 00:00:00 (2/3): epel/x86_64/primary | 3.5 MB 00:00:00 (3/3): epel/x86_64/updateinfo | 933 kB 00:00:00 Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * epel: mirrors.aliyun.com * extras: mirrors.aliyun.com * updates: mirrors.aliyun.com epel 12584/12584 Resolving Dependencies --> Running transaction check ---> Package epel-release.noarch 0:7-11 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================================================================ Installing: epel-release noarch 7-11 epel 15 k Transaction Summary ============================================================================================================================================================================================================================================ Install 1 Package Total download size: 15 k Installed size: 24 k Downloading packages: epel-release-7-11.noarch.rpm | 15 kB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : epel-release-7-11.noarch 1/1 warning: /etc/yum.repos.d/epel.repo created as /etc/yum.repos.d/epel.repo.rpmnew Verifying : epel-release-7-11.noarch 1/1 Installed: epel-release.noarch 0:7-11 Complete! [root@iZqmo9i3j77p7eZ ~]# yum install https://centos7.iuscommunity.org/ius-release.rpm -y Loaded plugins: fastestmirror ius-release.rpm | 8.1 kB 00:00:00 Examining /var/tmp/yum-root-c8qWEb/ius-release.rpm: ius-release-1.0-15.ius.centos7.noarch Marking /var/tmp/yum-root-c8qWEb/ius-release.rpm to be installed Resolving Dependencies --> Running transaction check ---> Package ius-release.noarch 0:1.0-15.ius.centos7 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================================================================ Installing: ius-release noarch 1.0-15.ius.centos7 /ius-release 8.5 k Transaction Summary ============================================================================================================================================================================================================================================ Install 1 Package Total size: 8.5 k Installed size: 8.5 k Downloading packages: Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : ius-release-1.0-15.ius.centos7.noarch 1/1 Verifying : ius-release-1.0-15.ius.centos7.noarch 1/1 Installed: ius-release.noarch 0:1.0-15.ius.centos7 Complete! [root@iZqmo9i3j77p7eZ ~]# yum install python36u -y Loaded plugins: fastestmirror ius | 2.3 kB 00:00:00 ius/x86_64/primary_db | 250 kB 00:00:00 Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * epel: mirrors.aliyun.com * extras: mirrors.aliyun.com * ius: mirrors.tuna.tsinghua.edu.cn * updates: mirrors.aliyun.com Resolving Dependencies --> Running transaction check ---> Package python36u.x86_64 0:3.6.5-1.ius.centos7 will be installed --> Processing Dependency: python36u-libs(x86-64) = 3.6.5-1.ius.centos7 for package: python36u-3.6.5-1.ius.centos7.x86_64 --> Processing Dependency: libpython3.6m.so.1.0()(64bit) for package: python36u-3.6.5-1.ius.centos7.x86_64 --> Running transaction check ---> Package python36u-libs.x86_64 0:3.6.5-1.ius.centos7 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================================================================ Installing: python36u x86_64 3.6.5-1.ius.centos7 ius 57 k Installing for dependencies: python36u-libs x86_64 3.6.5-1.ius.centos7 ius 8.7 M Transaction Summary ============================================================================================================================================================================================================================================ Install 1 Package (+1 Dependent package) Total download size: 8.8 M Installed size: 40 M Downloading packages: warning: /var/cache/yum/x86_64/7/ius/packages/python36u-3.6.5-1.ius.centos7.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 9cd4953f: NOKEY Public key for python36u-3.6.5-1.ius.centos7.x86_64.rpm is not installed (1/2): python36u-3.6.5-1.ius.centos7.x86_64.rpm | 57 kB 00:00:00 (2/2): python36u-libs-3.6.5-1.ius.centos7.x86_64.rpm | 8.7 MB 00:00:00 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 16 MB/s | 8.8 MB 00:00:00 Retrieving key from file:///etc/pki/rpm-gpg/IUS-COMMUNITY-GPG-KEY Importing GPG key 0x9CD4953F: Userid : "IUS Community Project <coredev@iuscommunity.org>" Fingerprint: 8b84 6e3a b3fe 6462 74e8 670f da22 1cdf 9cd4 953f Package : ius-release-1.0-15.ius.centos7.noarch (installed) From : /etc/pki/rpm-gpg/IUS-COMMUNITY-GPG-KEY Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : python36u-libs-3.6.5-1.ius.centos7.x86_64 1/2 Installing : python36u-3.6.5-1.ius.centos7.x86_64 2/2 Verifying : python36u-3.6.5-1.ius.centos7.x86_64 1/2 Verifying : python36u-libs-3.6.5-1.ius.centos7.x86_64 2/2 Installed: python36u.x86_64 0:3.6.5-1.ius.centos7 Dependency Installed: python36u-libs.x86_64 0:3.6.5-1.ius.centos7 Complete! [root@iZqmo9i3j77p7eZ ~]# ln -s /bin/python3.6 /bin/python3 [root@iZqmo9i3j77p7eZ ~]# yum install python36u-pip -y Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: mirrors.aliyun.com * epel: mirrors.aliyun.com * extras: mirrors.aliyun.com * ius: mirrors.tongji.edu.cn * updates: mirrors.aliyun.com Resolving Dependencies --> Running transaction check ---> Package python36u-pip.noarch 0:9.0.1-1.ius.centos7 will be installed --> Processing Dependency: python36u-setuptools for package: python36u-pip-9.0.1-1.ius.centos7.noarch --> Running transaction check ---> Package python36u-setuptools.noarch 0:39.0.1-1.ius.centos7 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================================================================================================================ Package Arch Version Repository Size ============================================================================================================================================================================================================================================ Installing: python36u-pip noarch 9.0.1-1.ius.centos7 ius 1.8 M Installing for dependencies: python36u-setuptools noarch 39.0.1-1.ius.centos7 ius 642 k Transaction Summary ============================================================================================================================================================================================================================================ Install 1 Package (+1 Dependent package) Total download size: 2.4 M Installed size: 13 M Downloading packages: (1/2): python36u-setuptools-39.0.1-1.ius.centos7.noarch.rpm | 642 kB 00:00:00 (2/2): python36u-pip-9.0.1-1.ius.centos7.noarch.rpm | 1.8 MB 00:00:00 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 4.7 MB/s | 2.4 MB 00:00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : python36u-setuptools-39.0.1-1.ius.centos7.noarch 1/2 Installing : python36u-pip-9.0.1-1.ius.centos7.noarch 2/2 Verifying : python36u-setuptools-39.0.1-1.ius.centos7.noarch 1/2 Verifying : python36u-pip-9.0.1-1.ius.centos7.noarch 2/2 Installed: python36u-pip.noarch 0:9.0.1-1.ius.centos7 Dependency Installed: python36u-setuptools.noarch 0:39.0.1-1.ius.centos7 Complete! [root@iZqmo9i3j77p7eZ ~]# ln -s /bin/pip3.6 /bin/pip3 [root@iZqmo9i3j77p7eZ ~]# python3 Python 3.6.5 (default, Apr 10 2018, 17:08:37) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux Type "help", "copyright", "credits" or "license" for more information.
[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声明; >>>
[root@iZqmo9i3j77p7eZ ~]# python3 Python 3.6.5 (default, Apr 10 2018, 17:08:37) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.system('uname -a ') Linux iZqmo9i3j77p7eZ 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 0 >>> import subprocess >>> subprocess.call(['ls','-lsh']) total 0 0 >>> subprocess.check_call(['ls','-lsh']) total 0 0 >>> subprocess.check_call(['ls','-lsh']) total 4.0K 0 srwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)> 4.0K drwx------ 3 root root 4.0K May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R 0 >>> subprocess.getoutput(['ls','-lsh']) 'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\nsystemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R' >>> subprocess.getoutput(['ls /bin/ls']) '/bin/ls' >>> res = subprocess.checkoutput(['ls','-l']) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'subprocess' has no attribute 'checkoutput' >>> res = subprocess.check_output(['ls','-l']) >>> res b'total 4\nsrwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\ndrwx------ 3 root root 4096 May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R\n' >>> help(subprocess.check_output) Help on function check_output in module subprocess: check_output(*popenargs, timeout=None, **kwargs) Run command with arguments and return its output. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"]) b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally. To capture standard error in the result, use stderr=STDOUT. >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], ... stderr=STDOUT) b'ls: non_existent_file: No such file or directory\n' There is an additional optional argument, "input", allowing you to pass a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it too will be used internally. Example: >>> check_output(["sed", "-e", "s/foo/bar/"], ... input=b"when in the course of fooman events\n") b'when in the course of barman events\n' If universal_newlines=True is passed, the "input" argument must be a string and the return value will be a string rather than bytes. >>> >>>
[root@iZqmo9i3j77p7eZ ~]# python3 Python 3.6.5 (default, Apr 10 2018, 17:08:37) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.system('uname -a ') Linux iZqmo9i3j77p7eZ 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 0 >>> import subprocess >>> subprocess.call(['ls','-lsh']) total 0 0 >>> subprocess.check_call(['ls','-lsh']) total 0 0 >>> subprocess.check_call(['ls','-lsh']) total 4.0K 0 srwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)> 4.0K drwx------ 3 root root 4.0K May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R 0 >>> subprocess.getoutput(['ls','-lsh']) 'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\nsystemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R' >>> subprocess.getoutput(['ls /bin/ls']) '/bin/ls' >>> res = subprocess.checkoutput(['ls','-l']) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'subprocess' has no attribute 'checkoutput' >>> res = subprocess.check_output(['ls','-l']) >>> res b'total 4\nsrwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>\ndrwx------ 3 root root 4096 May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R\n' >>> help(subprocess.check_output) Help on function check_output in module subprocess: check_output(*popenargs, timeout=None, **kwargs) Run command with arguments and return its output. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"]) b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally. To capture standard error in the result, use stderr=STDOUT. >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], ... stderr=STDOUT) b'ls: non_existent_file: No such file or directory\n' There is an additional optional argument, "input", allowing you to pass a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it too will be used internally. Example: >>> check_output(["sed", "-e", "s/foo/bar/"], ... input=b"when in the course of fooman events\n") b'when in the course of barman events\n' If universal_newlines=True is passed, the "input" argument must be a string and the return value will be a string rather than bytes. >>> >>> a = subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE) >>> subprocess.Popen() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __init__() missing 1 required positional argument: 'args' >>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE) >>> a.poll() 0 >>> a.poll() 0 >>> a.poll() 0 >>> a.poll() 0 >>> a.poll() 0 >>> a.poll() 0 >>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE) >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() 0 >>> a.poll() 0 >>> a.poll() 0 >>> a.poll() 0 >>> a.poll() 0 >>> def sayhi(): ... print('run...hahahah') File "<stdin>", line 2 print('run...hahahah') ^ IndentationError: expected an indented block >>> def sayhi(): ... print('run...hahahah') ... a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) File "<stdin>", line 3 a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) ^ SyntaxError: invalid syntax >>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'sayhi' is not defined >>> def sayhi(): ... print('run...hahahah') ... a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) File "<stdin>", line 3 a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) ^ SyntaxError: invalid syntax >>> import subprocess >>> def sayhi(): ... print('run...hahahah') ... >>> >>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.stdout <_io.BufferedReader name=3> >>> a.stdout.read() b'run...hahahah\n' >>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,cwd="/tmp",stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.stdout.read() b'run...hahahah\n/tmp\n' >>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.stdout.read() b'run...hahahah\n/root\n' >>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.wait() 0 >>> a = subprocess.Popen('echo $PWD;sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.wait() 0 >>> a = subprocess.Popen('sleep 100',shell=True,stdout=subprocess.PIPE) >>> a.pid 32476 >>> a.terminate() >>> a.pid 32476 >>> a.pid 32476 >>> a.pid 32476 >>> a.terminate() >>> a = subprocess.Popen('sleep 100',shell=True,stdout=subprocess.PIPE) >>> a.pid 32493 >>> a.kill() >>> a.pid 32493 >>> a = subprocess.Popen('for i in $(seq 1 100);do sleep 1;echo $i >>sleep.log;done',shell=True,stdout=subprocess.PIPE) >>> a = subprocess.Popen('for i in $(seq 1 100);do sleep 1;echo $i >>sleep.log;done',shell=True,stdout=subprocess.PIPE) KeyboardInterrupt >>> a.pid 32494 >>> a.kill() KeyboardInterrupt >>> help(os.kill) Help on built-in function kill in module posix: kill(pid, signal, /) Kill a process with a signal. >>>
经常使用参数:
下面这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
拿到所启动进程的进程号;
不少程序都有记录日志的需求,而且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,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 | 用户输出的消息 |
#!/usr/bin/env python # -*- coding:utf8 -*- #__author__:TQTL #date: 2018/6/2 14:17 # Author:TQTL # E-mail:tqtl911@163.com #Python的日志模块 import logging # logging.warning("user [alex] attempted wrong password more than 3 times") # logging.critical("Server is down") """ WARNING:root:user [alex] attempted wrong password more than 3 times CRITICAL:root:Server is down """ # logging.basicConfig(filename='log_test.log',level=logging.INFO)#指定日志的级别为INFO或比INFO级别更高的; # # logging.debug("This message should go to log file.")#此行,没法打印至日志文件中; # logging.info("So should this.") # logging.warning("And this,too.") #自定义日志格式; logging.basicConfig(filename='log_test.log', level=logging.DEBUG, #format='%(asctime)s %(message)s', #format='%(asctime)s-%(levelno)s- %(message)s', #format='%(asctime)s-%(levelname)s- %(message)s', #format='%(asctime)s-%(levelname)s-%(pathname)s-%(message)s', #format='%(asctime)s-%(levelname)s-%(filename)s-%(message)s', #format='%(asctime)s-%(levelname)s-%(funcName)s-%(message)s', format='%(asctime)s-%(levelname)s-%(funcName)s-%(lineno)s-%(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') def sayhi(): logging.error("from sayhi;") sayhi() logging.debug("This message should go to log file.")#此行,没法打印至日志文件中; logging.info("So should this.") logging.warning("And this,too.") logging.warning("-------------------------------------------")
06/02/2018 02:40:58 PM-ERROR-sayhi-from sayhi; 06/02/2018 02:40:58 PM-DEBUG-<module>-This message should go to log file. 06/02/2018 02:40:58 PM-INFO-<module>-So should this. 06/02/2018 02:40:58 PM-WARNING-<module>-And this,too. 06/02/2018 02:40:58 PM-WARNING-<module>-------------------------------------------- 06/02/2018 02:41:36 PM-ERROR-sayhi-32-from sayhi; 06/02/2018 02:41:36 PM-DEBUG-<module>-34-This message should go to log file. 06/02/2018 02:41:36 PM-INFO-<module>-35-So should this. 06/02/2018 02:41:36 PM-WARNING-<module>-36-And this,too. 06/02/2018 02:41:36 PM-WARNING-<module>-37--------------------------------------------
若是想同时把log打印在屏幕和文件日志里,就须要了解一点复杂的知识 了
Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的归纳最为合适:
每一个程序在输出信息以前都要得到一个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对象负责发送相关的信息到指定目的地。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.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同样。
logging.handlers.TimedRotatingFileHandler
这个Handler和RotatingFileHandler相似,不过,它没有经过判断文件大小来决定什么时候从新建立日志文件,而是间隔必定时间就 自动建立新的日志文件。重命名的过程与RotatingFileHandler相似,不过新的文件不是附加数字,而是当前时间。它的函数是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename参数和backupCount参数和RotatingFileHandler具备相同的意义。
interval
是时间间隔。
when
参数是一个字符串。表示时间间隔的单位,不区分大小写。它有如下取值:
日志的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,那就不会在屏幕上打印输出; """
#!/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")
正则表达式就是字符串的匹配规则,在多数编程语言里都有相应的支持,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']
#!/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())#返回值为空;
#!/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;
#!/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
#!/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'}
#!/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']
#!/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是每次须要单独翻译,会浪费时间; """
#!/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'>
#!/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'>
"设计项目目录结构",就和"代码编码风格"同样,属于我的风格问题。对于这种风格上的规范,一直都存在两种态度:
我是比较偏向于后者的,由于我是前一类同窗思想行为下的直接受害者。我曾经维护过一个很是很差读的项目,其实现的逻辑并不复杂,可是却耗费了我很是长的时间去理解它想表达的意思。今后我我的对于提升项目可读性、可维护性的要求就很高了。"项目目录结构"其实也是属于"可读性和可维护性"的范畴,咱们设计一个层次清晰的目录结构,就是为了达到如下两点:
关于如何组织一个较好的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
简要解释一下:
除此以外,有一些方案给出了更加多的内容。好比LICENSE.txt
,ChangeLog.txt
文件等,我没有列在这里,由于这些东西主要是项目开源的时候须要用到。若是你想写一个开源软件,目录该如何组织,能够参考这篇文章。
下面,再简单讲一下我对这些目录的理解和我的要求吧。
这个我以为是每一个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。
它须要说明如下几个事项:
通常来讲,用setup.py
来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools来管理这些事情。这种方式广泛应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目必定要有一个安装部署工具,能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。
这个我是踩过坑的。
我刚开始接触Python写项目的时候,安装环境、部署代码、运行程序这个过程全是手动完成,遇到过如下问题:
setup.py
能够将这些事情自动化起来,提升效率、减小出错的几率。"复杂的东西自动化,能自动化的东西必定要自动化。"是一个很是好的习惯。setuptools的文档比较庞大,刚接触的话,可能不太好找到切入点。学习技术的方式就是看他人是怎么用的,能够参考一下Python的一个Web框架,flask是如何写的: setup.py
固然,简单点本身写个安装脚本(deploy.sh
)替代setup.py
也何尝不可。
这个文件存在的目的是:
setup.py
安装依赖时漏掉软件包。这个文件的格式是每一行包含一个包依赖的说明,一般是flask>=0.10
这种格式,要求是这个格式能被pip
识别,这样就能够简单的经过 pip install -r requirements.txt
来把全部Python包依赖都装好了。具体格式说明: 点这里。
注意,在上面的目录结构中,没有将conf.py
放在源码目录下,而是放在docs/
目录下。
不少项目对配置文件的使用作法是:
import conf
这种形式来在代码中使用配置。这种作法我不太赞同:
conf.py
这个文件;因此,我认为配置的使用,更好的方式是,
可以佐证这个思想的是,用过nginx和mysql的同窗都知道,nginx、mysql这些程序均可以自由的指定用户配置。
因此,不该当在代码中直接import conf
来使用配置文件。上面目录结构中的conf.py
,是给出的一个配置样例,不是在写死在程序中直接引用的配置文件。能够经过给main.py
启动参数指定配置路径的方式来让程序读取配置内容。固然,这里的conf.py
你能够换个相似的名字,好比settings.py
。或者你也可使用其余格式的内容来编写配置文件,好比settings.yaml
之类的。
模拟实现一个ATM + 购物商城程序
示例代码 https://github.com/triaquae/py3_training/tree/master/atm
简易流程图:https://www.processon.com/view/link/589eb841e4b0999184934329