趁着有时间,把一些我用过的经常使用标准库进行整理和复习。php
用法 | 说明 |
---|---|
time.time() |
返回时间戳(从1970年1月1日00:00:00开始计算) |
time.localtime() |
返回当前时间的结构化时间(struct_time)对象,能够用.tm_year 等获取年等数据 |
time.gmtime() |
返回世界标准时间的结构化时间(struct_time)对象 |
time.mktime(struct_time) |
结构化时间转化为时间戳 |
time.strftime("时间格式", struct_time) |
结构化时间转化为字符串时间 |
time.strptime("字符串时间", "时间格式") |
字符串时间转化为结构化时间 |
time.asctime([tuple]) |
时间元组转换为字符串。若是时间元组不存在,则使用localtime()返回的当前时间 |
time.ctime(seconds) |
将时间秒数转换为时间字符串,至关于time.asctime(localtime(seconds)) 。second不存在,则使用localtime()返回的当前时间。 |
经常使用时间占位符html
%H:%M:%S
虽然python库中已经有了time库,但time库不支持对时间的加减等操做,所以就有了datetime库。node
用法 | 说明 |
---|---|
datetime.datetime.now() |
获取当前时间,返回datetime.datetime 对象,有year, month, day, hour, minute, second, microsecond等属性。 |
datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0 |
这是一个类,表示两个 date 或者 time 的时间间隔。 |
datetime.datetime.fromtimestamp(seconds) |
将秒数转换为datetime.datetime 对象,datetime.datetime.fromtimestamp(time.time()) <==>datetime.datetime.now() |
datetime.timetuple() |
这是datetime.datetime对象的方法,返回结构化时间,time.localtime() 的返回类型相同 |
datetime.replace(year=self.year, month=.., day=.., hour=.., minute=.., second=.., ...) |
同样是datetime.datetime对象的方法,能够替换当前对象的year等属性,详见文档 |
有了以上几个方法,咱们就能够对时间进行加减操做,并能够在time和datetime之间进行转换。python
import time
import datetime
def main():
date1_string = "2017/6/8 15:0:0"
# date1_string转换为时间戳
# strptime -> mktime -> fromtimestamp ==> datetime.datetime
date1 = datetime.datetime.fromtimestamp(time.mktime(
time.strptime(date1_string, '%Y/%m/%d %H:%M:%S')))
date2 = datetime.datetime.now() # 获取当前时间
# 使用datetime.datetime对象之间 进行操做,结果为datetime.timedelta对象
result1 = date2 - date1 # 两个时间过了多久了
print(result1.days, result1.seconds)
# datetime.datetime与datetime.timedelta之间的操做, 结果是datetime.datetime对象
year = datetime.timedelta(days=365) # 一年时间
result2 = date2 + 2 * year # 当前时间的两年后
print(result2.year, result2.month, result2.day)
if __name__ == '__main__':
main()
使用random能够生成伪随机数。linux
用法 | 说明 |
---|---|
random.seek(time.time()) |
初始化随机数生成器 |
random.random() |
生成[0.0, 1.0) 范围内的一个随机浮点数 |
random.uniform(num1, num2) |
返回[num1, num2] [1] 中一个随机浮点数 |
random.randint(num1, num2) |
生成[num1, num2] 范围内的一个整数,num1, num2均为int |
random.randrange(num1, num2) |
生成[num1, num2) 范围内的一个整数,num1, num2均为int |
random.choice(iterable_obj) |
从可迭代对象中随机取一个元素 |
random.sample(iterable_obj, n) |
从可迭代对象中随机取n个元素组成一个列表返回 |
random.shuffle(x) |
将序列 x 随机打乱位置。不可变的能够用random.sample(x, k=len(x)) |
生成验证码例子:git
import random
def make_code(n):
res = ''
for i in range(n):
letter = chr(random.randint(65, 90)) # 生成A-Z的任意一个字母
number = str(random.randint(0, 9)) # 生成0-9的任意一个数
res += random.choice([letter, number])
return res
print(make_code(9))
sys模块提供了一些与解释器相关的变量和函数。github
用法 | 说明 |
---|---|
sys.argv |
返回一个列表,第一个元素是程序自己路径,其余元素是命令行输入参数 |
sys.exit(n) |
退出程序,实现方式是抛出一个SystemExit 异常。正常时n为0,非零值视为“异常终止”。大多数系统要求该值的范围是 0~127。 |
sys.path |
返回模块的搜索路径,其本质上是列表,可使用append方法添加路径,导入特定模块。 |
sys.platform |
返回平台名称(Linux:'linux',Windows:'win32',Mac OS X:darwin') |
sys.stdout.write(" ") |
不换行打印 |
sys.stdout.flush() |
刷新 |
通常用于对文件和目录进性操做的模块。正则表达式
os.getcwd()
获取当前工做目录
os.chdir(path)
改变当前工做目录算法
用法 | 说明 |
---|---|
os.mkdir(path) |
建立目录 |
os.makedirs(path) |
递归建立目录 |
os.redir(path) |
删除空目录 |
os.removedirs(path) |
递归删除空目录 |
os.remove(path) |
删除文件 |
os.rename(old_name, new_name) |
更改文件或目录名 |
os.stat(path) |
查看文件详情( 'st_atime', 'st_ctime', 'st_mtime', 'st_size'等) |
用法 | 说明 |
---|---|
os.sep |
输出系统分隔符(如:\ 或/ ) |
os.linesep |
输出行终止符(win:\r\n ,linux:\n ) |
os.pathsep |
输出路径分割符(win:; ,linux:: ) |
path是os库中的一个模块,里面有不少实用的函数。shell
用法 | 说明 |
---|---|
os.path.split(path) |
把路径分割为(目录, 文件名) |
os.path.abspath(path) |
返回path规范化的绝对路径 |
os.path.normpath(path) |
返回path规范化后的结果 |
os.path.dirname(path) |
split结果的个第一元素 |
os.path.basername(path) |
split结果的个第二元素 |
os.path.join(path1, path2, path3 ...) |
把多个路径拼接成一个,并返回 |
os.path.exists(path) |
判断路径是否存在 |
os.path.isabs(path) |
判断路径是否为绝对路径 |
os.path.isfile(path) |
判断路径是否为文件 |
os.path.isdir(path) |
判断路径是否为目录 |
os.path.getatime(path) |
返回文件/目录的最后访问时间。返回值是一个浮点数,为纪元秒数 |
os.path.getctime(path) |
返回文件/目录的最后修改时间。返回值是一个浮点数,为纪元秒数 |
os.path.getmtime(path) |
Unix:返回元数据的最后修改时间,Win:返回建立时间。返回值是一个数,为纪元秒数 |
os.path.size(path) |
返回文件/目录的大小,以字节为单位 |
shutil模块提供了一系列对文件和文件集合的高阶操做。 特别是提供了一些支持文件拷贝和删除的函数。
shutil.copyfileobj(fsrc, fdst[, length])
将文件类对象 fsrc 的内容拷贝到文件类对象 fdst,length表示缓冲区大小,且默认状况为:1024 * 1024 if WINDOWS else 64 * 1024
。
import shutil
shutil.copyfileobj(open("./t1/a.txt", "r"), open("t1/b.txt", "w"))
注意有个fsrc是读,而fdst是写
shutil.copyfile(src, dst)
将src文件拷贝到dst文件,dst能够不存在
import shutil
shutil.copyfile("./t1/a.txt", "./t1/b.txt")
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变,此功能并非在全部平台上都可用(查看文档,了解更多)
import shutil
shutil.copymode("./t1/a.txt", "./t1/b.txt")
shutil.copystat(src, dst)
从 src 拷贝权限位、最近访问时间、最近修改时间以及旗标到 dst.
shutil.copy(src, dst)
拷贝文件和权限
shutil.copy2(src, dst)
拷贝文件和状态信息
shutil.copytree(src, dst)
递归拷贝,参数不少,没有详细列出
import shutil
shutil.copytree('folder1', 'folder2',
ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
# 目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
shutil.rmtree(path, ignore_errors=False, onerror=None)
shutil.move(src, dst)
json模块能够把python基本数据类型与json数据进行转换。
json.dumps(data)
将基本数据类型格式转换为json数据
import json
data = {
"name": "lczmx",
"age": 20,
}
s = json.dumps(data)
print(repr(s)) # '{"name": "lczmx", "age": 20}'
json.dump(data, file_obj)
将基本数据类型转换为json数据并写入到文件中
import json
data = {
"name": "lczmx",
"age": 20,
}
f = open("./res.json", "w", encoding="utf-8")
json.dump(data, f)
f.close()
json.loads(s)
把json字符串转化为python数据类型
import json
s = '{"name": "lczmx", "age": 20}'
res = json.loads(s)
print(res, type(res))
# {'name': 'lczmx', 'age': 20} <class 'dict'>
json.load(file_obj)
转换文件对象的json内容。
import json
with open("./res.json", "r", encoding="utf-8") as f:
res = json.load(f)
print(res, type(res))
扩展json
json模块只支持python基本数据类型,但咱们能够自定义JSON编码器,重写default方法,这样咱们本身写的类就可使用
json.dumps
了
import json
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def data_dict(self):
# 返回的是基本数据类型
return {"name": self.name, "age": self.age}
class JsonCustomEncoder(json.JSONEncoder):
# 重写default方法
def default(self, field):
if isinstance(field, Foo):
return field.data_dict() # 调用自定义的方法
else:
return json.JSONEncoder.default(self, field)
f = Foo("lczmx", 21)
# 使用时要指定自定义的编码器
res = json.dumps(f, cls=JsonCustomEncoder)
print(res)
# {"name": "lczmx", "age": 21}
模块 pickle 实现了对一个 Python 对象结构的二进制序列化和反序列化。它只能用于Python,而且可能不一样版本的Python彼此都不兼容,所以,只能用Pickle保存那些不重要的数据,不能成功地反序列化也不要紧。
注意:pickle 模块并不安全。你只应该对你信任的数据进行unpickle操做.
import pickle
dic = {'name': 'alvin', 'age': 23, 'sex': 'male'}
print(type(dic)) # <class 'dict'>
j = pickle.dumps(dic)
print(type(j)) # <class 'bytes'>
f = open('序列化对象_pickle', 'wb') # 注意是w是写入str,wb是写入bytes,j是'bytes'
f.write(j) # -------------------等价于pickle.dump(dic,f)
f.close()
# -------------------------反序列化
f = open('序列化对象_pickle', 'rb')
data = pickle.loads(f.read()) # 等价于data=pickle.load(f)
print(data['age'])
shelve" 是一种持久化的相似字典的对象,只有open方法,比pickle简单。
因为 shelve 模块须要 pickle 的支持,因此shelve模块也不安全。须要注意是否为信任数据才能使用。
import shelve
d = shelve.open("持久化文件.txt")
# 以 d[key] = data 的形式存储
d["name"] = "lczmx"
d["age"] = 22
d["addr"] = "guangzhou"
d["data"] = [1, 2, 3]
# 使用中括号取值
name = d["name"]
print(name) # lczmx
# 使用del删除某个键对应的值
del d["age"]
# 可使用 in 判断某个键是否存在
flag = "age" in d
print(flag) # False
# .keys()方法 能够列出全部的键 (速度较慢!)
klist = list(d.keys())
print(klist) # ['name', 'addr', 'data']
# 值即便是引用对象,假如要保存修改后的值,要从新赋值
temp = d['data']
temp.append(4)
print(d["data"]) # [1, 2, 3]
d['data'] = temp
print(d["data"]) # [1, 2, 3, 4]
# close掉,可使用上下文管理协议
d.close()
xml也是一个能够跨语言的数据交换协议,但使用起来没有json简单,因为xml诞生的时间比json早,因此至今还有一些公司正在使用。
步骤:
import xml.etree.ElementTree as ET
# 建立根节点
new_xml = ET.Element("namelist")
# 为跟节点建立字节点
name1 = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
age1 = ET.SubElement(name1, "age", attrib={"checked": "no"})
# 添加内容
name1.text = '老王'
age1.text = "30"
# 同上
name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
age2 = ET.SubElement(name2, "age")
name2.text = "隔壁"
age2.text = '33'
# 生成文档对象
et = ET.ElementTree(new_xml)
# 写入文件中
et.write("test.xml", encoding="utf-8", xml_declaration=True)
# 打印生成的格式
ET.dump(new_xml)
结果:
<?xml version='1.0' encoding='utf-8'?>
<namelist>
<name enrolled="yes">老王<age checked="no">30</age></name>
<name enrolled="no">隔壁<age>33</age></name>
</namelist>
对xml文件进行操做,用的是parse
方法和getroot方法
import xml.etree.ElementTree as ET
tree = ET.parse("./test.xml")
root = tree.getroot()
如下都以root即根节点这个对象进行操做
root
能够换成任意子节点
root.tag
获取标签名root.attrib
获取属性root.text
获取内容root.iter(tag)
查找子孙节点中的tag标签,以迭代器方式返回root.find(tag)
查找子节点的第一个tag标签root.findall(tag)
找子节点的全部tag标签root.text="xx"
修改内容root.set("属性名", "属性值")
设置属性值root.remove(node)
删除子节点此模块能够执行 Python 值和以 Python bytes 对象表示的 C 结构之间的转换。 这能够被用来处理存储在文件中或是从网络链接等其余来源获取的二进制数据。
通常使用它的两个函数:
struct.pack("格式", data)
struct.unpack("格式", byte_data)
import struct
# 数据 -> bytes
pi = 3.14159265358
res = struct.pack("f", pi)
print(res, type(res)) # b'\xdb\x0fI@' <class 'bytes'> # 已经转化为字节类型
# bytes -> 原数据
data = struct.unpack("f", res)
print(data, type(data)) # (3.1415927410125732,) <class 'tuple'>
格式 | C 类型 | Python 类型 | 标准大小 | 注释 |
---|---|---|---|---|
x | 填充字节 | 无 | ||
c | char | 长度为 1 的字节串 | 1 | |
b | signed char | 整数 | 1 | (1), (2) |
B | unsigned char | 整数 | 1 | (2) |
? | _Bool | bool | 1 | (1) |
h | short | 整数 | 2 | (2) |
H | unsigned short | 整数 | 2 | (2) |
i | int | 整数 | 4 | (2) |
I | unsigned int | 整数 | 4 | (2) |
l | long | 整数 | 4 | (2) |
L | unsigned long | 整数 | 4 | (2) |
q | long long | 整数 | 8 | (2) |
Q | unsigned long long | 整数 | 8 | (2) |
n | ssize_t | 整数 | (3) | |
N | size_t | 整数 | (3) | |
e | (6) | 浮点数 | 2 | (4) |
f | float | 浮点数 | 4 | (4) |
d | double | 浮点数 | 8 | (4) |
s | char[] | 字节串 | ||
p | char[] | 字节串 | ||
P | void * | 整数 | (5) |
正则表达式是用来描述字符或字符串的特殊符号,在python中用re模块实现,正则表达式模式被编译成一系列的字节码,用 C 编写的匹配引擎执行。
正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符,元字符实质上就是有特殊含义的字符。
下面列举一些经常使用的元字符,参考文档给出的元字符
字符 | 描述 | 列子 |
---|---|---|
\\ |
匹配\ | |
\w |
匹配字母、数字、下划线 | |
\W |
匹配非字母数字下划线 | |
\s |
匹配空白字符 | |
\S |
匹配非空白字符 | |
\d |
匹配数字 | |
\D |
匹配非数字 | |
\n |
匹配换行符 | |
\t |
匹配制表符 | |
^ |
匹配字符串的开头 | |
$ |
匹配字符串的结尾 | |
. |
匹配除换行符外的全部字符,当re.DOTALL标记被指定时,能够匹配换行符 | |
[] |
匹配括号中的每个字符,如[abc] 表示a 、b 、c |
|
[^] |
匹配不在括号中的字符,如[^abc] 表示不是a 或b |
|
* |
对它前面的正则式匹配0到任意次重复,如\w* 表示0到任意个数字 |
|
+ |
对它前面的正则式匹配1到任意次重复 | |
? |
对它前面的正则式匹配0到1次重复 | |
{n} |
对其以前的正则式指定匹配 m 个重复;少于 m 的话就会致使匹配失败,如\w{6} 表示6个数字 |
|
{n,m} |
对正则式进行 n 到 m 次匹配,在 n 和 m 之间取尽可能多。 | |
a|b |
匹配a或b | |
() |
组合,匹配括号内的表达式 |
更多能够看这篇文章 linux shell 正则表达式(BREs,EREs,PREs)差别比较
关于(?…)个扩展标记法
,能够看官方文档。
查找
使用 | 说明 |
---|---|
re.findall(pattern, string) |
匹配全部结果,返回一个列表,空匹配也会包含在结果里 |
re.finditer(pattern, string) |
匹配全部结果,返回由匹配对象(re.Match )构成的迭代器 。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。 |
re.search(pattern, string) |
匹配第一个结果,返回匹配对象(re.Match ),未匹配到时为None |
re.match(pattern, string) |
字符串开头至关于re.search("^ ...", string) 是否匹配pattern,是则返回匹配对象(re.Match ),未匹配到时为None |
分割
re.split(pattern, string, maxsplit=0, flags=0)
import re
s = "12a21v13xsa15"
res = re.split("[a-z]+", s)
print(res) # ['12', '21', '13', '15']
替换
import re
s = "12a21v13xsa15"
res = re.sub("[a-z]+", ", ", s)
print(res) # 12, 21, 13, 15
import re
s = "name=lczmx, age=22"
def repl_func(matchobj):
age = int(matchobj.group("age"))
return str(age + 1)
res = re.sub(r"(?P<age>\d+)", repl_func, s)
print(res) # name=lczmx, age=23
匹配对象(re.Match
)操做
Match.group([group1, ...])
(?P<name>…)
语法,能够用Match.group("name")的方式取值。Match.groups(default=None)
import re
s = "abc@example.com,user"
res = re.match(r"([a-zA-Z]+)@(\w+\.com)", s)
print(res.groups()) # ('abc', 'example.com')
print(res.group(0)) # abc@example.com
print(res.group(1)) # abc
print(res.group(2)) # example.com
res = re.match(r"(?P<prefix>\w+)@(?P<suffix>\w+\.com)", s)
print(res.groups()) # ('abc', 'example.com')
print(res.group(0)) # abc@example.com
print(res.group(1)) # abc
print(res.group("prefix")) # abc
print(res.group(2)) # example.com
print(res.group("suffix")) # example.com
print(res.groupdict()) # {'prefix': 'abc', 'suffix': 'example.com'}
去括号优先级
假如这样的例子:
import re
res = re.findall(r"(abc)+", "abcabcabc")
print(res) # ['abc']
其匹配结果是["abc"],而非["abcabcabc"],这是由于括号的优先级高,假如要括号与后面的元字符相结合的化可使用如下方法:
import re
res = re.findall(r"(?:abc)+", "abcabcabc")
print(res) # ['abcabcabc']
匹配原理
关于正则匹配原理,看此文。
关于日志管理的基本教程,请点击这里
关于使用日志的流程,大约有如下步骤:
logging.basicConfig()
设置logging
,肯定日记级别、是否输入到文件、信息格式等参数logging
的debug
、info
、warning
、error
、critical
方法注意
因为logging.basicConfig()只须要定义一次,因此debug
等方法应该在其被设置后调用
打印到终端是开发过程当中的一个实用的方法。
import logging
logging.basicConfig()
logging.debug("debug messages")
logging.info("info messages")
logging.warning("warning messages")
logging.error("error messages")
logging.critical("critical messages")
因为默认日志级别为WARNING,因此只在终端显示了后三行信息
为basicConfig()
增长filename
参数便可
import logging
logging.basicConfig(filename="test.log")
logging.debug("debug messages")
logging.info("info messages")
logging.warning("warning messages")
logging.error("error messages")
logging.critical("critical messages")
python 3.9版本的logging.basicConfig() 能够指定
encoding
参数,以前的以系统默认的编码方式打开。
在多个模块中import logging
便可,其操做的是同一个logging对象
import logging
import mylib
def main():
logging.basicConfig()
logging.warning("start function")
mylib.my_func()
logging.warning("end function")
print(id(logging)) # 2248755624272
if __name__ == '__main__':
main()
./mylib.py
# ./mylib.py
import logging
def my_func():
logging.error("error massage")
print(id(logging)) # 2248755624272
日志级别从低到高:
级别 | 什么时候使用 |
---|---|
DEBUG | 细节信息,仅当诊断问题时适用。 |
INFO | 确认程序按预期运行 |
WARNING | 代表有已经或即将发生的意外(例如:磁盘空间不足)。程序仍按预期进行 |
ERROR | 因为严重的问题,程序的某些功能已经不能正常执行 |
CRITICAL | 严重的错误,代表程序已不能继续执行 |
默认级别为WARNING
修改日志级别要用到logging.basicConfig()
的level
参数,其传入的值是一个在logging模块中已经被定义好的数:
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
例子:
import logging
logging.basicConfig(level=logging.INFO)
logging.warning("start function")
使用argparse
库接收命令行参数,再使用getattr()
方法从logging
模块中把对应的日志级别取出来:
import logging
import argparse
# log选项的值只能是level_list的元素
level_list = ["debug", "info", "warning", "warn", "error", "fatal", "critical"]
level_list.extend(list(map(lambda x: x.upper(), level_list))) # 全大写再加入
parser = argparse.ArgumentParser(description="test file")
parser.add_argument("--log", default="debug", choices=level_list)
args = parser.parse_args()
# 拿到级别字符串后要大写
level = getattr(logging, args.log.upper())
logging.basicConfig(level=level)
logging.debug("debug messages")
logging.info("info messages")
logging.warning("warning messages")
logging.error("error messages")
logging.critical("critical messages")
$ python test.py --log error ERROR:root:error messages CRITICAL:root:critical messages $ python test.py --log info INFO:root:info messages WARNING:root:warning messages ERROR:root:error messages CRITICAL:root:critical messages
configparser库是python的配置文件管理模块,其所用结构与 INI 文件的相似。
注意:小节(section)中的键(key)大小写不敏感而且会存储为小写形式
步骤:
configparser.ConfigParser()
import configparser
# 1 建立parser对象
config = configparser.ConfigParser()
# 2 添加数据
# 方法一
config["DEFAULT"] = {"HOST": "localhost", "PORT": "3306"}
# 方法二
config["CUSTOM"] = {}
config["CUSTOM"]["HOST"] = "192.168.0.1"
# 或
custom_config = config["CUSTOM"]
custom_config["PORT"] = "3333"
# 3 写入文件
with open("config.ini", "w") as f:
config.write(f)
最外层就是一个字典
config.ini文件:
[DEFAULT]
host = localhost
port = 3306
[CUSTOM]
host = 192.168.0.1
port = 3333
注意:DEFAULT不在sections()中,能够直接用["DEFAULT"].get(key)
或.get("DEFAULT", key)
取值
根据不一样的需求能够用如下几个方法:
config.read(path) 读取配置文件
config.sections() 返回可用节的列表,即[xxx]
中的xxx
config.options(Section) 返回键构成的元组
config.items(Section) 返回列表,元素为键值对组成的元组
config.get(Section, key) 等价于 Section.get(key)
Section.get(key, default) 相似字典同样取值
config 还能够经过使用for循环,有.keys(), .values(), .items()
import configparser
config = configparser.ConfigParser()
config.read("./config.ini")
print(config["DEFAULT"].get("host")) # localhost
print(config.options("CUSTOM")) # ['host', 'port']
print(config.items("CUSTOM"))
# [('host', '192.168.0.1'), ('port', '3333')]
config.remove_section(section) 删除块即整个[xxx]
config.remove_option(section, key) 删除块下面的键(包括值)
import configparser
config = configparser.ConfigParser()
config.read("./config.ini")
config.remove_section("CUSTOM")
config.remove_option("DEFAULT", "host")
config.write(open("./config.ini", "w"))
argparse是python推荐的命令行参数解析模块,argparse基于optparse(3.2版中已经被弃用),因此二者用法相似。
其通常的使用步骤是:
parser = argparse.ArgumentParser(description="计算两个数的和", prog="SUM")
description
参数能够指定帮助文档以前显示的描述信息prog
指定程序名,默认sys.argv[0]
使用parser.add_argument(name or flags)
方法,该方法能够指定位置参数或者是选项,并且它能够接收不少参数,下面列举几个经常使用的参数:
action值 | 说明 |
---|---|
store |
存储参数的值(默认) |
store_true and store_false |
分别用做存储 True 和 False 值的特殊用例 |
version |
指望有一个 version= 命名参数,version参数能够用%(prog)s 的形式使用prog参数 |
False
parser.add_argument("x", type=float, help="一个数x") # 添加位置参数x
parser.add_argument("y", type=float, help="一个数y") # 添加位置参数y
# 添加选项-a, 把值存储为True
parser.add_argument("-a", action="store_true", help="显示详细过程")
# 添加选项-f,它的值知道能是[1, 2, 3]中的元素
parser.add_argument("-f", default=1, choices=[1, 2, 3],
type=int, help="保留小数点位数")
# 添加选项-v 或 --version
# 使用来自argparse.ArgumentParser的prog参数
parser.add_argument("-v", "--version", action="version",
version="%(prog)s 0.1", help="显示版本")
经过parser.parse_args()
解析,而后经过.
的方式取值(不管位置参数仍是选项)
# 解析
args = parser.parse_args()
print(args.x)
print(args.a)
print(args.f)
一个计算两个数和的程序
import argparse
parser = argparse.ArgumentParser(description="计算两个数的和", prog="SUM")
parser.add_argument("x", type=float, help="一个数x") # 添加位置参数x
parser.add_argument("y", type=float, help="一个数y") # 添加位置参数y
# 添加选项-a, 把值存储为True
parser.add_argument("-a", action="store_true", help="显示详细过程")
# 添加选项-f,它的值知道能是[1, 2, 3]中的元素
parser.add_argument("-f", default=1, choices=[1, 2, 3],
type=int, help="保留小数点位数")
# 添加选项-v 或 --version
# 使用来自argparse.ArgumentParser的prog参数
parser.add_argument("-v", "--version", action="version",
version="%(prog)s 0.1", help="显示版本")
# 解析
args = parser.parse_args()
# 计算并保留小数
res = round(args.x + args.y, args.f)
if args.a:
print("{x} + {y} = {res}".format(x=args.x, y=args.y, res=res))
else:
print(res)
在命令行中使用:
$ python get_sum.py -h usage: SUM [-h] [-a] [-f {1,2,3}] [-v] x y 计算两个数的和 positional arguments: x 一个数x y 一个数y optional arguments: -h, --help show this help message and exit -a 显示详细过程 -f {1,2,3} 保留小数点位数 -v, --version 显示版本 $ python get_sum.py -v SUM 0.1 $ python get_sum.py 3.14 5.96 9.1 $ python get_sum.py 3.14 5.96 -a 3.14 + 5.96 = 9.1 $ python get_sum.py 3.14159 3.335 -f 3 -a 3.14159 + 3.335 = 6.477 $ python get_sum.py usage: SUM [-h] [-a] [-f {1,2,3}] [-v] x y SUM: error: the following arguments are required: x, y
hashlib是针对不一样的安全哈希和消息摘要算法实现了一个通用的接口。
生成md5
import hashlib
md5 = hashlib.md5()
# 输入的是字节串
md5.update("test message".encode("utf-8"))
res = md5.hexdigest()
print(res)
# c72b9698fa1927e1dd12d3cf26ed84b2
为md5加盐
所谓加盐就是update其余内容,改变md5的值,防止撞库。
import hashlib
md5 = hashlib.md5()
# 输入的是字节
md5.update("加盐".encode("utf-8"))
md5.update("test message".encode("utf-8"))
res = md5.hexdigest()
print(res)
# 3f5a030db81d9e5e83d2c8e7eba1965c
生成uuid4
import uuid
print(uuid.uuid4())
# f1d50cdd-2f36-4db2-b788-ec4f2f08ce52
subprocess 模块容许你生成新的进程,链接它们的输入、输出、错误管道,而且获取它们的返回码。
对于subprocess模块,咱们只须要关注底层的Popen接口的使用方法便可。
经常使用参数:
args
shell
True或False
/bin/sh
stdin
, stdout
和 stderr
subprocess.PIPE
表示打开标准流的管道None
更加详细内容,请看官方文档
获取返回信息
subprocess.PIPE
接收固然也能够在stdout中传入文件对象,直接写入文件中
使用例子
import subprocess
# 执行没有参数的
subprocess.Popen(["dir"], shell=True, stdout=open("dir_res.txt", "w"))
# 有参数
# get_sum.py为argparse模块最后的例子
command = "python get_sum.py 3.47 2.48 -a -f 2"
res2 = subprocess.Popen(command.split(" "), shell=True, stdout=subprocess.PIPE)
print(res2.stdout.read().decode("gbk")) # 3.47 + 2.48 = 5.95
# stdout做为stdin
res3 = subprocess.Popen(["echo", "www.baidu.com"],
shell=True, stdout=subprocess.PIPE)
res4 = subprocess.Popen(["nslookup"], shell=True,
stdin=res3.stdout, stdout=subprocess.PIPE)
print(res4.stdout.read().decode("gbk"))
""" 默认服务器: UnKnown Address: 192.168.0.1 > 服务器: UnKnown Address: 192.168.0.1 名称: www.baidu.com Address: 182.61.200.7 > """
num1 > num2时为[num2, num1] ↩