Python学习 - 常用模块(二)

目录

一. 常用模块 - hashlib

二. 常用模块 - hmac

三. 常用模块 - logging

四. 常用模块 - re

五. 常用模块 - requests

六. 常用模块 - paramiko

 

一. 常用模块 - hashlib

hash: 一种算法, 3.x里代替了md5模块和sha模块, 主要提供 SHA1, SHA224, SHA256, SHA384, SHA512, MD5 算法

特点:

  • 内容相同则hash运算结果相同, 内容稍微改变则hash值则变
  • 不可逆推
  • 相同算法: 无论校验多长的数据, 得到的哈希值长度固定.
 1 import hashlib
 2 
 3 m=hashlib.md5()# m=hashlib.sha256()
 4 m.update('hello'.encode('utf8'))
 5 print(m.hexdigest()) #5d41402abc4b2a76b9719d911017c592
 6 m.update('alvin'.encode('utf8'))
 7 print(m.hexdigest()) #92a7e713c30abbb0319fa07da2a5c4af
 8 
 9 m2=hashlib.md5()
10 m2.update('helloalvin'.encode('utf8'))
11 print(m2.hexdigest()) #92a7e713c30abbb0319fa07da2a5c4af
12 
13 '''
14 注意: 把一段很长的数据update多次, 与一次update这段长数据, 得到的结果一样
15 但是update多次为校验大文件提供了可能. 
16 '''

以上加密算法虽然依然非常厉害, 但时候存在缺陷, 即: 通过撞库可以反解. 所以, 有必要对加密算法中添加自定义key再来做加密.

1 import hashlib
2 # ######## 256 ########
3 hash = hashlib.sha256('898oaFs09f'.encode('utf8'))
4 hash.update('alvin'.encode('utf8'))
5 print (hash.hexdigest())
6 #e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7

 

二. 常用模块 - hmac

HMAC的应用
hmac主要应用在身份验证中,它的使用方法是这样的:

  • (1) 客户端发出登录请求(假设是浏览器的GET请求)
  • (2) 服务器返回一个随机值,并在会话中记录这个随机值
  • (3) 客户端将该随机值作为密钥,用户密码进行hmac运算,然后提交给服务器
  • (4) 服务器读取用户数据库中的用户密码和步骤2中发送的随机值做与客户端一样的hmac运算,然后与用户发送的结果比较,如果结果一致则验证用户合法

在这个过程中,可能遭到安全攻击的是服务器发送的随机值和用户发送的hmac结果,而对于截获了这两个值的黑客而言这两个值是没有意义的,绝无获取用户密码的可能性,随机值的引入使hmac只在当前会话中有效,大大增强了安全性和实用性。大多数的语言都实现了hmac算法,比如php的mhash、python的hmac.py、java的MessageDigest类,在web验证中使用hmac也是可行的,用js进行md5运算的速度也是比较快的。

1 import hmac
2 h = hmac.new('alvin'.encode('utf8'))
3 h.update('hello'.encode('utf8'))
4 print (h.hexdigest())
5 #320df9832eab4c038b6c1d7ed73a5940

 

三. 常用模块 - logging

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

1 import logging
2  
3 logging.warning("user [alex] attempted wrong password more than 3 times")
4 logging.critical("server is down")
5  
6 #输出
7 WARNING:root:user [alex] attempted wrong password more than 3 times
8 CRITICAL:root:server is down

上面是最简单的应用. 但明显还不足以与nginx, apache等成熟软件的日志媲美. 如果想达到nginx这种日志的效果我们需要深入了解一下这个模块.

logging : https://docs.python.org/3.6/library/logging.html
这个包中包含了以下几个类:

  • Logger 日志类, 日志的公开接口, 应用程序代码直接使用. 
  • Handler 处理类, 处理程序发送日志记录到相应的目的地。比如将日志输入到终端/文件/内存等.
  • Formatter 格式类, 最终的输出日志记录以格式器指定的格式输出。
  • Filter 过滤类, 过滤器提供更细粒度的功能确定哪些日志记录输出。
  • LogRecord XX类
  • LoggerAdapter XX类

