一、python入门
1. python介绍
1.1 python可运用范围
1.1.1 脚本、小工具
import random
import win32api
import time
import win32con
names = ['张三', '李四', '王五', '小六']
name = random.choice(names)
print("抽到谁谁是大帅比!")
print("倒计时开始~")
for num in range(3):
time.sleep(1)
print(3-num)
time.sleep(1)
win32api.MessageBox(0, name, "提示", win32con.MB_ICONASTERISK)
1.1.2 单个接口测试
import requests
import json
def config():
# 拉取配置,获取配置列表
# url
url = "http://17620533205.wicp.vip:46685/logout"
# 请求头
# headers = {
# 'Content-Type': 'application/x-www-form-urlencoded'
# }
# 请求参数
data = {
'account': '111000',
'password': '123456'
}
r1 = requests.post(url, json=data)
# 以json数据类型接收,传给r2,r2即整个接口测试返回的数据
r2 = r1.json()
print(json.dumps(r2, sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False))
config()
1.1.3 selenium
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
url = 'https://dev.umaicloud.com/login'
# 访问网页登录页
driver.get(url)
# 点击账号输入框和输入账号
driver.find_element_by_xpath('//*[@id="app"]/div/div[3]/div[1]/div[2]/div[1]/form/div[1]/div/div/input').send_keys(
'xxxxx')
# 点击密码输入框输入密码
driver.find_element_by_xpath('//*[@id="app"]/div/div[3]/div[1]/div[2]/div[1]/form/div[2]/div/div/input').send_keys(
'xxxxx')
# 点击登录按钮
driver.find_element_by_xpath('//*[@id="app"]/div/div[3]/div[1]/div[2]/div[1]/form/div[4]/div/button').click()
time.sleep(10)
print("登录成功")
# 关闭浏览器
driver.quit()
# 八大定位元素方法
# find_element_by_name
# find_element_by_id
# find_element_by_xpath
# find_element_by_link_text
# find_element_by_partial_link_text
# find_element_by_tag_name
# find_element_by_class_name
# find_element_by_css_selector
1.1.4 appium
# -*- encoding=utf8 -*-
__author__ = "Administrator"
from airtest.core.api import *
auto_setup(__file__)
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
def open_app(start_time):
stop_app('com.tencent.mm')
start_app('com.tencent.mm')
sleep(2)
items_elements = poco(name='com.tencent.mm:id/b2p').offspring('com.tencent.mm:id/e0n')
names = list(map(lambda x: x.get_text(), items_elements))
target = "调试"
index = names.index(target)
print([index])
print(items_elements[index])
items_elements[index].click()
while True:
times = time.strftime("%H:%M:%S")
sleep(1)
if times >= start_time:
while True:
try:
msg_list = poco("com.tencent.mm:id/alz").child("android.widget.RelativeLayout").offspring("com.tencent.mm:id/ak4")
except Exception:
print("暂无红包,继续等待!")
else:
while True:
for msg in msg_list:
red_package = msg.offspring("com.tencent.mm:id/r6")
invalid = msg.offspring("com.tencent.mm:id/aa5").offspring("com.tencent.mm:id/qv")
if red_package:
print("发现红包")
if invalid.exists() and (invalid.get_text() == '已领取' or invalid.get_text() == '已被领完'):
print("无效红包")
continue
else:
print("有效红包,正在抢~")
red_package.click()
open_btn = poco("com.tencent.mm:id/dbr")
if open_btn.exists():
open_btn.click()
else:
print("来晚一步,已被抢完~")
keyevent('BACK')
else:
print(times)
open_app("10:29:00")
1.1.5 爬虫
import requests
import re
from urllib import parse
from win32com.client import Dispatch
import time
import win32api
import pyperclip
from DownloadMovie import download
class dytt(object):
def __init__(self):
pass
@staticmethod
def get_id():
name = parse.quote(input("请输入你要下载的电影名称:"), encoding='gbk')
url = "http://s.ygdy8.com/plus/so1.php?typeid=1&keyword=" + name
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Cookie": "UM_distinctid=16f9ecd77256b4-07ee71ccac26da-376b4502-1fa400-16f9ecd77262a1",
"Host": "s.ygdy8.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36",
}
r = requests.get(url, headers=headers, verify=False)
r.encoding = 'gbk'
# print(r.text)
result1 = re.findall("<a href='/html/gndy/.+?</a>", r.text, re.S)
# print(result1)
if len(result1) == 0:
print("未获取到资源~正在切换路线寻找资源···")
names = parse.unquote(name, encoding='gbk')
# print(names)
download(names)
time.sleep(3)
quit()
elif len(result1) == 1:
result2 = str(re.findall("html/gndy/.+?.html", str(result1), re.S)).strip('[""]').strip("'")
# print(result2)
return result2
else:
for i in range(len(result1)):
print(f"{i + 1}、", result1[i].strip("<a href=</a>"))
i += 1
num = int(input("请输入你要下载的电影序号:"))
result2 = str(re.findall("html/gndy/.+?.html", result1[num - 1], re.S)).strip('[""]').strip("'")
# print(result2)
return result2
@staticmethod
def get_download_url():
movie_id = dytt.get_id()
requests.packages.urllib3.disable_warnings()
url = "https://www.ygdy8.com/" + movie_id
# print(url)
r = requests.get(url, verify=False)
r.encoding = 'gbk'
# print(r.text)
result = re.findall('>magnet:.+?<', r.text, re.S)
# print(len(result))
if len(result) == 0:
result1 = re.findall('<a href="ftp:.+?">', r.text, re.S)
if len(result1) == 0:
result3 = re.findall('thunder.+?<', r.text, re.S)
if len(result3) == 0:
print("暂未找到下载链接或下载链接失效!")
elif len(result3) == 1:
print("正在打开迅雷,可能需要几秒钟~")
win32api.ShellExecute(0, 'open', 'C:\\Program Files\\Thunder\\Program\\ThunderStart.exe', '', '', 3)
time.sleep(5)
pyperclip.copy(result3)
else:
for j in range(len(result3)):
print(f"{j + 1}、", result3[j])
j += 1
num = int(input("请选择:"))
pyperclip.copy(result3[num - 1])
else:
if len(result1) == 1:
result2 = str(result1).strip("['<a href=>']").strip('"')
# print(result2)
dytt.open_thunder(result2)
else:
for m in range(len(result1)):
print(f"{m + 1}、", result1[m])
m += 1
num = int(input("请选择:"))
result2 = str(result1[num - 1]).strip("['<a href=>']").strip('"')
# print(result2)
dytt.open_thunder(result2)
else:
for n in range(len(result)):
print(f"{n + 1}、", result[n].strip('><'))
n += 1
num = int(input("请输入你要下载的电影序号:"))
result3 = result[num - 1].strip('><')
dytt.open_thunder(result3)
def open_thunder(downloadurl):
print("正在打开迅雷,可能需要几秒钟~")
win32api.ShellExecute(0, 'open', 'C:\\Program Files\\Thunder\\Program\\ThunderStart.exe', '', '', 3)
time.sleep(5)
thunder = Dispatch('ThunderAgent.Agent64.1')
thunder.AddTask(downloadurl)
thunder.CommitTasks()
dytt.get_download_url()
1.1.6 面向对象与面向过程
- 区别
- 面向过程
- 面向对象
1.2 环境搭建(python+pycharm)
1.2.1 python下载
1.2.2 python安装
1.2.3 python安装路径添加至path
1.2.4 检验安装
1.2.5 修改pip下载路径为国内源
[global]
trusted-host = mirrors.aliyun.com
index-url = https://mirrors.aliyun.com/pypi/simple
1.2.6 升级pip版本到20版本+
1.2.7 查看安装的所有模块
1.2.8 设置pycharm运行Python的路径
1.2.9 修改字体大小及主题
1.3 解释器及编码
1.3.1 解释器
#!/usr/bin/python
1.3.2 编码
#!/usr/bin/python
print ("你好,世界")
2.python基础(针对性讲解)
2.1 语法要求
-
python标识符
print ('hello');print ('world'); hello world print('hello \ world') Hello, World!
-
python保留字符
and exec not assert finally or break for pass class from print continue global raise def if return del import try elif in while else is with except lambda yield -
行和缩进
if True: print ("True") else: print ("False")
if True: print ("Answer") print ("True") else: print ("Answer") # 没有严格缩进,在执行时会报错 print ("False")
File "test.py", line 11 print ("False") ^ IndentationError: unindent does not match any outer indentation level
-
注释
# 第一个注释 print ("Hello, Python!") # 第二个注释
''' 这是多行注释,使用单引号。 这是多行注释,使用单引号。 这是多行注释,使用单引号。 ''' """ 这是多行注释,使用双引号。 这是多行注释,使用双引号。 这是多行注释,使用双引号。 """
-
输入和输出
2.2 常用运算符
-
算数运算符
a = 1 b = 2 w = a + b x = b - a y = a * b z = int(b / a) print(w, x, y, z)
-
比较(关系)运算符
运算符 描述 实例 == 等于 - 比较对象是否相等 (a == b) 返回 False != 不等于 - 比较两个对象是否不相等 (a != b) 返回 true <> 不等于 - 比较两个对象是否不相等 (a <> b) 返回 true。这个运算符类似 != > 大于 - 返回x是否大于y (a > b) 返回 False < 小于 - 返回x是否小于y (a < b) 返回 true >= 大于等于 - 返回x是否大于等于y (a >= b) 返回 False <= 小于等于 - 返回x是否小于等于y (a <= b) 返回 true -
赋值运算符
运算符 描述 实例 = 简单的赋值运算符 c = a + b 将 a + b 的运算结果赋值为 c += 加法赋值运算符 c += a 等效于 c = c + a -= 减法赋值运算符 c -= a 等效于 c = c - a *= 乘法赋值运算符 c *= a 等效于 c = c * a /= 除法赋值运算符 c /= a 等效于 c = c / a %= 取模赋值运算符 c %= a 等效于 c = c % a **= 幂赋值运算符 c **= a 等效于 c = c ** a //= 取整除赋值运算符 c //= a 等效于 c = c // a -
逻辑运算符
运算符 逻辑表达式 描述 and x and y "与" or x or y "或" not not x "非" -
成员运算符
运算符 描述 实例 in 找到返回True,否则False x 在 y 序列中 , 如果 x 在 y 序列中返回 True not in 没有找到返回True,否则False x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True
2.3 条件语句
if 判断条件:
执行语句……
else:
执行语句……
if 判断条件1:
执行语句1……
elif 判断条件2:
执行语句2……
elif 判断条件3:
执行语句3……
else:
执行语句4……
2.4 循环语句
2.4.1 for
for num in range(10):
print(num) # num会从0开始遍历,至10结束(不包含10),打印出来
0
1
2
3
4
5
6
7
8
9
for num in range(1, 10):
print(num) # num从1开始遍历,至10结束(不包含10),打印出来
1
2
3
4
5
6
7
8
9
names = ['张三', '李四', '王五', '小六']
for name in names:
print(name) # 遍历列表names,打印names所有元素
张三
李四
王五
小六
names = ['张三', '李四', '王五', '小六']
print(len(names)) # 获取列表长度 结果为4
for num in range(len(names)): # 将长度作为一个范围,num会从0遍历,再把num作为序号加入到列表索引中
print(names[num])
4
张三
李四
王五
小六
2.4.2 while
while 判断条件:
执行语句……
age = 0
while age > 0: # 条件不成立,所以不会执行该while语句
print("条件不成立")
while age == 0: # 因为age永远是0,所以陷入无限循环
print("条件为真")
2.4.3 循环控制语句
age = 0
while True: # 判断该条件是否为真,真就会一直循环往下执行代码,也可以表示为while age >= 0:
age += 1 # 每过一年,我大一岁
if age > 18: # 如果我长大到了18岁,则跳出循环
print("我超过18岁了")
break # 开始跳出
elif age == 18: # 当age=18岁时,会走到这,因为加了pass语句,执行了空语句,所以不会报错
# print("我刚好18岁了")
pass
else:
print("我还没到18岁呢") # 判断我还没到18岁,会一直循环下去,知道18岁才跳出循环
continue
print("加了continue就不会走到这条语句,没加的话会执行完else里的语句再进行下一次循环")
-
break
-
continue
-
pass
2.5 变量类型
-
整型
-
浮点型
-
字符串
-
字典
-
列表
-
元组
2.6 字符串
-
索引
strings = 'hello world' # 空格也属于一个字符 print(strings[0]) # 取第一个字符 print(strings[1:5]) # 截取第二个字符到第五个(不包含5即第6个字符)
h ello
-
运算
操作符 描述 实例 + 字符串连接 >>>a + b 'HelloPython' * 重复输出字符串 >>>a * 2 'HelloHello' [] 通过索引获取字符串中字符 >>>a[1] 'e' [ : ] 截取字符串中的一部分 >>>a[1:4] 'ell' in 成员运算符 - 如果字符串中包含给定的字符返回 True >>>"H" in a True not in 成员运算符 - 如果字符串中不包含给定的字符返回 True >>>"M" not in a True % 格式字符串 请看下一章节 var = 'Hello World!' print("输出:", var[:6] + 'Python!')
输出: Hello Python!
-
格式化
符 号 描述 %c 格式化字符及其ASCII码 %s 格式化字符串 %d 格式化整数 %u 格式化无符号整型 %o 格式化无符号八进制数 %x 格式化无符号十六进制数 %X 格式化无符号十六进制数(大写) %f 格式化浮点数字,可指定小数点后的精度 %e 用科学计数法格式化浮点数 %E 作用同%e,用科学计数法格式化浮点数 %g %f和%e的简写 %G %F 和 %E 的简写 %p 用十六进制数格式化变量的地址 #!/usr/bin/python print("My name is %s and I am %d years old!" % ('python', 29))
My name is python and I am 29 years old!
2.7 列表
-
访问列表中的值及截取
Python 表达式 结果 描述 L[2] 'Taobao' 读取列表中第三个元素 L[-2] 'Runoob' 读取列表中倒数第二个元素 L[1:] ['Runoob', 'Taobao'] 从第二个元素开始截取列表 list1 = ['physics', 'chemistry', 1997, 2000] list2 = [1, 2, 3, 4, 5, 6, 7] print(list1[0]) print(list2[1:5])
physics [2, 3, 4, 5]
-
增加值
list = [] # 空列表 list.append('hello') # 使用 append() 添加元素 list.append('python') print(list)
['hello', 'python']
-
删除值
list = [] # 空列表 list.append('hello') # 使用 append() 添加元素 list.append('python') print(list) del list[1] # 删除list中第二个元素,即python print(list)
-
列表函数&方法
序号 函数 1 cmp(list1, list2) 比较两个列表的元素 2 len(list) 列表元素个数 3 max(list) 返回列表元素最大值 4 min(list) 返回列表元素最小值 5 list(seq) 将元组转换为列表 序号 方法 1 list.append(obj) 在列表末尾添加新的对象 2 list.count(obj) 统计某个元素在列表中出现的次数 3 list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) 4 list.index(obj) 从列表中找出某个值第一个匹配项的索引位置 5 list.insert(index, obj) 将对象插入列表 6 [list.pop(index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 7 list.remove(obj) 移除列表中某个值的第一个匹配项 8 list.reverse() 反向列表中元素 9 list.sort(cmp=None, key=None, reverse=False) 对原列表进行排序
2.8 字典
-
查(访问字典的值,同json取值)
dicts = {'Name': 'python', 'Age': 29, 'sex': 'other'} print(dicts['Name']) print(dicts['Age'])
python 29
dicts = {'Name': 'python', 'Age': 29, 'Sex': 'other'} print(dicts['email'])
-
增/改(增加/修改字典)
dicts = {'Name': 'python', 'Age': 29, 'Sex': 'other'} dicts['Sex'] = '男' dicts['Age'] = 30 print(dicts)
{'Name': 'python', 'Age': 30, 'Sex': '男'}
dicts = {'Name': 'python', 'Age': 29, 'Sex': 'other'} dicts['name'] = 'java' dicts['age'] = 30 dicts['sex'] = '男' print(dicts)
{'Name': 'python', 'Age': 29, 'Sex': 'other', 'name': 'java', 'age': 30, 'sex': '男'}
-
删(删除字典元素)
dicts = {'Name': 'python', 'Age': 29, 'Sex': 'other'} del dicts['Sex'] print(dicts) # 删除了Sex及值,打印时就不会被打印出来 dicts.clear() # 清空了字典元素,打印时会打印空的字典 print(dicts) del dicts # 删除了整个字典,所以打印时会提示未定义dicts print(dicts)
{'Name': 'python', 'Age': 29} {} NameError: name 'dicts' is not defined
2.9 类型转换
2.9.1 各数据类型转换
函数 | 描述 |
---|---|
[int(x ,base]) | 将x转换为一个整数 |
[long(x ,base] ) | 将x转换为一个长整数 |
float(x) | 将x转换到一个浮点数 |
[complex(real ,imag]) | 创建一个复数 |
str(x) | 将对象 x 转换为字符串 |
repr(x) | 将对象 x 转换为表达式字符串 |
eval(str) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s) | 将序列 s 转换为一个元组 |
list(s) | 将序列 s 转换为一个列表 |
set(s) | 转换为可变集合 |
dict(d) | 创建一个字典。d 必须是一个序列 (key,value)元组。 |
frozenset(s) | 转换为不可变集合 |
chr(x) | 将一个整数转换为一个字符 |
unichr(x) | 将一个整数转换为Unicode字符 |
ord(x) | 将一个字符转换为它的整数值 |
hex(x) | 将一个整数转换为一个十六进制字符串 |
oct(x) | 将一个整数转换为一个八进制字符串 |
2.9.2 字符串与字典
-
json.dumps()
import json # 需要导入JSON包 data = {'name': '张三', 'password': '123456', "male": True, "money": None} # 字典格式 str_data = json.dumps(data) # 序列化,转化为合法的JSON文本(方便HTTP传输) print(str_data)
{"name": "\u5f20\u4e09", "password": "123456", "male": true, "money": null}
import json # 需要导入JSON包 data = {'name': '张三', 'password': '123456', "male": True, "money": None} # 字典格式 str_data = json.dumps(data, indent=4, sort_keys=True, ensure_ascii=False) # 序列化,转化为合法的JSON文本(方便HTTP传输) print(str_data)
{ "male": true, "money": null, "name": "张三", "password": "123456" }
-
json.loads()
import json # 需要导入JSON包 data = {'name': '张三', 'password': '123456', "male": True, "money": None} # 字典格式 str_data1 = json.dumps(data, indent=4, sort_keys=True, ensure_ascii=False) # 序列化,转化为合法的JSON文本(方便HTTP传输) print(str_data1) print(type(str_data1)) str_data2 = json.loads(str_data1) print(str_data2) print(type(str_data2))
{ "male": true, "money": null, "name": "张三", "password": "123456" } <class 'str'> {'male': True, 'money': None, 'name': '张三', 'password': '123456'} <class 'dict'>
3. 脚本实例编写
- 打印1~100中所有奇数/偶数
- 计算1~100之间所有奇数的和
- 计算1~100之间所有偶数的和
二、接口测试
1. 内置模块
1.1 time
序号 | 函数及描述 |
---|---|
1 | time.altzone 返回格林威治西部的夏令时地区的偏移秒数。如果该地区在格林威治东部会返回负值(如西欧,包括英国)。对夏令时启用地区才能使用。 |
2 | [time.asctime(tupletime]) 接受时间元组并返回一个可读的形式为"Tue Dec 11 18:07:14 2008"(2008年12月11日 周二18时07分14秒)的24个字符的字符串。 |
3 | time.clock( ) 用以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用。 |
4 | [time.ctime(secs]) 作用相当于asctime(localtime(secs)),未给参数相当于asctime() |
5 | [time.gmtime(secs]) 接收时间戳(1970纪元后经过的浮点秒数)并返回格林威治天文时间下的时间元组t。注:t.tm_isdst始终为0 |
6 | [time.localtime(secs]) 接收时间戳(1970纪元后经过的浮点秒数)并返回当地时间下的时间元组t(t.tm_isdst可取0或1,取决于当地当时是不是夏令时)。 |
7 | time.mktime(tupletime) 接受时间元组并返回时间戳(1970纪元后经过的浮点秒数)。 |
8 | time.sleep(secs) 推迟调用线程的运行,secs指秒数。 |
9 | [time.strftime(fmt,tupletime]) 接收以时间元组,并返回以可读字符串表示的当地时间,格式由fmt决定。 |
10 | time.strptime(str,fmt='%a %b %d %H:%M:%S %Y') 根据fmt的格式把一个时间字符串解析为时间元组。 |
11 | time.time( ) 返回当前时间的时间戳(1970纪元后经过的浮点秒数)。 |
12 | time.tzset() 根据环境变量TZ重新初始化时间相关设置。 |
-
time.time()——获取时间戳
import time print(time.time())
1588929714.3305402
-
获取当前时间(格式化时间)
import time localtime = time.strftime('%Y-%m-%d %H:%M:%S') print(localtime)
20-05-08 17:26:05
-
round()
print(round(3.1415926, 2))
```python
3.14
import time
print(time.time()) # 打印当前时间戳
print(round(time.time())) # 打印无小数点的时间戳
print(round(time.time()*100)) # 等于1588932416.278496四舍五入后的值*100,即12位时间戳
1588932416.278496
1588932416
158893241628
1.2 calendar
序号 | 函数及描述 |
---|---|
1 | calendar.calendar(year,w=2,l=1,c=6) 返回一个多行字符串格式的year年年历,3个月一行,间隔距离为c。 每日宽度间隔为w字符。每行长度为21* W+18+2* C。l是每星期行数。 |
2 | calendar.firstweekday( ) 返回当前每周起始日期的设置。默认情况下,首次载入 calendar 模块时返回 0,即星期一。 |
3 |
calendar.isleap(year) 是闰年返回 True,否则为 False。>>> import calendar >>> print(calendar.isleap(2000)) True >>> print(calendar.isleap(1900)) False
|
4 | calendar.leapdays(y1,y2) 返回在Y1,Y2两年之间的闰年总数。 |
5 | calendar.month(year,month,w=2,l=1) 返回一个多行字符串格式的year年month月日历,两行标题,一周一行。每日宽度间隔为w字符。每行的长度为7* w+6。l是每星期的行数。 |
6 | calendar.monthcalendar(year,month) 返回一个整数的单层嵌套列表。每个子列表装载代表一个星期的整数。Year年month月外的日期都设为0;范围内的日子都由该月第几日表示,从1开始。 |
7 | calendar.monthrange(year,month) 返回两个整数。第一个是该月的星期几的日期码,第二个是该月的日期码。日从0(星期一)到6(星期日);月从1到12。 |
8 | calendar.prcal(year,w=2,l=1,c=6) 相当于 print calendar.calendar(year,w=2,l=1,c=6)。 |
9 | calendar.prmonth(year,month,w=2,l=1) 相当于 print calendar.month(year,month,w=2,l=1) 。 |
10 | calendar.setfirstweekday(weekday) 设置每周的起始日期码。0(星期一)到6(星期日)。 |
11 | calendar.timegm(tupletime) 和time.gmtime相反:接受一个时间元组形式,返回该时刻的时间戳(1970纪元后经过的浮点秒数)。 |
12 | calendar.weekday(year,month,day) 返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)。 |
-
获取某月日历
import calendar cal = calendar.month(2020, 5) print(cal)
May 2020 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
-
格式化日期
import time # 格式化成2016-03-20 11:45:39形式 print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) # 格式化成Sat Mar 28 22:24:24 2016形式 print(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())) # 将格式字符串转换为时间戳 a = "Sat Mar 28 22:24:24 2016" print(time.mktime(time.strptime(a, "%a %b %d %H:%M:%S %Y")))
2020-05-08 17:32:39 Fri May 08 17:32:39 2020 1459175064.0
1.3 json
函数 | 描述 |
---|---|
json.dumps | 将 Python 对象编码成 JSON 字符串 |
json.loads | 将已编码的 JSON 字符串解码为 Python 对象 |
- python 原始类型向 json 类型的转化对照表
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str, unicode | string |
int, long, float | number |
True | true |
False | false |
None | null |
- json 类型转换到 python 的类型对照表
JSON | Python |
---|---|
object | dict |
array | list |
string | unicode |
number (int) | int, long |
number (real) | float |
true | True |
false | False |
null | None |
1.4 random
-
返回值
import random # 生成第一个随机数 print(random.random()) # 生成第二个随机数 print(random.random())
0.9516361757935445 0.3494738700183079
-
常用方法
import random list = [1, 2, 3, 4, 5] print(random.randint(1, 10)) # 产生 1 到 10 的一个整数型随机数 print(random.random()) # 产生 0 到 1 之间的随机浮点数 print(random.uniform(1.1, 5.4)) # 产生 1.1 到 5.4 之间的随机浮点数,区间可以不是整数 print(random.choice(list)) # 从序列中随机选取一个元素 print(random.randrange(1, 100, 2)) # 生成从1到100的间隔为2的随机整数 random.shuffle(list) # 将序列list中的元素顺序打乱 print(list)
7 0.04950387613677654 3.5018207607321745 5 65 [3, 4, 5, 1, 2]
1.5 os常用方法
-
os.open()
import os # 打开文件 fd = os.open("foo.txt", os.O_RDWR | os.O_CREAT) # 关闭文件 os.close(fd) print("关闭文件成功!!")
-
os.system()
import os os.system('shutdown /s /t 300 /c "5分钟后自动关机"')
1.6 hashlib
import hashlib
md5 = hashlib.md5() # 创建hashlib的md5对象
md5.update('字符串'.encode('utf-8')) # 将字符串载入到md5对象中,获得md5算法加密
new_md5 = md5.hexdigest() # 通过hexdigest()方法,获得new_md5对象的16进制md5显示
print(new_md5)
cc4dd1da7e1a754534215f02fb9ba85d
import hashlib
new_md5 = hashlib.md5()
new_sha1 = hashlib.sha1()
new_sha256 = hashlib.sha256()
2. 第三方模块
2.1 requests
-
安装库
pip install requests
-
导入库
import requests
3. 组成
3.1 url
3.2 params的用法
-
参数类型
-
特点
import requests url = 'http://httpbin.org/get' data = { "name": "张三", "age": 22 } response = requests.get(url, params=data) # 自动对params中的内容进行编码,然后和url进行拼接,再发出请求,查看打印的name已经被编码了,如需解码可以用urllib.parse.unquote print(response.url)
http://httpbin.org/get?name=%E5%BC%A0%E4%B8%89&age=22
-
参数包含在url中
import requests response = requests.get("http://httpbin.org/get?name=zhangsan&age=22") print(response.text)
-
通过get方法传送参数
import requests url = 'http://httpbin.org/get?name=zhangsan&age=22' data = { "name": "zhangsan", "age": 22 } response = requests.get("http://httpbin.org/get", params=data) # print(response.text) print(response.url) if url == response.url: print("两个url是一致的") else: print("两个url不一致")
3.3 data
-
用于post请求
response = requests.post(url, data = data, headers=headers)
3.4 headers
-
模拟发送请求头(传送headers参数)
import requests headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded" } response = requests.get("http://httpbin.org/get", headers=headers) print(response.text)
3.5 cookies和session
-
cookies和session的用处
-
获取cookies信息
response.cookies
-
cookies在首次登录后获取到,后面可以放在requests提交时用
import requests headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded" } response = requests.get("http://httpbin.org/get", headers=headers, cookies=response.cookies) print(response.text)
-
构造session回话对象
session = requests.session()
4. get请求
-
无参数
常用于访问网址或无参数的请求url
import requests response = requests.get("www.baidu.com") print(response.headers) # 可查看响应头headers中Content-Type中的类型,从而决定以什么方法接收 print(response.text)
-
有参数
import requests url = 'http://httpbin.org/get' data = { "name": "张三", "age": 22 } response = requests.get(url, params=data) # 自动对params中的内容进行编码,然后和url进行拼接,再发出请求,查看打印的name已经被编码了,如需解码可以用urllib.parse.unquote print(response.url) print(response.headers) # 返回的是application/json,尽量用response.json() print(response.text) # 可能也不会报错,但是数据类型不是字典,是字符串 print(type(response.text)) print(response.json()) # 返回的是json,以json去接收,数据类型是字典,方便后续字典取值 print(type(response.json()))
{'Date': 'Sat, 09 May 2020 03:39:03 GMT', 'Content-Type': 'application/json', 'Content-Length': '378', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'} { "args": { "age": "22", "name": "\u5f20\u4e09" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Host": "httpbin.org", "User-Agent": "python-requests/2.22.0", "X-Amzn-Trace-Id": "Root=1-5eb625d7-7528eeb39efb718f94feac7e" }, "origin": "183.15.91.21", "url": "http://httpbin.org/get?name=\u5f20\u4e09&age=22" } <class 'str'> {'args': {'age': '22', 'name': '张三'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-5eb625d7-7528eeb39efb718f94feac7e'}, 'origin': '183.15.91.21', 'url': 'http://httpbin.org/get?name=张三&age=22'} <class 'dict'>
-
urllib.parse.quote编码(需要导入urllib.parse)
from urllib import parse # 或者import urllib.parse name = '张三' age = '22' url1 = 'http://httpbin.org/get?name=%E5%BC%A0%E4%B8%89&age=22' new_name = urllib.parse.quote(name) print(new_name) url2 = "http://httpbin.org/get?name=" + new_name + '&age=' + age print(url2) if url1 == url2: print("两个url是一致的") else: print("两个url不一致")
%E5%BC%A0%E4%B8%89 http://httpbin.org/get?name=%E5%BC%A0%E4%B8%89&age=22 两个url是一致的
-
urllib.parse.unquote解码
from urllib import parse # 或者import urllib.parse name = '%E5%BC%A0%E4%B8%89' # %E5%BC%A0%E4%B8%89即张三 print(urllib.parse.unquote(name))
张三
5. post请求
-
x-www-form-urlencoded
name=value&name2=value2=name3=value3
-
application/json
{"name1":"value1","name2":"value2"}
-
text/html
<!--?xml version="1.0"?--> <methodcall> <methodname>examples.getStateName</methodname> <params> <param> <value><i4>41</i4></value> </params> </methodcall>
6. 代理
-
代理的用法
proxies = { "http": "https://175.44.148.176:9000", "https": "https://183.129.207.86:14002" } response = requests.get("https://www.baidu.com/", proxies=proxies)
7. response属性
属性 | 描述 |
---|---|
response.text | 获取str类型(Unicode编码)的响应,即:url对应的页面内容 |
response.content | 获取bytes类型的响应 |
response.status_code | 获取响应状态码 |
response.headers | 获取响应头 |
response.request | 获取响应对应的请求 |
response.url | 获取请求url |
response.encoding | 从HTTP header中猜测的响应内容编码方式 |
-
response.encoding
import requests r = requests.get("http://www.baidu.com") print(r.text) # 未指定编码,打印中文时出现乱码
<!DOCTYPE html> <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>ç�¾åº¦ä¸�ä¸�ï¼�ä½ å°±ç�¥é��</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=ç�¾åº¦ä¸�ä¸� class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>æ�°é�»</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>å�°å�¾</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>è§�é¢�</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>è´´å�§</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>ç�»å½�</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">ç�»å½�</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">æ�´å¤�产å��</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>å
³äº�ç�¾åº¦</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使ç�¨ç�¾åº¦å��å¿
读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>����</a> 京ICP�030173� <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
> 指定encoding后可以解决乱码,utf-8是通用编码,如遇到中文乱码问题,也可以使用gbk2312
```python
import requests
r = requests.get("http://www.baidu.com")
r.encoding = 'utf-8'
# r.encoding = 'gbk2312'
print(r.text)
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
三、python进阶
1. 函数
1.1 规则
1.2 调用
# 定义函数
def printme1():
print("无参数,随便打印")
def printme2(strings):
"打印任何传入的字符串"
print(strings)
return # 未带表达式,不返回内容则不用写return,两者相同,所以返回的是None
def printme3(a):
"打印任何传入的字符串"
print(f"传进来的a的值为:{a}")
b = 2
c = a + b
return c # 带表达式,会返回a给调用方,经常这样表达:返回值=函数名(参数)
# 调用函数
printme1() # 无参数,不用填写参数,直接函数名()调用即可
printme2("调用函数!") # 有参数,需要提交参数,不然会报错
num = printme3(1)
print("返回的c的值为:{num}")
1.3 参数
1.3.1 必备参数
def printme(strings):
"打印任何传入的字符串"
print(strings)
printme()
TypeError: printme() missing 1 required positional argument: 'strings'
1.3.2 关键字参数
def printme(string1, string2):
"打印任何传入的字符串"
print(string1)
print(string2)
printme(string2="打赢我Java你就是第一", string1="php是世界上最好的语言!") # 会按照关键字传值,所以顺序不重要
php是世界上最好的语言!
打赢我Java你就是第一
1.3.3 默认参数
# 可写函数说明
def printinfo(name, age=35):
"打印任何传入的字符串"
print("Name: ", name)
print("Age ", age)
return
# 调用printinfo函数
printinfo(age=50, name="miki") # 传递了age,所以age取最后一次传递的值
printinfo(name="miki") # 没有传递age,但是age有默认值,所以不会报错
Name: miki
Age 50
Name: miki
Age 35
1.3.4 不定长参数
def printinfo(arg1, *arg2):
"打印任何传入的参数"
print(arg1)
for var in arg2:
print(var)
return
# 调用printinfo 函数
printinfo(10)
printinfo(70, 60, 50, 40) # 70传递给了arg1,剩下的60 50 40···全部传给了arg2
1.4 return
def test():
a = 1
return a
b = test() # 右侧调用test函数,因为函数返回了a的值,所以在左侧设置一个变量b接收函数返回的a,为了避免看起来混乱,所以尽量改个名来接收返回的值
print(b) # 此时b的值就是a,也就是1
1.5 全局变量和局部变量
total = 0 # 这是一个全局变量
# 可写函数说明
def sum(arg1, arg2):
# 返回2个参数的和."
total = arg1 + arg2 # total在这里是局部变量.
print("函数内是局部变量 : ", total)
return total
# 调用sum函数
sum(10, 20)
print("函数外是全局变量 : ", total)
函数内是局部变量 : 30
函数外是全局变量 : 0
2. file读写
-
mode参数:
模式 描述 t 文本模式 (默认)。 x 写模式,新建一个文件,如果该文件已存在则会报错。 b 二进制模式。 + 打开一个文件进行更新(可读可写)。 U 通用换行模式(不推荐)。 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 r+ 打开一个文件用于读写。文件指针将会放在文件的开头。 rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 -
file对象
序号 方法及描述 1 file.close()关闭文件。关闭后文件不能再进行读写操作。 2 file.flush()刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。 3 file.fileno()返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。 4 file.isatty()如果文件连接到一个终端设备返回 True,否则返回 False。 5 file.next()返回文件下一行。 6 [file.read(size])从文件读取指定的字节数,如果未给定或为负则读取所有。 7 [file.readline(size])读取整行,包括 "\n" 字符。 8 [file.readlines(sizeint])读取所有行并返回列表,若给定sizeint>0,则是设置一次读多少字节,这是为了减轻读取压力。 9 [file.seek(offset, whence])设置文件当前位置 10 file.tell()返回文件当前位置。 11 [file.truncate(size])截取文件,截取的字节通过size指定,默认为当前文件位置。 12 file.write(str)将字符串写入文件,返回的是写入的字符长度。 13 file.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。
3. 异常处理
3.1 try except else finally
try:
<语句> #运行别的代码
except BaseException: # BaseException为所有异常的基类,还有很多异常,RuntimeError、ValueError··
<语句> #如果引发了异常,执行这,不执行else
else:
<语句> #如果没有异常发生,就执行else,不会执行except
finally:
<语句> #不管有无报错,都会执行这条语句
a = 1
try:
print(b) # 尝试打印b,但是b不存在,所以会报错
except Exception as e: # 在这捕获了异常,且打印出异常,代码还会往下执行,不捕获的话走到print(b)就会终止运行
print(e)
else: #
print(a)
finally:
print("不管有无报错,都会执行这条语句")
<class 'Exception'>
不管有无报错,都会执行这条语句
3.2 try except else
try:
正常的操作
except:
发生异常,执行这块代码
else:
如果没有异常执行这块代码
3.3 try finally
try:
<语句>
finally:
<语句> #退出try时总会执行
3.4 触发异常
# 定义函数
def mye(level):
if level < 1:
raise(Exception, "Invalid level!")
# 触发异常后,后面的代码就不会再执行
try:
mye(0) # 触发异常
except Exception:
print(Exception, "Invalid level!") # 这里捕获异常且打印异常
else:
print(2)
<class 'Exception'> Invalid level!
3.5 用户自定义异常
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
try:
raise Networkerror("Bad hostname")
except Networkerror as e:
print(e)
4. 面向对象
4.1 类
-
创建类
class ClassName: '类的帮助信息' #类文档字符串 class_suite #类体
class Employee: '所有员工的基类' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print("Total Employee %d" % Employee.empCount) def displayEmployee(self): print("Name : ", self.name, ", Salary: ", self.salary)
-
self代表类的实例,而非类
class Test: def prt(self): print(self) print(self.__class__) print("我是打印") t = Test() # 实例化对象,无参数传递,函数如设置了参数,则需要在此传递 t.prt() # 通过类Test()调用类里的方法,等于Test().prt(),只是把Test()传给了t
<__main__.Test object at 0x000001DC4B453648> <class '__main__.Test'> 我是打印
4.2 实例化对象与访问属性
-
创建实例对象
t1 = man('zhangsan', 24) t2 = man('lisi', 25)
-
初始化方法
def __init__(self, name, age): # 实例化对象时传递name和age给self.name和self.age,后续类中的任何方法需要调用name时,输入self.name或self.age即可访问,直接类.类变量和这有一定的区别,见下文4.5章节中解释 self.name = name self.age = age
-
调用方法和变量
t1 = man('zhangsan', 24) t.print1() # 调用print1方法,即类名+类中的方法名 t1.age # 调用类中的age变量
class man: def __init__(self, name, age): self.name = name self.age = age def print1(self): print("我是负责打印的~") print(self.name) def print2(self): print("我也是负责打印的~") print(self.age) t = man('zhangsan', 24) # 实例化对象给t,后续t就是类,只用用t调用方法或变量 t.print1() # 通过类调用类里面定义的方法(函数和方法的区别见下面4.3章节中描述) t.print2() pring(t.name) # 通过类调用类变量name和age pring(t.age)
4.3 类方法和Python函数的区别
-
所处位置不同
-
定义的方式不同
def test(): pringt("我是打印") test() # 函数调用,无参数时不用传递参数,有参数时必须传递参数
class Test(object): def test(self): pringt("我是打印") t = Test() # 实例化对象 t.test() # 方法调用是通过对象.方法调用
-
调用的方式不一致
t = Test() # 实例化对象 t.test() # 方法调用是通过对象.方法调用
4.4 深入理解实例化对象
class 人(object):
def __init__(self,性别,年龄,姓名等等):
self.性别=性别
self.年龄=年龄
self.姓名=姓名
def 吃饭(self,要吃的菜品):
print(要吃的菜品)
def 喝水(self,要喝的水)
print(要喝的水)
def 睡觉(self)
pass
小明=人(男,20岁,小明)
小明.吃饭('青椒土豆丝')
小明.喝水('快乐肥宅水')
小明.睡觉()
4.5 深入理解类方法、静态方法、类变量和实例变量
-
类方法
class Test(object): @classmethod # 使用@classmethod修饰符 def test(cls): pass Test.test() # 直接使用类名调用test方法
class Test(object): def test(self): pass t = Test() # 需要实例化,通过实例化对象调用test方法 t.test()
-
静态方法
class Test(object): @classmethod # 使用@classmethod修饰符 def test1(cls): print("我是类方法") def test2(self): print("我也是类方法") @staticmethod def test3(): print("我是静态方法") # Test是叫类名,Test()是叫类,要区分开来 Test.test1() # 直接使用类名调用类方法test1() t = Test() # 实例化对象,用t和Test()是一样的,只是为了书写和方便会把类名传给一个值 t.test2() # 通过类的实例对象调用类的方法test2() t.test3() # 通过类的实例对象调用类中静态方法test3() Test.test3() # 支持通过类名直接调用静态方法
-
类变量
# Test()是表达类,Test是类名, # 在常规的类中,只需记住类名调用类变量,类(实例对象)调用类方法 class Test(object): a = 10 # 类变量 def test(self): print(Test.a) # 通过类名调用类变量 t.a = 20 # 实例只能访问类变量,不能修改类变量a的值 print(t.a) # 通过实例调用类变量 print(Test.a) # 这里再次打印的还是a = 10 t = Test() # 需要实例化,通过实例对象调用test方法 t.test()
10 20 10
class Test(object): a = 10 # 类变量 def test(self): print(Test.a) # 通过类名调用类变量 print(t.a) # 通过实例调用类变量 Test.a = 20 # 实例调用类变量,且重新赋值20 print(Test.a) # 实例再次调用类变量查看a的值 print(t.a) # 因为a已经被修改成了20,所以调用的时候都会打印20 t = Test() # 需要实例化,通过实例对象调用test方法 t.test()
10 10 20 20
-
实例变量
class man(object): def __init__(self, name, age): self.name = name self.age = age def print1(self): print("我是负责打印的~") print(self.name) def print2(self): print("我也是负责打印的~") print(self.age) t = man("zhangsan", 24) # 实例化对象,且传递变量到了init方法中,self.name接收了name的值,self.name='zhangsan'即实例变量,后面类中调用self.name即可
5. mysql
5.1 数据库连接与查询
import MySQLdb
# 打开数据库连接
db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8')
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# 使用execute方法执行SQL语句
cursor.execute("SELECT VERSION()")
# 使用 fetchone() 方法获取一条数据
data = cursor.fetchone()
# 关闭数据库连接
db.close()
5.2 数据库更新操作
import MySQLdb
# 打开数据库连接
db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8')
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 更新语句
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')
try:
# 执行SQL语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
except:
# 发生错误时回滚
db.rollback()
# 关闭数据库连接
db.close()
5.3 删除操作
import MySQLdb
# 打开数据库连接
db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8')
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 删除语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > %s" % (20)
try:
# 执行SQL语句
cursor.execute(sql)
# 提交修改
db.commit()
except:
# 发生错误时回滚
db.rollback()
# 关闭连接
db.close()
6. 多线程
6.1 线程模块
6.2 创建多线程
-
方式一:函数式,调用thread模块中的_start_new_thread()函数来产生新线程。
_thread.start_new_thread ( function, args[, kwargs] ) # function - 线程函数 # args - 传递给线程函数的参数,他必须是个tuple类型 # kwargs - 可选参数
import _thread import time # 为线程定义一个函数 def print_time(threadName, delay): count = 0 while count < 5: time.sleep(delay) count += 1 print("%s: %s" % (threadName, time.ctime(time.time()))) # 创建两个线程 try: _thread.start_new_thread(print_time, ("Thread-1", 2,)) _thread.start_new_thread(print_time, ("Thread-2", 4,)) except: print("Error: 无法启动线程") while 1: pass
Thread-1: Sun May 10 18:37:08 2020 Thread-2: Sun May 10 18:37:10 2020 Thread-1: Sun May 10 18:37:10 2020 Thread-1: Sun May 10 18:37:12 2020 Thread-2: Sun May 10 18:37:14 2020 Thread-1: Sun May 10 18:37:14 2020 Thread-1: Sun May 10 18:37:16 2020 Thread-2: Sun May 10 18:37:18 2020 Thread-2: Sun May 10 18:37:22 2020 Thread-2: Sun May 10 18:37:26 2020
-
方式二:使用Threading模块创建线程,直接从threading.Thread继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,即它调用了线程的 run() 方法:
import threading import time exitFlag = 0 class myThread(threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print("开始线程:" + self.name) print_time(self.name, self.counter, 5) print("退出线程:" + self.name) def print_time(threadName, delay, counter): while counter: if exitFlag: threadName.exit() time.sleep(delay) print("%s: %s" % (threadName, time.ctime(time.time()))) counter -= 1 # 创建新线程 thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # 开启新线程 thread1.start() thread2.start() thread1.join() thread2.join() print("退出主线程")
开始线程:Thread-1 开始线程:Thread-2 Thread-1: Sun May 10 18:43:46 2020 Thread-2: Sun May 10 18:43:47 2020 Thread-1: Sun May 10 18:43:47 2020 Thread-1: Sun May 10 18:43:48 2020 Thread-2: Sun May 10 18:43:49 2020 Thread-1: Sun May 10 18:43:49 2020 Thread-1: Sun May 10 18:43:50 2020 退出线程:Thread-1 Thread-2: Sun May 10 18:43:51 2020 Thread-2: Sun May 10 18:43:53 2020 Thread-2: Sun May 10 18:43:55 2020 退出线程:Thread-2 退出主线程
6.3 线程锁
import threading
import time
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("开启线程: " + self.name)
# 获取锁,用于线程同步
threadLock.acquire()
print_time(self.name, self.counter, 3)
# 释放锁,开启下一个线程
threadLock.release()
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
threadLock = threading.Lock()
threads = []
# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 开启新线程
thread1.start()
thread2.start()
# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)
# 等待所有线程完成
for t in threads:
t.join()
print ("退出主线程")
开启线程: Thread-1
开启线程: Thread-2
Thread-1: Sun May 10 18:47:12 2020
Thread-1: Sun May 10 18:47:13 2020
Thread-1: Sun May 10 18:47:14 2020
Thread-2: Sun May 10 18:47:16 2020
Thread-2: Sun May 10 18:47:18 2020
Thread-2: Sun May 10 18:47:20 2020
退出主线程
7. 正则
7.1 re.match()和re.search()
re.match(pattern, string, flags=0)
# pattern 匹配的正则表达式
# string 要匹配的字符串
# flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
匹配对象方法 | 描述 |
---|---|
group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
import re
line = "Cats are smarter than dogs"
# .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I)
if matchObj:
print("matchObj.group() : ", matchObj.group())
print("matchObj.group(1) : ", matchObj.group(1))
print("matchObj.group(2) : ", matchObj.group(2))
else:
print("No match!!")
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
import re
line = "Cats are smarter than dogs"
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
print ("match --> matchObj.group() : ", matchObj.group())
else:
print ("No match!!")
matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
print ("search --> matchObj.group() : ", matchObj.group())
else:
print ("No match!!")
No match!!
search --> matchObj.group() : dogs
7.2 re.sub()
re.sub(pattern, repl, string, count=0, flags=0)
# pattern : 正则中的模式字符串
# repl : 替换的字符串,也可为一个函数
# string : 要被查找替换的原始字符串
# count : 可选参数,模式匹配后替换的最大次数,默认 0 表示替换所有的匹配
# flags : 可选参数,编译时用的匹配模式,数字形式
phone = "2004-959-559 # 这是一个电话号码"
# 删除注释
num = re.sub(r'#.*$', "", phone)
print("电话号码 : ", num)
# 移除非数字的内容
num = re.sub(r'\D', "", phone)
print("电话号码 : ", num)
电话号码 : 2004-959-559
电话号码 : 2004959559
7.3 re.compile()
re.compile(pattern[, flags])
# pattern : 一个字符串形式的正则表达式
# flags 可选,表示匹配模式,比如忽略大小写,多行模式等
# re.I 忽略大小写:
# re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
# re.M 多行模式
# re.S 即为' . '并且包括换行符在内的任意字符(' . '不包括换行符)
# re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
# re.X 为了增加可读性,忽略空格和' # '后面的注释
7.4 re.findall()
re.findall(string[, pos[, endpos]])
# string 待匹配的字符串
# pos 可选参数,指定字符串的起始位置,默认为0
# endpos 可选参数,指定字符串的结束位置,默认为字符串的长度
import re
pattern = re.compile(r'\d+') # 查找数字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
print(result1)
print(result2)
['123', '456']
['88', '12']
7.5 正则表达式模式
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[...] | 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' |
[^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
re* | 匹配0个或多个的表达式。 |
re+ | 匹配1个或多个的表达式。 |
re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
re{ n} | 匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。 |
re{ n,} | 精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。 |
re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
a| b | 匹配a或b |
(re) | 匹配括号内的表达式,也表示一个组 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (...), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#...) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。 |
(?> re) | 匹配的独立模式,省去回溯。 |
\w | 匹配数字字母下划线 |
\W | 匹配非数字字母下划线 |
\s | 匹配任意空白字符,等价于 [\t\n\r\f]。 |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9]。 |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
\n, \t, 等。 | 匹配一个换行符。匹配一个制表符, 等 |
\1...\9 | 匹配第n个分组的内容。 |
\10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
7.6 正则表达式修饰符
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
7.7 正则表达式实例
实例 | 描述 |
---|---|
python | 匹配 "python". |
实例 | 描述 |
---|---|
[Pp]ython | 匹配 "Python" 或 "python" |
rub[ye] | 匹配 "ruby" 或 "rube" |
[aeiou] | 匹配中括号内的任意一个字母 |
[0-9] | 匹配任何数字。类似于 [0123456789] |
[a-z] | 匹配任何小写字母 |
[A-Z] | 匹配任何大写字母 |
[a-zA-Z0-9] | 匹配任何字母及数字 |
[^aeiou] | 除了aeiou字母以外的所有字符 |
[^0-9] | 匹配除了数字外的字符 |
实例 | 描述 |
---|---|
. | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式 |
\d | 匹配一个数字字符。等价于 [0-9] |
\D | 匹配一个非数字字符。等价于 [^0-9] |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v] |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v] |
\w | 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]' |
\W | 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]' |