Python用法全面总结(持续更新)

Python 用法总结(持续更新)


文章目录

  • Python 用法总结(持续更新)
  • 前言
  • 一、Python中global的用法
  • 使用global的例子(结合logging模块)
  • logging
  • 二、Typing中Optional及Pydantic中BaseModel
  • 1.Typing中Optional
  • 2.Pydantic中BaseModel
  • 3.总结
  • 三、Python eval函数及Counter详解

  • 前言

    主要记录一下工作中用到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 <class 'float'>
    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]
    #<class 'list'>
    

    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}))
    

    作者:淡水,

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python用法全面总结(持续更新)

    发表回复