测试基础 测试基础-Python 篇 基础②

耿晓 · 2023年02月14日 · 4293 次阅读

再梳理一遍 Python 系列知识点,夯实基础,无他,唯手熟尔

Python 系列总结都是我自己平时的学习笔记,如果有不正确的地方,希望各位佬儿哥指正纠偏🤗

常用模块-math

import math

  • print(math.ceil(3.14)) # 取大于等于 x 的最小整数
  • print(math.fabs(-3)) # 取绝对值
  • print(math.floor(3.14)) # 取小于等于 x 的最大整数
  • print(math.fsum([1,2,3])) # 求和
  • print(math.pow(3,4)) #3 的 4 次方 等价于 3**4
  • print(math.sqrt(3)) # 开平方,3 的平方根

常用模块-random

import random

  • print(random.random()) # 返回 [0.0,1.0) 之间的浮点数
  • print(random.randint(10,20)) # 生成 10 到 20 之间的一个随机整数,也就是 [10,20]
  • print(random.randrange(10,20)) # 生成 10 到 20 之间的一个随机整数,也就是 [10,20)
  • print(random.uniform(10,20)) # 生成 10 到 20 之间的一个随机浮点数,也就是 [10,20]
  • print(random.choice([10,20,30])) # 随机从列表选择一个数
  • print(random.choices([10,20,30],k=2)) # 随机从列表选择 k 个数,返回列表形式,取出放回方式,意思是取出的数可以重复
  • print(random.sample(a1,3)) # 随机从列表选 k 个数,返回列表形式,取出不放回方式,意思是取出的数不会重复
  • random.shuffle(a1) # 洗牌,随机变换列表顺序

常用模块-json

  • 用 loads() 函数读取 JSON
    要将包含 JSON 数据的字符串转换为 Python 的值,就将它传递给 json.loads() 函数;

  • 用 dumps() 函数写出 JSON
    将一个 python 值转换成 JSON 格式的数据字符串,就用 json.dumps() 函数;

import json

d = {'name':'Tom','age':26}
j = json.dumps(d)
d2 = json.loads(j)

print(d)
print(type(d))
print()
print(j)
print(type(j))
print()
print(d2)
print(type(d2))
-------------------------------------
{'name': 'Tom', 'age': 26}
<class 'dict'>

{"name": "Tom", "age": 26}
<class 'str'>

{'name': 'Tom', 'age': 26}
<class 'dict'>

常用模块-time

  • round() 第一个参数是要处理的数字,第二个可选参数为四舍五入保留的位数,若不传如第二个参数,则默认四舍五入到最近的整数
import time

n = time.time()
print(n)
n1 = round(n,3)
print(n1)
------------------------
1675392067.2974966
1675392067.297
  • time.time() ---获取当前时间戳:1675392067.2974966
  • time.sleep(sec) ---睡眠 sec 秒

常用模块-datetime()

  • datetime 模块有自己的 datetime 数据类型:
  • datetime 的一些方法:
import datetime

dt = datetime.datetime.now()

print(dt)
print('dt.year:' + str(dt.year) + '---type:' + str(type(dt.year)))
print('dt.month:' + str(dt.month) + '---type:' + str(type(dt.month)))
print('dt.day:' + str(dt.day) + '---type:' + str(type(dt.day)))
print('dt.hour:' + str(dt.hour) + '---type:' + str(type(dt.hour)))
print('dt.minute:' + str(dt.minute) + '---type:' + str(type(dt.minute)))
print('dt.second:' + str(dt.second) + '---type:' + str(type(dt.second)))
----------------------------------------------------------------------------------------------------------
2023-02-03 11:00:08.205691
dt.year:2023---type:<class 'int'>
dt.month:2---type:<class 'int'>
dt.day:3---type:<class 'int'>
dt.hour:11---type:<class 'int'>
dt.minute:0---type:<class 'int'>
dt.second:8---type:<class 'int'>
  • Unix 时间戳可以通过 datetime.datetime.fromtimestamp() 转换为 datetime 对象
import datetime
import time

now = time.time()
date = datetime.datetime.fromtimestamp(now)

print(now)
print(date)
----------------------------------------------------------------------------
1675393953.0860312
2023-02-03 11:12:33.086031
  • datetime 对象可以用比较操作符进行比较,后面的 datetime 对象时"更大"的值
import datetime
import time

d1 = datetime.datetime.now()
time.sleep(1)
d2 = datetime.datetime.now()

print(d2>d1)
-----------------------------------------------
True
  • datetime 对象的差的数据类型是'timedelta'
import datetime
import time

d1 = datetime.datetime.now()
time.sleep(1)
d2 = datetime.datetime.now()
d3 = d2 -d1

print(d3)
print(type(d3))
------------------------------------------------
0:00:01.002022
<class 'datetime.timedelta'>
  • 要创建 timedelta 对象,就用 datetime.timedelta() 函数
import datetime

dt = datetime.timedelta(days=11,hours=10,minutes=9,seconds=8)

