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,一经查实,立即删除!

相关文章

select函数分析

Select在Socket编程中还是比较重要的&#xff0c;可是对于初学Socket的人来说都不太爱用Select写程序&#xff0c;他们只是习惯写诸如connect、accept、recv或recvfrom这样的阻塞程序&#xff08;所谓阻塞方式block&#xff0c;顾名思义&#xff0c;就是进程或是线程执行到这些…

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目录…

rabbitmq队列的exclusive,durability,auto-delete属性以及消息可靠传输设计

非集群下&#xff0c;简单的说&#xff1a;- 如果是excl&#xff0c;则设置durability没有意义&#xff0c;因为不管服务器挂了还是客户端主动/被动断开了&#xff0c;队列都会自动删除。- auto-delete&#xff0c;其实可简单的认为是同理&#xff0c;即使非excl&#xff0c;则…

IIC 总线接口详细介绍

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

DMA数据传输过程

DMA方式具有如下特点&#xff1a;1、 外部设备的输入输出请求直接发给主储存器。主存储器既可以被CPU访问&#xff0c;也可以被外围设备访问。因此&#xff0c;在主存储器中通常要有一个存储管理部件来为各种访问主存储器的申请排队&#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…

驻扎博客园

今天把之前hexo里的一些文章全部转移到博客园了&#xff0c;之后就在博客园写点东西&#xff0c;记录一些生活的琐事。为什么要移至博客园呢&#xff1f;其实很简单&#xff0c;这边可以和一些同意从事前端的小伙伴一起互动。技术还是需要多讨论的&#xff0c;希望之后能多更新…

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 帧&…

require.js学习记录

1、简介 官方对requirejs的描述&#xff1a;RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will impro…

iOS-AFNetworking参数和多文件同时上传【多文件上传】

1. 前言 在项目开发中&#xff0c;我们经常需要上传文件&#xff0c;例如&#xff1a;上传图片&#xff0c;上传各种文件&#xff0c;而有时也需要将参数和多个文件一起上传&#xff0c;不知道大家的项目中遇到了没有&#xff0c;我在最近的项目中&#xff0c;就需要这样的一个…

智能音箱 之 平台方案简介

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

Linux Kconfig及Makefile学习

内核源码树的目录下都有两个文档 Kconfig &#xff08;2.4版本是Config.in&#xff09;和Makefile。分布到各目录的Kconfig构成了一个分布式的内核配置数据库&#xff0c;每个Kconfig分别描述了 所属目录源文档相关的内核配置菜单。在内核配置make menuconfig时&#xff0c;从K…

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

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

Scala-Spark digamma stackoverflow问题

这两天在用spark做点击率的贝叶斯平滑&#xff0c;参考雅虎的论文进行了一番尝试。 先上代码&#xff1a; 1 # click_count, show_count # this method takes time2 def do_smooth(data_list):3 import scipy.special as sp4 a, b, i 1.0, 1.0, 05 da, db a, b6 …

IIS接口详细介绍

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

UVA - 10934 Dropping water balloons(装满水的气球)(dp)

题意&#xff1a;有k个气球&#xff0c;n层楼&#xff0c;求出至少需要多少次实验能确定气球的硬度。气球不会被实验所“磨损”。 分析&#xff1a; 1、dp[i][j]表示第i个气球&#xff0c;测试j次所能确定的最高楼层。 2、假设第i-1个气球测试j-1次所确定的最高楼层是a, 若第i个…

继承进阶

先讲一个例子&#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…