由于个人能力问题, 目前只说明Logger Handler Formatter 三个类的关系与用法. 其余三种等日后在更新.


Logger Handler Formatter
他们的关系请看下图.

Formatter 可以绑定给 Handler, Handler 可以绑定给Logger

如图上所示, Logger1 拥有 Handler1与Handler2的处理配置, 还拥有 Formatter 的格式配置. Logger2 拥有 Handler2与Handler3 的处理配置, 还拥有 Formatter 的格式配置.

那我们现在来看一下每个类到底都有什么功能.

Logger

 1 Logger.propagate
 2     若为True, 日志信息除了传递给该logger的handler之外, 也被传递给上游logger的handler, 不会考虑上游logger的级别与filter限制
 3     若为False, 日志信息不会传递给上游logger的handler
 4     构造函数设置该属性为True
 5 
 6 Logger.setLevel(lvl)
 7     设置该logger级别为lvl. 低于lvl的日志信息将被忽略.
 8     当创建一个根logger时, 默认级别为WARNING
 9     当创建一个非根logger时, 默认级别为NOTSET
10 
11 Logger.isEnabledFor(lvl)
12     表明lvl级别的信息是否会被该logger处理. 该方法首先检查由logging.disable(lvl)设置的模块级的级别, 然后检查由getEffective()决定的该logger的有效级别.
13     判断这个级别的信息是否会被处理. 
14 
15 Logger.getEffectiveLevel()
16     获取该logger处理信息的级别
17 
18 Logger.getChild(suffix)
19 
20 Logger.debug(msg, *args, **kwargs)
21     给该logger记录一条级别为 DEBUG 的信息, msg为消息格式字符串,args为通过字符串格式操作符合并到msg的参数。(注意这意味着可以在格式字符串中使用关键字和一个字典参数。)
22 
23     kwargs中有两个关键字参数会被检查:第一个是exc_info,如果它不为false,异常信息会被添加到日志消息。如果有提供异常元组(格式为sys.exc_info()返回值的格式),使用该元组;否则调用sys.exc_info()来得到异常信息。
24     第二个检查的关键字参数是extra,可以给它传递一个字典,用来填充LogRecord的__dict__,LogRecord用以表示日志事件,且有自定义属性。你可以随意使用这些自定义属性。例如,它们可以合并到日志消息中。示例:
25 
26     FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
27     logging.basicConfig(format=FORMAT)
28     d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
29     logger = logging.getLogger('tcpserver')
30     logger.warning('Protocol problem: %s', 'connection reset', extra=d)
31     将会打印
32     2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset
33 
34     extra的字典的键不应该与日志系统使用的键冲突。(参见Formatter文档了解日志系统所用键的信息。)
35     如果决定要在日志消息中使用这些属性,使用时要小心。拿上面的例子,Formatter的格式字符串期待LogRecord的属性字典中有'clientip''user'。如果缺失的话,该消息就不会被记录,因为会发生字符串格式异常。在这种情况下,你总是要传递带这些键的extra字典。
36     这可能有些麻烦,它主要在一些特定的环境下使用。如有一个多线程服务器,相同的代码会在许多上下文执行,而感兴趣的条件在上下文才会出现(如上例中的远端客户端IP地址和已认证用户名)。在这种环境下,很可能对特殊的Handler使用特定的Formatter。
37 
38 Logger.info(msg, *args, **kwargs)
39     给该logger记录一条级别为 INFO 的信息
40 
41 Logger.warning(msg, *args, **kwargs)
42     给该logger记录一条级别为 WARNING 的信息
43 
44 Logger.error(msg, *args, **kwargs)
45     给该logger记录一条级别为 ERROR 的信息
46 
47 Logger.critical(msg, *args, **kwargs)
48     给该logger记录一条级别为 CRITICAL 的信息
49 
50 Logger.log(lvl, msg, *args, **kwargs)
51     给该logger记录一条级别为 lvl 的信息。
52 
53 Logger.exception(msg, *args, **kwargs)
54     给该logger记录一条级别为 ERROR 的信息。异常信息将添加到日志信息中。该方法应该只在异常处理器调用。
55 
56 Logger.addFilter(filt)
57     添加指定的filter filt 到该logger。
58 
59 Logger.removeFilter(filt)
60     删除该logger中的filter filt。
61 
62 Logger.filter(record)
63     对record应用该logger的filters,如果该record应该被处理,返回真。轮流调用filters,直到有一个返回假。如果没有filter返回假值,该record将会被处理(传递给handlers)。如果有一个返回了假值,将不会对record做进一步的处理。
64 
65 Logger.addHandler(hdlr)
66     将指定的handlerhdlr添加到logger中。
67 
68 Logger.removeHandler(hdlr)
69     从logger中移除指定的handler hdlr。
70 
71 Logger.findCaller(stack_info=False)
72     查找调用者的源码文件名和行号。以3元组的形式返回文件名,行号和函数名。
73     2.4版本中的变动: 函数名被加入进来。在早期版本中,以2元组形式返回文件名和行号。
74 
75 Logger.handle(record)
76     处理一个record,将它传给该logger及其祖先的所有的handler(直到propagate为假为止)。该方法用于从套接字接收到的反序列化的record,以及那些本地创建的。使用filter()日志级别过滤会应用。
77 
78 Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)
79     这是一个工厂方法,可以在子类中覆盖它来创建特定的LogRecord实例。
80     版本2.5中的改变:添加func 和extra 参数。
81 
82 Logger.hasHandlers()
83     检查是否此日志记录器已配置的任何处理程序。这是通过寻找此日志记录器中的处理程序和其父母记录器层次结构中。如果处理程序被发现,否则错误将返回 True。方法停止搜索层次结构中向上,每当与 '传播' 属性设置为 false 的记录器发现 — — 这将是最后一个记录器,检查存在的处理程序。
84     3.2 版中的新增功能。

 