print(dt)
print(type(dt))
print(dt.days)
print(dt.seconds) # 天不参与计算,10*60*60 + 9*60 + 8 = 36548
print(dt.total_seconds()) # 11*24*60*60 + 10*60*60 + 9*60 + 8 = 986948
print(str(dt))
---------------------------------------------------------------------------------------------------------
11 days, 10:09:08
<class 'datetime.timedelta'>
11
36548
986948.0
11 days, 10:09:08
  • 算数运算符可以用于对 datetime 值进行日期运算,例如,要计算今天之后 1000 天的日期;
import datetime

dt = datetime.datetime.now()
print(dt)

thounsandDays = datetime.timedelta(days=1000)
print(thounsandDays)

print(dt + thounsandDays)
------------------------------------------------------------------------------
2023-02-06 14:20:46.265084
1000 days, 0:00:00
2025-11-02 14:20:46.265084

常用模块-logging

Logging 库是非常常用的记录日志库,通过 logging 模块存储各种格式的日志,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;

  • 日志级别
    DEBUG --logging.debug()
    INFO --logging.info()
    WARNING --logging.warning()
    ERROR --logging.error()
    CRITICAL --logging.critical()

  • 使用日志模块

import logging

logging.basicConfig(format='%(levelname)s %(asctime)s: %(message)s: %(module)s',level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')
-----------------------------------------------------------------------------------------------------
DEBUG 2023-02-07 17:04:37,473: This message should appear on the console: logging_practice
INFO 2023-02-07 17:04:37,473: So should this: logging_practice
WARNING 2023-02-07 17:04:37,473: And this, too: logging_practice
  • 将日志记录到文件-logging.basicConfig() 函数接受 filename 关键字。
import logging

logging.basicConfig(filename='myProgramLog',format='%(levelname)s %(asctime)s: %(message)s: %(module)s',level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')
  • 禁用日志 只要向 logging.disable() 传入一个日志级别,他就会禁止该级别和更低级别的所有日志消息; logging.disable(logging.CRITICAL) 加在代码前面即可隐藏日志信息(接近 import.logging 的位置更容易找到和管理);
import logging

logging.disable(logging.CRITICAL)

logging.basicConfig(filename='myProgramLog',format='%(levelname)s %(asctime)s: %(message)s: %(module)s',level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')

常用模块-threading

  • 要得到单独的线程,首先要调用 threading.Thread() 函数,生成一个 Thread 对象。
import time
import threading

print('Start of program.')

def takeANap():
    time.sleep(5)
    print('Wake up!')

threadObj = threading.Thread(target=takeANap)
threadObj.start()
print('End of program')
----------------------------------------------------------------------------
Start of program.
End of program
Wake up!

注意:target 参数名后传的是方法名,不加 (),因为此处并不是调用。

  • 向线程的目标函数传递参数 常规参数可以作为一个列表,传递给 threading.Thread() 中的 args 关键字参数。关键字参数可以作为一个字典,传递给 threading.Thread() 中的 kwargs 关键字参数:
import threading

l = [1,2,3,4]

def a(*args):
    for _ in args:
        print(_)

thread_a = threading.Thread(target=a,args=l)
thread_a.start()
------------------------------------------------------------------------
1
2
3
4
import threading

d = {'name': 'Tom', 'age': 18}

def b(**kwargs):
    for k, v in kwargs.items():
        print(str(k) + ':' + str(v))

thread_b = threading.Thread(target=b, kwargs=d)
thread_b.start()
----------------------------------------------------------------------------
name:Tom
age:18
  • 并发问题需要注意的是:为了避免并发问题,绝不让多个线程读取或写入相同变量。当创建一个新的 Thread 对象时,要确保其目标函数只使用该函数中的局部变量。

  • 线程阻塞-thread.join()
    thread.join() 方法的作用是阻塞当前线程,直到调用 join() 方法的线程结束。也就是说,如果你有多个线程并希望在其中一个线程结束之后再继续执行,则可以使用 join() 方法。

# 不使用join,两个线程并行运行
import time
import threading

def a():
    time.sleep(1)
    print('我是a:1/3')
    time.sleep(1)
    print('我是a:2/3')
    time.sleep(1)
    print('我是a:3/3')

def b():
    print('我是b:1/2')
    print('我是b:2/2')

thread_a = threading.Thread(target=a)
thread_b = threading.Thread(target=b)

thread_a.start()
thread_b.start()
-------------------------------------------------------------
我是b1/2
我是b2/2
我是a1/3
我是a2/3
我是a3/3
# 使用join,线程b需要等线程a运行完后再运行
import time
import threading

def a():
    time.sleep(1)
    print('我是a:1/3')
    time.sleep(1)
    print('我是a:2/3')
    time.sleep(1)
    print('我是a:3/3')

def b():
    print('我是b:1/2')
    print('我是b:2/2')

thread_a = threading.Thread(target=a)
thread_b = threading.Thread(target=b)

thread_a.start()
thread_a.join()
thread_b.start()
--------------------------------------------------------------
我是a1/3
我是a2/3
我是a3/3
我是b1/2
我是b2/2
# join()方法可以自定义timeout参数,意为最长暂用CPU时间,如果不设置的话就永远等待;
import time
import threading

def a():
    time.sleep(1)
    print('我是a:1/3')
    time.sleep(1)
    print('我是a:2/3')
    time.sleep(1)
    print('我是a:3/3')

def b():
    print('我是b:1/2')
    print('我是b:2/2')

thread_a = threading.Thread(target=a)
thread_b = threading.Thread(target=b)

thread_a.start()
thread_a.join(timeout=2)
thread_b.start()
-------------------------------------------------------------
我是a1/3
我是a2/3
我是b1/2
我是b2/2
我是a3/3

深拷贝浅拷贝

不可变数据类型(如整型,字符串等)在 Python 中只是拷贝了值,因此在执行浅拷贝时实际上是创建了一个新的副本,而不是拷贝引用。因此,对原数据的更改不会影响到拷贝后的数据。

import copy

a = 1000
b = a
c = copy.copy(a)
d = copy.deepcopy(a)

print(a, b, c, d)
print(id(a), id(b), id(c), id(d))

a += 1

print(a, b, c, d)
print(id(a), id(b), id(c), id(d))

----------------------------------------------
1000 1000 1000 1000
2518799374640 2518799374640 2518799374640 2518799374640
1001 1000 1000 1000
2518805613936 2518799374640 2518799374640 2518799374640

对于可变数据类型,浅拷贝只拷贝第一层中的引用,深拷贝在拷贝时,会逐层进行拷贝,直到所有的引用都是不可变对象为止。

import copy

a = [1, 2, [3, 4]]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
e = a.copy()
f = a[:]

print(a, b, c, d, e,f)
print(id(a), id(b), id(c), id(d), id(e),id(f))
print()

a.append(5)

print(a, b, c, d, e,f)
print(id(a), id(b), id(c), id(d), id(e),id(f))
print()

a[2].append(6)
print(a, b, c, d, e,f)
print(id(a), id(b), id(c), id(d), id(e),id(f))
----------------------------------------------------
[1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]]
2213595331584 2213595331584 2213595362304 2213595356992 2213595443008 2213595442368

[1, 2, [3, 4], 5] [1, 2, [3, 4], 5] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]] [1, 2, [3, 4]]
2213595331584 2213595331584 2213595362304 2213595356992 2213595443008 2213595442368

