使用字典来代替 switch 语句

方法:
    使用字典的key代替 switch中的case
示例:
    switcher = {
        0 : 'Go left',
        1 : 'Go right',
        2 : 'Go straght'
    }
使用key选择分支:
    print(switcher[0])
缺点:
    模拟不了default分支

解决:
    使用get方法,并指定匹配不到key时的返回值
    print(switcher.get(5, 'Unknown')) #输出 Unknown

仍有缺点:
    只能简单赋值,无法书写代码段

完备的示例:
    将原有字符串部分均使用函数进行返回
    代码:
        def goleft():
            return 'goleft'
        def goright():
            return 'goright'
        def gostraght():
            return 'gostraght'
        def default():
            return 'default'
        注意:定义顺序必,函数必须先进行定义
        switcher1 = {
            0 : goleft,
            1 : goright,
            2 : gostraght
        }
        print( switcher1.get(5, default)() ) #输出default
    注意:
        调用形式,函数式编程 :switcher1.get(5, default)() 
        由于get到的是函数名,所以需要加()显式调用

列表推导式:(Pythonic)

场景:
    通过已经存在的列表,生成新的列表
示例:
    对[1,2,3,4,5]全部元素进行平方
实现:
    其他可以实现的方式:map+filter
推导式实现:
    a = [1,2,3,4,5,6]
    b = [i*i for i in a] # [ 关于i的表达式 for i in 列表 ]
    print(b)
    #输出:[1, 4, 9, 16, 25, 36]
    b = [i*i for i in a if i>3] # [ 关于i的表达式 for i in 列表 if 关于i的判断 ]
    print(b)
    #输出:[16, 25, 36]


注意:
    如果对于set进行集合推导式
代码:
    a = {1,2,3,4,5,6}
    b = {i*i for i in a} # [ 关于i的表达式 for i in 列表 ]
    print(b)
    #输出:{1, 4, 36, 9, 16, 25}
其他;
    元组,列表,字典,集合,都可以被推导
    对于字典:
        stu = {
            'Tom':18,
            'Jack':13,
            'Kimmy':15
        }

    提取key:
        stub = { key for key,value in stu }
        会报错,字典不能直接被解包遍历,需要使用items()方法
    代码:
        print( { key for key,value in stu.items() } )
        #{'Tom', 'Kimmy', 'Jack'}
        print( { value:key for key,value in stu.items() } )
        #{18: 'Tom', 13: 'Jack', 15: 'Kimmy'} 键值互换
        print( ( key for key,value in stu.items() ) )
        #<generator object <genexpr> at 0x0000000000B36B48>

None 空类型 type=NoneType

注意:
    在类型和字符串方面:不是'',不是[],不是0,不是false
验证:
    def fun1():
        pass        #函数没有return,返回None
    def fun2():
        return      #return后不跟变量,返回None
    print(fun1())   #返回None
    print(fun2())   #返回None


判断a = []为空的方式

    正确的方式
        if not a:
            print('None') 
        else:
            print('NotNone----') 

    错误的方式
        if a is None:
            print('None') 
        else:
            print('NotNone') #a=[]时,并不能判空
注意:
    print(bool(None))   #Fasle
    print(bool([]))     #Fasle

    python中每个类型都和True False有对应关系:None = False

验证一:
    class Test():
        pass
    test = Test()

    if test:
        print('NotNone')
    else:
        print('None')
    #输出:NotNone
    print(bool(test))   #True
    print(bool(Test())) #True

验证二:(添加__len__方法)
    class Test():
        def __len__(self):
            return 0
    test = Test()

    if test:
        print('NotNone')
    else:
        print('None')
    #输出:None
    print(bool(test))   #False
    print(bool(Test())) #False
结论:
    上述表明,实例化后使用if并不一定能判空,其取决于类内的定义
    特别是__len__()和__bool__()方法,会决定实例化后返回的布尔取值
注意:

    __len__(self)方法返回值:只能返回整形或布尔值
    触发函数:
        bool(Test()),在没有__bool__()时调用对象的__len__()
        len(Test()),在没有__bool__()时调用对象的__len__()
混合:
    class Test():
        def __bool__(self):
            return True 
        def __len__(self):
            return False
    test = Test()
    print(bool(Test())) #输出:True
结论:
    __bool__()方法优先级高于__len__()方法,如果有bool方法存在那么优先使用bool的返回值

装饰器的副作用

使用自定义的装饰器
    import time
    def decorator(func):
        def wrapper():
            '''
                wrapper的描述
            '''
            print(time.time())
            func()
        return wrapper
验证一:
    def f1():
        '''
            描述f1的作用等等
        '''
        print('f1.__name__:',f1.__name__)
    f1() # 输出:f1
    print(help(f1))
    #输出:描述f1的作用等等
验证二:
    @decorator
    def f2():
        '''
            描述f2的作用等等
        '''
        print('f2.__name__:',f2.__name__)
    f2() # 输出:wrapper

    # >>> help(len)可以查看len()函数的说明
    print(help(f2))
    #输出:“wrapper的描述”
结论:
    由上可知,装饰器会盖面原有函数的本身性质,函数名注释等等


定义无副作用的装饰器:
    方法:
        在自定义装饰器中添加装饰器@wraps
    代码:
        import time
        from functools import wraps

        def decorator(func):
            '''
                装饰器的注释
            '''
            @wraps(func) #添加装饰器,可以带参数
            def wrapper():
                print(time.time())
                func()
            return wrapper
    验证:
        @decorator
        def f1():
            '''
                描述f1的作用等等
            '''
            print('f1.__name__:',f1.__name__)
        f1() # 输出:f1
        print(help(f1)) #输出:描述f1的作用等等

    @wraps装饰器:
        原先的装饰器直接执行的wrapper函数,添加@wraps装饰器之后,
        首先执行warps装饰器,其可以获得被装饰函数的全部信息,所以可以将原被修饰的函数的全部信息进行保留