Handlers

Handlers是个基类, 在他下面有很多子类来实现了各种handlers的配置方向

StreamHandler流Handler
FileHandler文件Handler
NullHandler空Handler
WatchedFileHandler守卫文件Handler
BaseRotatingHandler基本轮询Handler
RotatingFileHandler轮询文件Handler
TimedRotatingFileHandler时间轮询文件Handler
SocketHandlerSocket Handler
DatagramHandler数据报Handler
SysLogHandler系统日志Handler
NTEventLogHandlerWindows事件日志Handler
SMTPHandlerSMTP协议Handler
MemoryHandler内存Handler
HTTPHandlerHTTP协议Handler
QueueHandler队列Handler
QueueListener队列监听器

# 每个Handler具体使用方法, 请参考: http://python.usyiyi.cn/translate/python_278/library/logging.handlers.html#module-logging.handlers

# logging模块中文文档: http://python.usyiyi.cn/python_278/library/logging.html

# 待整理文档内容到博客中.

 

按天分割日志, 并保留最近七天的配置: 

 1 # /usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @Author: kys1230
 4 # @Email: kys1230@126.com
 5 # @Date:   2017-02-22 14:36:25
 6 
 7 
 8 import logging
 9 import logging.handlers
10 
11 filename = "access.log"
12 
13 # 创建logger对象, 设置logger的日志级别
14 acc_log = logging.getLogger("access")
15 acc_log.setLevel(logging.INFO)
16 
17 # 创建文件Handler
18 fh = logging.handlers.TimedRotatingFileHandler(filename, when='D', interval=1, backupCount=7)
19 
20 # 创建格式
21 fmt = logging.Formatter("%(asctime)s - %(name)s %(filename)s:%(funcName)s:%(lineno)d %(levelname)s %(message)s")
22 
23 # 将格式绑定到Handler
24 fh.setFormatter(fmt)
25 
26 # 将Handler绑定到Logger
27 acc_log.addHandler(fh)
28 
29 # 使用Logger
30 acc_log.debug("debug")
31 acc_log.info("info")
32 acc_log.warning("warning")
33 acc_log.error("error")
34 acc_log.critical("critical")

 