[1, 2, [3, 4, 6], 5] [1, 2, [3, 4, 6], 5] [1, 2, [3, 4, 6]] [1, 2, [3, 4]] [1, 2, [3, 4, 6]] [1, 2, [3, 4, 6]]
2213595331584 2213595331584 2213595362304 2213595356992 2213595443008 2213595442368

  • Python 有多种方式实现浅拷贝,copy 模块的 copy 函数 ,对象的 copy 函数 ,工厂方法,切片等。
  • 赋值符号"=":如果是可变类型,就是引用传递;如果是不可变类型,就是值传递。
  • 浅拷贝的优点:拷贝速度快,占用空间少,拷贝效率高。
  • 因为浅拷贝不能解决嵌套问题,所以引出了深拷贝,深拷贝会遍历并拷贝 items 里所有的内容 - 包括他嵌套的子列表;

对象的可哈希性

  • 不可变的内置类型都是可哈希的,比如 str、int、float、frozenset
  • 可变的内置类型都是不可以哈希的,比如 list、dict
  • 对于不可变容器类型(tuple、frozenset),仅当他的所有成员都不可变时,他自身才是可哈希的
  • 用户定义的类型默认都是可哈希的

注意:只有可哈希对象才能被放进集合或者作为字典的键

sorted() 函数

sorted 函数是 Python 内置函数,用于对可迭代对象进行排序,并返回一个新的列表。
注意:sorted 函数不会改变原来的可迭代对象,而是返回一个新的列表。如果需要改变原来的可迭代对象,可以使用 sort 方法,但它只能用于列表。
参数:

  • iterable:可以是列表、元组、字典等任意可迭代对象。
  • key:一个函数,用于提取每个元素的排序关键字。默认为 None,表示按元素本身的顺序进行排序。
  • reverse:是否按降序排列,默认为 False,表示按升序排列。

enumerate() 函数

enumerate() 适用于任何"可迭代对象",可以用于列表、元祖、字典、字符串等。

def enumerate_func():
    names = ['lily','wenwen','tom']
    for index, s in enumerate(names,start=1):
        print(index,s)
---------------------------------------------
1 lily
2 wenwen
3 tom

如果不指定 start 参数,则 index 从 0 开始

测试基础-Python 篇 基础③

共收到 0 条回复 时间 点赞
耿晓 测试基础-Python 篇 基础① 中提及了此贴 02月14日 17:11
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册