• python 中级用法


    Prerequisite

    老是用那几个 crud,都忘了类啊,装饰器啥的怎么用,重新回来学学~
    参考文章:廖雪峰

    基础知识

    *args 是非关键字参数,用于元组,**kw 是关键字参数,用于字典
    同时使用 *args 和 **kwargs 时,必须 *args 参数列要在 **kwargs 前(比如 foo(a=1, b='2', c=3, a', 1, None, ) 会报错)

    def foo(*args, **kwargs):
        print('args = ', args)
        print('kwargs = ', kwargs)
        print('---------------------------------------')
    
    
    if __name__ == '__main__':
        foo(1, 2, 3, 4)
        foo(a=1, b=2, c=3)
        foo(1, 2, 3, 4, a=1, b=2, c=3)
        foo('a', 1, None, a=1, b='2', c=3)
    
    '''
    args =  (1, 2, 3, 4)
    kwargs =  {}
    ---------------------------------------
    args =  ()
    kwargs =  {'a': 1, 'b': 2, 'c': 3}
    ---------------------------------------
    args =  (1, 2, 3, 4)
    kwargs =  {'a': 1, 'b': 2, 'c': 3}
    ---------------------------------------
    args =  ('a', 1, None)
    kwargs =  {'a': 1, 'b': '2', 'c': 3}
    ---------------------------------------
    '''
    

    super()._init_()
    针对子类的,用于自动初始化,减少代码数的语句
    参考博客:理解super()._init_()

    class Car(object):
        def __init__(self, owner, year, model):
            self.owner = owner
            self.year = year
            self.model = model
    
    class ElectricalCar(Car):
        def __init__(self, battery, *args, **kwargs):
            # 将剩下的参数打包送给 super
            super().__init__(*args, **kwargs)
            # 从参数列表中拿出 battery 初始化子类属性
            self.battery = battery
        
        def get_power(self):
            """打印电池信息"""
            print(f'The battery of this car is {self.battery}')
    
    
    car = ElectricalCar('10000kwh','Jarry', 2021, 'Model S')
    car.get_power()
    print(car.owner, car.year, car.model)
    """
    The battery of this car is 10000kwh
    Jarry 2021 Model S
    """
    

    判断 变量/函数 类型

    # 一般用 type 就行了
    
    type(123)
    # <class 'int'>
    type(abs)
    # <class 'builtin_function_or_method'>
    type(a)
    # <class '__main__.Animal'>
    type(fn)==types.FunctionType
    # True
    type(abs)==types.BuiltinFunctionType
    # True
    type(lambda x: x)==types.LambdaType
    # True
    type((x for x in range(10)))==types.GeneratorType
    # True
    
    # 类就用 isinstance
    # 实际上 type 能用的 isinstance 都能用,建议优先使用 isinstance 判断类型
    # object -> Animal -> Dog -> Husky
    
    isinstance(h, Dog)
    # True
    

    执行字符串

    expr = """
    a, b = ["123", "456"]
    print(a, b)
    """
    exec(expr)
    
    # 123 456
    

    高级特性

    生成器 generator

    简单介绍

    # 普通列表
    L = [x * x for x in range(10)]
    print(L)
    # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    
    # 生成器
    g = (x * x for x in range(10))
    print(next(g))
    # 0
    print(next(g))
    # 1
    print(next(g))
    # 4
    
    for n in g:
        print(n)
    '''
    9
    16
    25
    36
    49
    64
    81
    '''
    

    斐波那契的运用

    # 最普通的斐波那契
    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            print(b)
            a, b = b, a + b
            n = n + 1
        return 'done'
    
    # 使用了生成器的斐波那契(print 变成了 yield)
    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
        return 'done'
    
    # 正常的输出,最后不会输出 done
    for n in fib(6):
        print(n)
    
    # 最后会输出 done
    g = fib(6)
    while True:
        try:
            x = next(g)
            print('g:', x)
        except StopIteration as e:
            print('Generator return value:', e.value)
            break
    

    迭代器

    可迭代对象:Iterable
    迭代器:Iterator

    凡是可作用于 for 循环的对象都是 Iterable 类型
    凡是可作用于 next() 函数的对象都是 Iterator 类型,它们表示一个惰性计算的序列

    # 集合数据类型如 list、dict、str 等是 Iterable 但不是 Iterator,不过可以通过 iter() 函数获得一个 Iterator 对象
    # Python 的 for 循环本质上就是通过不断调用 next() 函数实现的,例如:
    
    for x in [1, 2, 3, 4, 5]:
        pass
    
    # 完全等价于
    
    # 首先获得Iterator对象:
    it = iter([1, 2, 3, 4, 5])
    # 循环:
    while True:
        try:
            # 获得下一个值:
            x = next(it)
        except StopIteration:
            # 遇到StopIteration就退出循环
            break
    

    函数式编程

    匿名函数 lambda

    直接举例

    def is_odd(n):
        return n % 2 == 1
    
    L = list(filter(is_odd, range(1, 20)))
    
    # 完全等价于
    
    L = list(filter(lambda n:n%2 == 1 , range(1,20)))
    

    装饰器

    一句话,装饰器就是给原函数添加额外的功能(迭代原函数)的东西
    装饰器的英文是 decorator,装饰器分为传参和非传参,下面写了两个模板

    from datetime import datetime
    import functools
    
    # 一个普通的函数
    def now():
        print(datetime.now())
    
    # 运行函数和打印函数的名字
    now()
    # 2022-07-26 17:55:02.891440
    print(now.__name__)
    # now
    
    
    # 普通的装饰器(两层)
    # @functools.wraps(func) 的功能相当于 wrapper.__name__ = func.__name__
    # 使用 *args, **kw 的目的是完全接收 func 原本的传参
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('call %s():' % func.__name__)
            return func(*args, **kw)
        return wrapper
    
    @decorator
    def now():
        print(datetime.now())
    
    now()
    # call now():
    # 2022-07-26 17:58:56.143251
    print(now.__name__)
    # now
    
    
    # 使用参数的装饰器(三层)
    def log(text):
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kw):
                print('%s %s():' % (text, func.__name__))
                return func(*args, **kw)
            return wrapper
        return decorator
    
    @log('text')
    def now():
        print(datetime.now())
    
    now()
    # text now():
    # 2022-07-26 17:59:50.026713
    print(now.__name__)
    # now
    

    偏函数

    偏函数可以简化参数操作
    当函数的某个参数是我们可以提前获知的,那我们就可以将它固定住!

    import functools
    
    # 定义一个取余函数,默认和2取余;
    def mod(x,y=2):
      # 返回 True 或 False
      return x % y == 0
    
    # 假设我们要计算和3取余,如果不使用partial()函数,那么我们每次调用mod()函数时,都要写y=3
    mod(4,y=3)
    mod(6,y=3)
    
    # 使用partial()函数
    mod_3 = functools.partial(mod,y=3)
    mod_3(4)
    mod_3(6)
    
  • 相关阅读:
    C++ 引用的作用和用法
    const和指针
    sizeof的用法
    C++数组初始化的问题
    C++变量的存储类别(动态存储、静态存储、自动变量、寄存器变量、
    c++变量在内存中的存储区域(转)
    C语言的 &数组名 和 数组名的区别
    C语言运算中的数据类型自动转换原则
    链表反转
    常见的排序方法
  • 原文地址:https://www.cnblogs.com/CourserLi/p/16521218.html
Copyright © 2020-2023  润新知