四. 常用模块 - re

下图列出了Python支持的正则表达式元字符和语法: 

数量词的贪婪模式与非贪婪模式

正则表达式通常用于在文本中查找匹配的字符串. Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪), 总是尝试匹配尽可能多的字符;非贪婪的则相反, 总是尝试匹配尽可能少的字符. 例如: 正则表达式"ab*"如果用于查找"abbbc", 将找到"abbb". 而如果使用非贪婪的数量词"ab*?", 将找到"a".

反斜杠的困扰

与大多数编程语言相同, 正则表达式里使用"\"作为转义字符, 这就可能造成反斜杠困扰. 假如你需要匹配文本中的字符"\", 那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\": 前两个和后两个分别用于在编程语言里转义成反斜杠, 转换成两个反斜杠后再在正则表达式里转义成一个反斜杠. Python里的原生字符串很好地解决了这个问题, 这个例子中的正则表达式可以使用r"\\"表示. 同样, 匹配一个数字的"\\d"可以写成r"\d". 有了原生字符串, 你再也不用担心是不是漏写了反斜杠, 写出来的表达式也更直观.

匹配模式

正则表达式提供了一些可用的匹配模式, 比如忽略大小写、多行匹配等, 这部分内容将在Pattern类的工厂方法re.compile(pattern[, flags])中一起介绍.

 

re模块方法

re.compile(pattern, flags=0)  # 将字符串形式的正则表达式编译为 Pattern对象

  • strPattern  字符串形式的正则表达式
  • flag  匹配模式, 可以使用'|'表示同时生效, 比如re.I | re.M.
1 prog = re.compile(pattern)
2 result = prog.match(string)
3 # 上面用法等价于下面的用法, 区别在于可以将正则表达式的规则保存到对象中, 以便之后重复使用.
4 result = re.match(pattern, string)

Flags:

  • re.A & re.ASCII  # 待更新
  • re.DEBUG   # 显示调试信息
  • re.I & re.IGNORECASE  # 忽略大小写进行匹配
  • re.L & re.LOCALE  # 待更新
  • re.M & re.MULTILINE # 多好模式, 自行测试
  • re.S & re.DOTALL # 默认. 是不匹配换行符的, 如果加上 re.S 那么. 会匹配换行符
  • re.X & re.VERBOSE # 详细模式. 这个模式下正则表达式可以是多行, 忽略空白字符, 并可以加入注释
1 a = re.compile(r"""\d +     # the integral part
2                             \.          # the decimal point
3                             \d *      # some fractional digits""", re.X)
4 b = re.compile(r"\d+\.\d*") 
re.X 实例

re.search(pattern, string, flags=0)  # 从头开始将内容与pattern进行匹配, 如果匹配则返回一个 匹配对象, 如果匹配不到, 最终返回None

re.match(pattern, string, flags=0)  # match 相当于 search的正则表达式前加了个^, 他仅从数据的开始位置开始匹配.

re.fullmatch(pattern, string, flags=0)  # 将string与pattern进行匹配, 如果完全匹配则返回 匹配对象, 否则 返回None, 这个方法是3.4中新增加的.

1 pattern = "o[gh]" 
2 print(re.fullmatch(pattern, "dog")) # 返回None,没有og|oh开头 
3 print(re.fullmatch(pattern, "ohr")) # 返回None,不是整串完全匹配,虽然有Oh开头,但是还包含字母r 
4 print(re.fullmatch(pattern, "og")) # 返回og,完全匹配
re.fullmatch 实例

re.split(pattern, string, maxsplit=0, flags=0)   # str.split只能按照某个分隔符分割, re.split 可以按照正则规则分割. 在3.1版本后 添加了flags参数

  • maxsplit  最大分割次数

