文章目录

  • python
  • 1、三元表达式
  • 2、列表生成式
  • 3、判断一个序列是不是另一个序列的子序列
  • 4、 GIL 全局解释器锁(Global Interpreter Lock,简称 GIL)
  • GIL 工作原理
  • 5、装饰器
  • 简单装饰器
  • 装饰器工厂
  • 类装饰器
  • python

    1、三元表达式

    # <expression1> if <condition> else <expression2>
    x = 10
    y = 20
    
    # 使用三元表达式判断 x 和 y 的大小,并赋值给 result
    result = "x 大于 y" if x > y else "x 小于或等于 y"
    
    print(result)  # 输出: x 小于或等于 y
    

    2、列表生成式

    # [expression for item in iterable if condition]
    # expression:要计算并添加到新列表中的表达式。
    # item:从可迭代对象中获取的元素。
    # iterable:一个可迭代对象,例如列表、字符串、范围等。
    # condition(可选):过滤条件,只有满足条件的元素才会被包含在新列表中。
    # 例子
    
    # 创建一个包含 1 到 10 的平方的列表
    squares = [x**2 for x in range(1, 11)]
    print(squares)  # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    
    # 创建一个包含 1 到 10 中偶数的平方的列表
    even_squares = [x**2 for x in range(1, 11) if x % 2 == 0]
    print(even_squares)  # 输出: [4, 16, 36, 64, 100]
    
    # 嵌套循环:创建一个包含 (i, j) 元组的列表,其中 i 是 1 到 3,j 是 1 到 2
    pairs = [(i, j) for i in range(1, 4) for j in range(1, 3)]
    print(pairs)  # 输出: [(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2)]
    
    # 带有多个条件的列表生成式(两个if相当于用and连接)
    filtered_list = [x for x in range(20) if x % 2 == 0 if x % 3 == 0]
    # 等价于下面
    filtered_list = [x for x in range(20) if (x % 2 == 0 and x % 3 == 0)]
    print(filtered_list)  # 输出: [0, 6, 12, 18]
    
    # 带有多个条件的列表生成式使用or连接
    custom_list = [x for x in range(20) if x % 2 == 0 or if x % 5 == 0]
    custom_list = [x for x in range(20) if (x % 2 == 0 or x % 5 == 0)]
    print(custom_list)  # 输出: [0, 2, 4, 5, 6, 8, 10, 12, 14, 15, 16, 18, 20]
    
    # 从一个字符串中提取字母并转换为大写
    text = "Hello, World!"
    uppercase_letters = [char.upper() for char in text if char.isalpha()]
    print(uppercase_letters)  # 输出: ['H', 'E', 'L', 'L', 'O', 'W', 'O', 'R', 'L', 'D']
    

    3、判断一个序列是不是另一个序列的子序列

    def is_subsequence(a, b):
        b = iter(b)
        return all(i in b for i in a)
    
    print(is_subsequence([1, 3], [0, 1, 2, 3]))  # 输出: True
    print(is_subsequence([1, 4], [0, 1, 2, 3]))  # 输出: False
    

    定义函数
    def is_subsequence(a, b): 定义一个名为 is_subsequence 的函数,接受两个参数 ab
    创建迭代器
    b = iter(b):将 b 转换为一个迭代器。这样做的目的是为了在检查 b 中是否存在元素时,可以消耗掉 b 中的元素。换句话说,一旦某个元素在 b 中被找到,之后的查找会从该元素后面开始,而不是从头开始
    检查子序列
    return all(i in b for i in a)

  • 这个表达式使用生成器表达式遍历 a 中的每个元素 i
  • 对于每个元素 i,它检查是否在迭代器 b 中。
  • all() 函数会返回 True 当且仅当生成器表达式中的所有检查都返回 True。也就是说,只有当 a 中的每个元素都能在 b 中找到时,is_subsequence 才会返回 True
  • 4、 GIL 全局解释器锁(Global Interpreter Lock,简称 GIL)

    Python 的全局解释器锁(Global Interpreter Lock,简称 GIL)是一个机制,用于确保在任何时刻只有一个线程可以执行 Python 字节码。这一设计主要是为了简化 CPython 的内存管理并避免多线程环境下的数据竞争和崩溃。但使用线程时的时候仍需要自己加锁来管理内存。

    GIL 工作原理

    单线程运行: GIL 使得 CPython 解释器在执行字节码时只允许一个线程运行。这意味着即使在多核处理器上,Python 程序也不能利用多个 CPU 核心进行并行计算。
    线程切换: 当一个线程需要执行一段时间的操作(如 I/O 操作),GIL 会被释放,允许其他线程获取 GIL 并执行。这种切换通常发生在 I/O 阻塞、时间片到期等情况下。这样,虽然 GIL 限制了 CPU 密集型操作的并行性,但对于 I/O 密集型操作,多个线程仍然可以有效共享时间。
    影响:

  • 对于 CPU 密集型任务,GIL 可能导致性能瓶颈,因为多个线程无法并行运行。
  • 对于 I/O 密集型任务,如网络请求或文件读写,GIL 的影响较小,因为线程可以在等待 I/O 时让出 GIL。
  • 注: NumPy 的许多核心功能是用 C 和 Fortran 编写的,这些底层库可以在执行计算时释放 GIL。这意味着在进行大量数值计算时,NumPy 可以利用多核 CPU 的优势,特别是在调用外部库(如 BLAS 或 LAPACK)进行矩阵运算时

    5、装饰器

    简单装饰器

  • 装饰器是一个接收函数作为参数并返回一个增强功能的函数(通常是一个闭包)的函数。装饰器的目的是在不修改原始函数代码的前提下添加额外的功能
  • 一个典型的装饰器定义没有外层函数包裹,直接接收一个函数并返回一个函数
  • # 外层函数(Decorator Function):这个函数接受被装饰的函数作为参数
    def decorator(func): 
    	# 内层函数(Wrapper Function):这个函数用于包装或增强被装饰的函数的行为。它通常会接受任意的参数,并在适当的时候调用原始函数。
        def wrapper():
            print("在函数执行前做点什么")
            # 调用原始函数
            func()	
            print("在函数执行后做点什么")
        return wrapper
    
    @decorator
    def say_hello():
        print("Hello!")
    
    say_hello()
    

    装饰器工厂

  • 装饰器工厂是一个返回装饰器的函数。这种结构让你可以在创建装饰器时传递参数,从而控制装饰器的行为。
  • 装饰器工厂通常由两层或更多层函数组成:最外层函数接收装饰器的配置参数,内层函数则是实际的装饰器,它接收一个函数并返回一个增强版的函数。
  • # 简单装饰器本身不支持在装饰器应用时直接传递参数来控制其行为
    def decorator_with_args(prefix):
        def decorator(func):
            def wrapper(*args, **kwargs):
                print(prefix, "在函数执行前做点什么")
                result = func(*args, **kwargs)
                print(prefix, "在函数执行后做点什么")
                return result
            return wrapper
        return decorator
    
    @decorator_with_args("LOG:")
    def say_hello():
        print("Hello!")
    
    say_hello()
    

    类装饰器

    类装饰器是使用类来实现装饰器的功能。类装饰器利用了类的 __call__ 方法,这使得类的实例可以被当作函数调用,使用类装饰器的优势在于它能够利用面向对象编程的特性,如继承、封装等,来构建更复杂的装饰器逻辑。

    普通的装饰器用类方法实现

    class CountCalls:
        def __init__(self, func):
            self.func = func
    
        def __call__(self, *args, **kwargs):
            print("在函数执行前做点什么")
            result = self.func(*args, **kwargs)
            print("在函数执行后做点什么")
            return result
    
    
    @CountCalls
    def say_hello():
        print("Hello!")
    
    
    say_hello()
    

    装饰器工厂用类装饰器实现

    from functools import wraps
    class CountCalls:
        def __init__(self, prefix):
            self.prefix = prefix
    
        def __call__(self, func):
        	# 将一些重要的元数据从原始函数(即被装饰的函数 func)复制到包装函数(即装饰器内部定义的函数 wrapper)。这些元数据包括函数的名称 __name__、文档字符串 __doc__、以及其他由用户定义的属性。
            @wraps(func)	
            def wrapper(*args, **kwargs):
                print(self.prefix, "在函数执行前做点什么")
                result = func(*args, **kwargs)
                print(self.prefix, "在函数执行后做点什么")
                return result
            return wrapper
    
    @CountCalls(prefix='LOG:')
    def say_hello():
        print("Hello!")
    
    
    say_hello()
    

    当函数执行失败时按照传入参数重试

    import logging
    import time
    from functools import wraps
    from time import sleep
    
    
    class Retry:
        """
        类装饰器,当函数执行抛出异常时,按照max_retries和wait_time重试
        """
    
        def __init__(self, max_retries=3, wait_time=2):
            self.max_retries = max_retries
            self.wait_time = wait_time
    
        def __call__(self, func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                attempts = 0
                while attempts < self.max_retries:
                    try:
                        return func(*args, **kwargs)
                    except Exception as e:
                        attempts += 1
                        logging.error(f"Error occurred: {e}. Retrying {attempts}/{self.max_retries}...")
                        time.sleep(self.wait_time)  # 等待惩罚时间
                        if attempts == self.max_retries:
                            logging.error("Max retries reached. Giving up.")
    
            return wrapper
    
    
    @Retry(max_retries=5, wait_time=1)
    def say_hello():
        print("Hello!")
        sleep(0.2)
        raise Exception("手动抛出异常")
    
    say_hello()
    
    # Hello!
    # ERROR:root:Error occurred: 手动抛出异常. Retrying 1/5...
    # Hello!
    # ERROR:root:Error occurred: 手动抛出异常. Retrying 2/5...
    # Hello!
    # ERROR:root:Error occurred: 手动抛出异常. Retrying 3/5...
    # Hello!
    # ERROR:root:Error occurred: 手动抛出异常. Retrying 4/5...
    # Hello!
    # ERROR:root:Error occurred: 手动抛出异常. Retrying 5/5...
    # ERROR:root:Max retries reached. Giving up.
    

    作者:吃不到的烤鱼

    物联沃分享整理
    物联沃-IOTWORD物联网 » python常用代码-自用

    发表回复