Python 用法总结(持续更新) 主要记录一下工作中用到python的总结吧 相当于一个大杂烩了。
Python 用法总结(持续更新)
文章目录
前言
主要记录一下工作中用到python的总结吧 相当于一个大杂烩了。
一、Python中global的用法
Python中的全局变量一般定义在函数外部,如果需要在函数内部使用全局变量的话,就需要用global关键字了。
vax = 1
def add(x):
return x+vax
add(2)
#最后返回为3
在函数中,可以访问全局变量,并使用其值。但是如果不对变量进行global宣言,则不会改变全局变量的值。如下图
如果需要在函数中改变全局变量的值,需要在函数中先定义global,用例如下。
使用global的例子(结合logging模块)
场景:在代码中我需要请求一个token,而token是一小时刷新一次,这种情况下就需要global了。
global:global关键字用来在函数或其他局部作用域中使用全局变量。
顺便提一下 nonlocal,nonlocal用于在嵌套函数中修改外部(非全局)变量的值。
main.py
import time
import logging
log_format = "%(asctime)s - %(levelname)s - %(message)s"
logging.basicConfig(level=logging.DEBUG,format=log_format,handlers=[logging.FileHandler('log1.log',encoding='utf-8'), logging.StreamHandler()])
#logging.basicConfig(level=logging.DEBUG)
# 保存最近一次获取的 token
current_token = None
token_expiration_time = 0 # Token 过期时间戳
test =10
def gettokenfunction():
global test
test+=1
return test
def getoken():
global current_token, token_expiration_time,test
# 如果当前 token 不存在或已过期,则重新获取
if current_token is None or time.time() > token_expiration_time:
current_token = gettokenfunction() # 调用获取 token 的函数
logging.info(f"token had renew,current_token:{current_token}")
token_expiration_time = time.time() + 3600 # 设置 token 过期时间(1小时后)
else:
logging.info("token not crash")
return current_token
def getvid():
token = getoken() # 获取或刷新 token
# 继续执行 getvid 的逻辑,使用获取到的 token
# ...
return token
test.py
import main # 导入包含 getoken 和 getvid 的模块
import time
import logging
log_format = "%(asctime)s - %(levelname)s - %(message)s"
logging.basicConfig(level=logging.DEBUG,format=log_format,handlers=[logging.FileHandler('log1.log',encoding='utf-8'), logging.StreamHandler()])
while True:
# 使用 getvid 函数
video_data = main.getvid()
logging.info("使用getvid函数")
print(video_data)
time.sleep(5)
通过这两个文件,我们就能实现上述场景了。
logging
其中还用到了logging模块,logging在工程中作用真的非常大,可以用它定位信息等,简单配置的话如下:
import logging
log_format = "%(asctime)s - %(levelname)s - %(message)s"
logging.basicConfig(level=logging.DEBUG,format=log_format,handlers=[logging.FileHandler('log1.log',encoding='utf-8'), logging.StreamHandler()])
logging.info("11111")
logging.debug("11111")
logging.warning('debugu1111')
[logging.FileHandler(‘log1.log’,encoding=‘utf-8’), logging.StreamHandler()]的作用在于即把log保存在指定文件里,又将其输出到控制台。
logging是python自带的模块,比较原始,很多人在使用logru作为日志模块,后续学习一下logru。
二、Typing中Optional及Pydantic中BaseModel
1.Typing中Optional
Python Typing Optional(类型提示中的 Optional)是 Python 3.5 开始支持官方类型提示的可选类型之一。
Optional 最常用的场景就是表示函数参数的默认值,通过这种方式可以让函数参数既可以接受一个特定类型的值,也可以默认为 None。
简单来说,单独的类型注释只能表示一种,比如说a:int,但是如果是a:int或None,这种情况,就可以用
a:Optional[int]来表示,这就表示可能是int,也可能是None
例如:
def test(aa:Optional[int] = 1):
return aa
print(test(0.1),type(test(0.1)))
#0.1
print(test())
#1
例子中定义函数test,其参数aa可选为int,默认为1,即如果不传参数那aa值为1。如果传的话,输出即为0.1。
由于python没有强制,虽然注释为int类型,你还是可以传入其他类型。
2.Pydantic中BaseModel
pydantic库是一种常用的用于数据接口schema定义与检查的库。
通过pydantic库,我们可以更为规范地定义和使用数据接口,这对于大型项目的开发将会更为友好。
结合Optional,在构建Fastapi接口时,BaseModel与Optinal非常好用
from typing import Optional, Union
from pydantic import BaseModel
class Modelinput(BaseModel):
sim_th: Optional[float] = 0.8
alist: Optional[list] = []
@app.post("/test")
async def completions(data: Modelinput):
data = data.dict()
logger.info(
f'data:{data}'
)
上述是一个fastapi构建,接收data数据,并且data数据按照Modelinput解析。
在你的 FastAPI 路由 completions 中,你将 data 参数的类型指定为 Modelinput。这意味着 FastAPI 会尝试从 HTTP 请求中提取并验证请求体中的数据,并将其转换为一个 Modelinput 对象。如果请求体中的数据不满足 Modelinput 的定义,FastAPI 会返回一个验证错误响应。
但如果在普通函数中,这样写则没用
from pydantic import BaseModel
from typing import Optional, Union
class Modelinput(BaseModel):
sim_th: Optional[float] = 0.8
alist: Optional[list] = []
def function(data:Modelinput):
return data
data = {"sim_th":0.6}
print(function(data))
在你的代码中,你定义了一个名为 Modelinput 的 Pydantic 模型,该模型用于验证和处理输入数据。然而,在你调用 function(data) 时,你传递了一个字典 data,而不是一个 Modelinput 对象。这是为什么 Modelinput 没有生效的原因。
要使 Modelinput 生效,你需要首先创建一个 Modelinput 对象,然后将其传递给 function 函数。示例如下:
data = {"sim_th": 6}
model_input = Modelinput(**data)
result = function(model_input)
print(result)
3.总结
1.在 FastAPI 中,使用 (data: Modelinput) 这种形式的参数声明会强制要求 FastAPI 从请求中自动解析、验证并转换传入的数据,以确保其符合 Modelinput 的定义。这是 FastAPI 和 Pydantic 结合使用的功能,它将输入数据自动转换为指定的数据类型,从而使验证和处理输入数据变得非常方便和可靠。
2.在普通函数中,参数声明 (data: Modelinput) 并不会自动触发数据转换和验证,除非你自己编写代码来执行这些操作。如果你在普通函数中接受一个参数,并传入一个字典,如 function(data),Python 本身不会自动将字典转换为 Modelinput 对象。在这种情况下,你需要手动执行转换,例如通过 Modelinput(**data),以便让 Modelinput 的验证规则生效。
所以,总结起来:
在 FastAPI 中,使用 (data: Modelinput) 形式的参数声明会自动触发数据转换和验证。
在普通函数中,使用 (data: Modelinput) 形式的参数声明不会自动触发数据转换和验证,需要手动处理。
三、Python eval函数及Counter详解
简单讲,eval函数就是将字符串解析为Python的表达式并执行。
# 示例1:计算表达式的结果
x = 7
result = eval('3 * x')
print(result) # 输出: 21
# 示例2:调用函数
result = eval('pow(2, 2)')
print(result) # 输出: 4
# 示例3:执行简单的数学运算
result = eval('2 + 2')
print(result) # 输出: 4
# 示例4:在指定命名空间中执行表达式
namespace = {'a': 2, 'b': 3}
result = eval('a + b', namespace)
print(result) # 输出: 5
#示例5:将字符串列表转换为真列表
lis = '[1,2]'
res = eval(lis)
print(res)
print(type(res))
#输出:
# [1, 2]
#
Counter函数是Python标准库collections模块中的一个类,用于计算可迭代对象中元素的数量。Counter是dict字典的子类,它以元素作为键,以元素出现的次数作为值进行计数。
from collections import Counter
# 示例1:统计列表中元素的出现次数
my_list = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
my_counter = Counter(my_list)
print(my_counter) # 输出: Counter({4: 4, 3: 3, 2: 2, 1: 1})
# 示例2:获取出现次数最多的元素
print(my_counter.most_common(2)) # 输出: [(4, 4), (3, 3)]
# 示例5:从计数器中减去另一个可迭代对象中的元素
another_list = [1, 2, 2, 3, 4, 4]
my_counter.subtract(another_list)
print(my_counter) # 输出: Counter({3: 2, 4: 2, 1: 0, 2: 0}))