re.findall(pattern, string, flags=0)  # 获取全部的匹配字符,返回一个所有匹配字符串的列表


re.finditer(pattern, string, flags=0)  # findall类似,只是 finditer 返回的是一个迭代器

1 import re
2 data = "My name is Kys1230"
3 for i in re.finditer("\w+", data):
4     print(i.group())
5 # 执行结果
6 My
7 name
8 is
9 Kys1230
re.finditer 实例

re.sub(pattern, repl, string, count=0, flags=0)  # 将正则表达式匹配的字符串替换为新字符串

  • repl  新字符串 或 函数地址
  • count  替换几次, 0为不限制次数
1 >>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
2 ... r'static PyObject*\npy_\1(void)\n{',
3 ... 'def myfunc():')
4 'static PyObject*\npy_myfunc(void)\n{'
re.sub 实例1

如果repl是个函数, 会将正则匹配到的字符串逐一传递给函数执行, 将函数的返回值加入到结果中. 例如:

1 >>> def dashrepl(matchobj):
2 ... if matchobj.group(0) == '-': return ' '
3 ... else: return '-'
4 >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
5 'pro--gram files'
re.sub 实例2

re.subn(pattern, repl, string, count=0, flags=0)  # 与re.sub类似, 返回的是元组(新字符串, 替换的次数)

re.escape(string)  # 用于将string中的正则表达式元字符如 * + ? 等之前加上转义符再返回, 在需要大量匹配元字符时有那么一点用. 3.3版本后 "_" 不再进行转移

re.purge()  # 清空缓存中的正则表达式

 

正则表达式对象的 方法 与 属性:

regex.search(string[, pos[, endpos]])  # 从字符串string的开始位置pos开始匹配正则表达式, 到位置endpos结束匹配. 匹配成功返回 match对象, 否则返回None

  • pos 从字符串string的开始位置pos开始匹配正则表达式
  • endpos 到位置endpos结束匹配
1 >>> pattern = re.compile("d")
2 >>> pattern.search("dog") # Match at index 0
3 <_sre.SRE_Match object; span=(0, 1), match='d'>
4 >>> pattern.search("dog", 1) # No match; search doesn't include the "d"
实例

regex.match(string[, pos[, endpos]])  # 指定从字符串string头部或者指定位置的头部匹配

1 >>> pattern = re.compile("o")
2 >>> pattern.match("dog") # No match as "o" is not at the start of "dog".
3 >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog".
4 <_sre.SRE_Match object; span=(1, 2), match='o'>
实例

regex.fullmatch(string[, pos[, endpos]])  # 当整个string与正则表达式匹配时返回match对象, 否则返回None, 3.4版本中新增方法

1 >>> pattern = re.compile("o[gh]")
2 >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog".
3 >>> pattern.fullmatch("ogre") # No match as not the full string matches.
4 >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits.
5 <_sre.SRE_Match object; span=(1, 3), match='og'>
实例

regex.split(string, maxsplit=0)  # 本方法与re.split()一样

regex.findall(string[, pos[, endpos]])  # 与re.findall()一样, 本方法接收参数pos与endpos参数, 可以指定开始位置和结束位置

regex.finditer(string[, pos[, endpos]])  # 与re.finditer()一样, 本方法接收参数pos与endpos参数, 可以指定开始位置和结束位置

regex.sub(repl, string, count=0)  # 与re.sub()一样

regex.subn(repl, string, count=0)  # 与re.subn()一样

regex.flags   # 待更新

The regex matching flags. This is a combination of the flags given to compile(), any (?...) inline flags in the pattern, and implicit flags such as UNICODE if the pattern is a Unicode string.
文档原文

regex.groups   # 正则表达式匹配分组的数量

pattern = re.compile('(?P<style>[^|]*)\|(?P<tags>[^|]*)')
print(pattern.findall('OL|AAAAA'))
print(pattern.groups)
# 结果输出如下:
[('OL', 'AAAAA')]
2
实例

regex.groupindex  # 返回分组的名称和序号, 以字典方式返回. 如果没有返回空字典

pattern = re.compile('(?P<style>[^|]*)\|(?P<tags>[^|]*)')
print(pattern.findall('OL|AAAAA'))
print(pattern.groupindex)
# 结果输出如下:
[('OL', 'AAAAA')]
{'style': 1, 'tags': 2}
实例

regex.pattern  # 已经编译的正则表达式的字符串

pattern = re.compile('(?P<style>[^|]*)\|(?P<tags>[^|]*)')
print(pattern.findall('OL|AAAAA'))
print(pattern.pattern)
# 结果输出如下:
regex.pattern
[('OL', 'AAAAA')]
(?P<style>[^|]*)\|(?P<tags>[^|]*)
实例

 

Match(匹配)对象

match对象 是通过正则表达式匹配成功之后返回的对象, 如果不成功也会返回, 不过其布尔值为False. 因此, 判断是否匹配成功, 只要判断match对象的布尔值就可以, 简单的就是使用if语句来判断.

match = re.search(pattern, string)
if match:process(match)
判断是否匹配成功

match对象支持下面的方法和属性:
match.expand(template)  # 在模板字符串template中指定位置替换为指定分组的内容, 可能过索引(\1,\2)或组名称(\g<1>, \g<name>)来引用.

pattern = re.compile('(?P<style>[^|]*)\|(?P<tags>[^|]*)')
match = pattern.match('OL|AAAAA')
print(pattern.groups)
print(pattern.groupindex)
print(match.expand(r'这是一个测试\2, 没错'))
# 输出结果如下: 
2
{'style': 1, 'tags': 2}
这是一个测试AAAAA, 没错
实例

match.group([group1, ...])  # 返回分组中子分组的结果. 如果只有一个参数, 当作一个字符串返回. 如果有多个参数, 使用元组返回. 如果没有参数输入, 默认返回第一组的结果. 组号的范围在[1, 99]之间. 如果输入组号为负数, 或者大于匹配的分组最大值, 就抛出IndexError异常.

>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0) # The entire match
'Isaac Newton'
>>> m.group(1) # The first parenthesized subgroup.
'Isaac'
>>> m.group(2) # The second parenthesized subgroup.
'Newton'
>>> m.group(1, 2) # Multiple arguments give us a tuple.
('Isaac', 'Newton')>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.group('first_name')
'Malcolm'
>>> m.group('last_name')
'Reynolds'
>>> m.group(1)
'Malcolm'
>>> m.group(2)
'Reynolds'>>> m = re.match(r"(..)+", "a1b2c3") # Matches 3 times.
>>> m.group(1) # Returns only the last match.
'c3'
实例

match.groups(default=None)  # 使用元组返回所有匹配的分组, 如果有分组没有匹配, 就返回None. 如果有设置参数, 就会使用参数来替换相应没有匹配到的分组.

>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
>>> m.groups()
('24', '1632')>>> m = re.match(r"(\d+)\.?(\d+)?", "24")
>>> m.groups() # Second group defaults to None.
('24', None)
>>> m.groups('0') # Now, the second group defaults to '0'.
('24', '0')
实例

match.groupdict(default=None)  # 以字典的方式返回分组命名的匹配结果. 如果没有匹配成的分组, 以参数替换, 如果没有参数, 就默认为None替换.

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.groupdict()
{'first_name': 'Malcolm', 'last_name': 'Reynolds'}
实例

match.start([group])
match.end([group])  # 返回匹配组的开始位置和结束位置. 参数是group组号, 默认为0, 就所有组都返回.

>>> email = "tony@tiremove_thisger.net"
>>> m = re.search("remove_this", email)
>>> email[:m.start()] + email[m.end():]
'tony@tiger.net'
实例

match.span([group])  # 返回匹配对象组的开始位置和结束位置(m.start(group), m.end(group)), 格式是元组方式. 如果没有匹配任何组返回(-1, -1).

match.pos
match.endpos  # 在search和match里使用开始位置和结束位置.

match.lastindex  # 保存最后分组的值. 如果没有组, 返回None.

match.lastgroup  # 待更新

The name of the last matched capturing group, or None if the group didn’t have a name, or if no group was matched at all.
文档原文

match.re   # 在search和match中使用的正则表达式对象.

match.string   # 传给search或match进行匹配的字符串.

 

五. 常用模块 - requests

# 待更新

六. 常用模块 - paramiko

# 待更新

转载于:https://www.cnblogs.com/kys1230/p/6426985.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/253349.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UART介绍

1. 概述 UART, Universal Asynchronous Receiver-Transmitter, 通用异步收发器&#xff1b; 串口&#xff1a;在嵌入式里指的是UART口&#xff0c;常用TTL电平即3.3V或者5.0V&#xff1b; COM口&#xff1a;在台式机上常用的口&#xff0c;DB9那种接口&#xff0c;接口协议只…

mongodb环境安装

1、mongodb安装 我采用的是离线安装&#xff0c; &#xff08;1&#xff09;在mongodb的官方网址下载所需要的版本。我下载的是 mongodb-linux-x86_64-ubuntu1604-3.4.5.tgz 。 &#xff08;2&#xff09;下载后解压缩到待安装目录&#xff0c;我这里下载在了Downloads目录…

IIC 总线接口详细介绍

1. 概述 IIC Inter Integrated-Circuit 总线是PHLIPS公司推出的一种串行总线&#xff0c;是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线&#xff0c;它支持多主控(multimastering)&#xff0c;其中任何能够进行发送和接收的设备都可以成为主总线。…

Android JNI开发系列(二)HelloWorld

2019独角兽企业重金招聘Python工程师标准>>> 入门HelloWorld 新建项目 Configure your new project部分选中 Include C Support 复选框 Next 正常填写所有其他字段并完成向导接下来几个部分 在向导的Customize C Support 部分&#xff0c;您可以使用谢列选项自定…

sublime text3安装js提示的插件

今天安装Sublime Text3的js插件&#xff0c;在网上查了很多资料&#xff0c;为了方便以后看&#xff0c;写一个安装插件的总结和方法。 要安装js相关的插件&#xff0c;就要先安装一个Package Control&#xff08;插件管理器&#xff09;的插件&#xff0c;通过这个插件再去安装…

SPI接口详细介绍

1. 概述 SPI Serial Peripheral Interface&#xff0c;是串行外围设备接口&#xff0c;是一种高速&#xff0c;全双工&#xff0c;同步的通信总线。常规只占用四根线&#xff0c;节约了芯片管脚&#xff0c;PCB的布局省空间。现在越来越多的芯片集成了这种通信协议&#xff0…

H.264 Profile、Level、Encoder三张简图

H.264有四种画质级别,分别是BP、EP、MP、HP&#xff1a; 1、BP-Baseline Profile&#xff1a;基本画质。支持I/P 帧&#xff0c;只支持无交错&#xff08;Progressive&#xff09;和CAVLC&#xff1b;   2、EP-Extended profile&#xff1a;进阶画质。支持I/P/B/SP/SI 帧&…

智能音箱 之 平台方案简介

智能音箱&#xff0c;被认为是物联网时代的入口&#xff0c;在去年成为了各大厂商争相投入的风口。在当今互联网时代&#xff0c;它不仅仅是一台单纯的音乐播放器&#xff0c;在其背后支撑的 AI 技术才是整个产品的核心&#xff0c;也是各大公司觊觎物联网入口的最根本原因。经…

Linux编程 23 shell编程(结构化条件判断 命令if -then , if-then ... elif-then ...else,if test)...

一.概述 在上一篇里讲到了shell脚本&#xff0c;shell按照命令在脚本中出现的顺序依次进行处理&#xff0c;对于顺序操作已经足够了&#xff0c;但许多程序要求对shell脚本中的命令加入一些逻辑流程控制&#xff0c;这样的命令通常叫做 结构化命令。 1.1 使用if - then语句 --最…

IIS接口详细介绍

1. 概述 I2S Inter-IC Sound Integrated Interchip Sound IIS&#xff0c;是飞利浦在1986年定义&#xff08;1996年修订&#xff09;的数字音频传输标准&#xff0c;用于数字音频数据在系统内器件之间传输&#xff0c;例如编解码器CODEC、DSP、数字输入/输出接口、ADC、DAC…

继承进阶

先讲一个例子&#xff1a; #老师有生日&#xff0c;怎么组合哪&#xff1f; class Birthday: # 生日def __init__(self,year,month,day):self.year yearself.month monthself.day dayclass Teacher: # 老师<br>def __init__(self,name,birth):self.name nameself.b…

PCM接口详细介绍--TDM方式

1. 概述 PCM = Pulse Code Modulation 是通过等时间隔(即采样率时钟周期)采样将模拟信号数字化的方法。图为4 bit 采样深度的PCM数据量化示意图: PCM数字音频接口,说明接口传输的音频数据是通过PCM方式采样得到的,区别于PDM形式;IIS传输的也是PCM类型数据,属于其一个特…

Kconfig文件结构(图文)简介

1 Kconfig和Makefile 毫不夸张地说&#xff0c;Kconfig和Makefile是我们浏览内核代码时最为依仗的两个文件。基本上&#xff0c;Linux 内核中每一个目录下边都会有一个Kconfig文件和一个Makefile文件。Kconfig和Makefile就好似一个城市的地图&#xff0c;地图引导我们去 认识一…

PDM接口介绍

1. 概述 PDM Pulse Density Modulation是一种用数字信号表示模拟信号的调制方法。 PDM则使用远高于PCM采样率的时钟采样调制模拟分量&#xff0c;只有1位输出&#xff0c;要么为0&#xff0c;要么为1。因此通过PDM方式表示的数字音频也被称为Oversampled 1-bit Audio。相比P…

Kaggle 泰坦尼克

入门kaggle&#xff0c;开始机器学习应用之旅。 参看一些入门的博客&#xff0c;感觉pandas&#xff0c;sklearn需要熟练掌握&#xff0c;同时也学到了一些很有用的tricks&#xff0c;包括数据分析和机器学习的知识点。下面记录一些有趣的数据分析方法和一个自己撸的小程序。 1…

语音交互设备 前端信号处理技术和语音交互过程介绍

一、前端信号处理 1. 语音检测&#xff08;VAD&#xff09; 语音检测&#xff08;英文一般称为 Voice Activity Detection&#xff0c;VAD&#xff09;的目标是&#xff0c;准确的检测出音频信号的语音段起始位置&#xff0c;从而分离出语音段和非语音段&#xff08;静音或噪…

【BZOJ1500】[NOI2005]维修数列 Splay

【BZOJ1500】[NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000)&#xff0c;N 表示初始时数列中数的个数&#xff0c;M表示要进行的操作数目。第2行包含N个数字&#xff0c;描述初始时的数列。以下M行&#xff0c;每行一条命令&#xff0c;格式参见…

bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)

每个节点继承父节点的树&#xff0c;则答案为query(root[x]root[y]-root[lca(x,y)]-root[fa[lca(x,y)]]) #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> using namespace std; const int maxn1…

图文详解YUV420数据格式

YUV格式有两大类&#xff1a;planar和packed。 对于planar的YUV格式&#xff0c;先连续存储所有像素点的Y&#xff0c;紧接着存储所有像素点的U&#xff0c;随后是所有像素点的V。 对于packed的YUV格式&#xff0c;每个像素点的Y,U,V是连续交*存储的。 YUV&#xff0c;分为三个…

USB通信接口介绍

1. 概述 Usb Universal Serial Bus全称通用串行总线&#xff0c;是一种支持热插拔的高速串行传输总线&#xff0c;使用差分信号来传输数据。 USB设备可以直接和host通信&#xff0c;或者通过hub和host通信。一个USB系统中仅有一个USB主机&#xff0c;设备包括功能设备和hub&…