zoukankan      html  css  js  c++  java
  • 第五章 函数

    5.1 三元运算

    • 又称为三目运算

    和运算符相关

    val = v if v else 666
    val = v or 666 # 源码中会见到
    

    Note:为了赋值

    # 简单条件赋值时使用
    v = 前面 if 条件 else 后面
    
    # 用户输入,如果是整数,则转换,否则赋值为None
    data = input('>>>')
    value = int(data) if data.isdecimal() else None
    

    5.2 函数基础

    面向过程【可读性差、可重用性差】—> 函数式编程—>面向对象

    # 如果给其他人发送邮件,可以把发送程序进行封装起来,可缩减代码长度和提高重复利用性。
    

    函数式编程

    • 将n行代码放在别处,并取别名,以后可以调用
    • 场景:
      • 代码重复执行
      • 代码量特别多,超过一屏,可以选择函数编程(一般控制在一屏以内

    1. 定义函数

    可以定义一个由自己想要功能的函数,以下是简单的规则:(5)

    • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
    • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
    • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
    • 函数内容以冒号起始并且缩进
    • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
    def functionname( parameters ):   
      "函数_文档字符串"
      function_suite  # 函数体  
    	return [expression]
    # 默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。
    
    # 函数定义
    # way1
    def 函数名():
      	# 函数体
        pass
    # 函数的执行
    函数名()    # 会自动执行
    
    # way2 
    # 形参可以是多个
    def 函数名(形参):
      	# 函数体
        pass
    函数名(实参)
    

    Note1(1)

    • None方法类似函数,但不是(方法操作是s.upper(),方式,而函数是直接调用,len(),open())

    2. 两种参数(示例)

    形参(形式参数)与实参(实际参数)的位置关系。

    def 函数名(形参):
      	# 函数体
        pass
    函数名(实参)
    
    # 无形参示例
    def get_sum_list()
    	sum = 0
      for i in li:
        sum += i
    print(get_sum_list())
    
    # 有形参示例
    # 请写一个函数,函数计算列表 info = [11,22,33,44,55] 中所有元素的和。
    info = [11, 22, 33, 44]
    def get_list_sum(li):
        sum = 0
        for i in li:
            sum += i
        print(sum)
    get_list_sum(info)
    

    3. 函数的返回值

    Note2(4)

    1. return [表达式] 结束函数,选择性地返回一个值给调用方(func()为返回值)。
    2. return 1, 2 ,3 会返回tuple:(1, 2, 3)
    3. 函数默认返回值是 None ,有时可以使用其作为flag
    4. 可变类型(list)的基本上都是None, 不可变(str)基本上会返回新值
    def func(arg):
      	return 9 # 返回值为9,默认为None,可以返回任何类型的数据
    val = def func(v)
    
    # 示例2
    # 让用户输入一段字符串,计算字符串中有多少A,就在文件中写入多少‘echo’
    def get_char_count(arg):
      	count = 0
        for i in arg:
          	count += 1
    
    def write_file(data):
      	open('a.txt', mode='w', encoding='utf-8') as v:
            if len(data) == 0:或者 if not bool(data):
                return '写入失败'
    				v.write(data)
            return '写入成功'
      	
    print(count)
    content = input()
    

    4. 函数的四种方式

    # way1 无形参,无return
    def fun1():
      	pass
    fun()
    # way2 有形参,无return
    def fun2(arg):
      	pass
    fun2(v)
    # way3 无形参,有return(指定值)
    def fun3():
      	pass
      	return 9
    val = fun3(v)
    # way4 有形参,有return(变量)
    def fun4(arg1, arg2):
      	pass
      	return arg1 + arg2
    val = fun4(v1 + v2)
    

    5. 练习(3)

    # 1. 写函数,计算一个list中有多少个数字,打印,有%s个数字
    # 判断数字:type(a) == int
    # 2. 写函数,计算一个列表中偶数索引位置的数据构造成另外一个列表,并返回。
    # 3. 读取文件,将文件的内容构造成指定格式的数据,并返回。
    a.log文件
        alex|123|18
        eric|uiuf|19
        ...
    目标结构:
    a. ["alex|123|18","eric|uiuf|19"] 并返回。
    b. [['alex','123','18'],['eric','uiuf','19']]
    c. [
    	{'name':'alex','pwd':'123','age':'18'},
    	{'name':'eric','pwd':'uiuf','age':'19'},
    ]
    

    5.3 变量作用域&嵌套

    1. 函数传参方式(2+1)

    • 参数传递方式分为位置传参、关键字传参、函数作为参数进行传递

    • 位置传参

      • 严格按照位置进行传参
    # 示例
    def func(a1, a2):
      pass
    
    func(1, 3)
    func(1, [1, 2, 3])
    
    • 关键字传参
    # 示例
    def func(a1, a2):
    	pass
    
    func(a1 = 1, a2 = [1, 2, 3])
    
    func(a1 = 1, 2 )     # 此时会报顺序错误
    

    Note3(1)

    1. 关键字传参可以和位置传参混合使用,但 位置参数 必须在 关键字传参

    2. 函数定义参数(3)

    • 函数定义中,def func() 括号中可以省略默认参数和 *args/**kwargs。

    1. 省略参数

    # 示例
    def func():
    	pass
    

    2. 默认参数

    • 注意默认参数一定要在位置参数之后
    • 在定义默认参数时,慎用可变类型变量
    # 示例 
    def func(a1, a2=2):
    	pass
    # 调用方法,有默认参数时,可以不用省略,采取默认值,也可以重新赋值
    func(1)
    func(1, 3)
    # 默认形参时,如果默认是可变类型的需要谨慎使用
    
    # 如果想要给values设置默认是空list
    def func(data, value=[]):
      pass
    # 推荐
    def func(data, value=None):
      if not value:    
        valu=[]
    

    3. *args/**kwargs(万能参数)

    • *args 表示接收所有由实参通过位置传参方式,传递过来的数据,可以和位置参数一起使用。
    • 接收到的参数值,会通过循环加入tuple
    # 示例 : 可以传递任意类型数据
    def func(*args):
    	pass
    
    # [1, 2, 3]会被当成整体变成tuple中的一个元素
    func(1, 2, 3, [1, 2 ,3])
    # 直接赋值, [1, 2, 3]也会循环取出追加到tuple中
    func(4, 5 ,6 ,*[1, 2 ,3])
    
    • **kwargs 表示接收所有关键字传参的数据,也可以通过**{'k1': 1, 'k2':2},循环取出keys对,加入形参dict中
    # 示例 :只能通过关键字传参,或者dict赋值
    def func(**kwargs):
        print(kwargs)
    
    # [1, 2, 3]会被当成整体变成dict中 'd': [1, 2, 3]
    func(a=1, b=2, c=3, d=[1, 2 ,3])
    # 直接赋值, {'k1': 4, 'k2': 5}也会循环取出追加到形参的dict中
    func(a=1, b=2, c=3, d=[1, 2, 3], **{'k1': 4, 'k2': 5})
    

    Note4(4)

    1. 形参中的默认参数,也可以使用位置传参方式
    2. 传参时,有*(**)时,会直接赋值 (循环加入) 给形参
    3. 不带* / **的实参,会转换为tuple / dict
    4. 传入的数据都是循环加入tuple / dict中

    3. 作用域&函数嵌套

    • 变量作用域时是变量的有效作用范围,在python中函数就是一个局部作用域。由于作用域的不同,变量的有效范围也不同,根据作用范围可以把变量分为,全局变量和局部变量。
    • 全局变量:可供任何函数进行使用,修改,在python文件第一层的变量。在python中一般把全局变量命名为全部大写(规范),例如:USRE_NAME = 'henry'。
    • 局部变量:可以把函数中的变量视为局部变量。函数体中变量为函数所私有(只能被其子函数进行使用)。
    # 示例1
    a	= 'henry'
    def func():
      print(a)
    a = 123
    func()   # 此时使用的是全局变量, 结果是 123
    
    # 示例2
    a = 'henry'
    def func1():
        def func2():
         		a = 'echo'
            print(a)
        func2()
        print(a)
    
    a = 123
    func1()
    print(a)
    # echo 123 123
    

    Note5(4)

    1. python文件就是一个全局作用域
    2. 函数是一个 (局部) 作用域
    3. 局部作用域中的数据归自己私有
    4. 作用域中查找数据规则
      • 优先查找自己作用域,自己没有,去父籍作用域查找直到找到全局作用域
      • 查找不到会报错,默认只能使用父籍作用域中的变量值不能赋值(可变类型可以修改
    # 示例
    # 对于可变变量可以进行修改
    a = [1, 3, 5, 7]
    def fun1():
      	a.append('henry')
    fun1()
    print(a)     # 此时a会被修改
    
    # 两种赋值的方法
    # 可以使用 global 关键字对全局变量进行重新赋值
    global name
    name = 'alex'  # 给全局变量重新赋值
    
    # 可以使用 nolocal 关键字对父籍变量进行重新赋值, 在父籍找不到时,会报错
    nonlocal name 
    name = 'alex'  # 给父籍变量重新赋值
    

    Note6(3)

    1. 对于可变变量可以进行修改
    2. global 关键字对全局变量进行重新赋值
    3. nolocal 关键字对父籍变量进行重新赋值, 在父籍找不到会报错

    5.4 函数进阶

    • 高阶函数(3)
      1. 对函数赋值
      2. 函数当作参数传递
      3. 把函数当作返回值
    # <class 'function'>
    def func ():
      pass
    print(type(func))
    # 函数可以认为是一变量
    

    1. 函数赋值

    def func():
      print(123)
    v = fun # 指向相同的地址
    v()
    
    # 示例
    def func():
      print(123)
    v1 = [func, func, func]
    v2 = [func(), func(), func()]
    print(v1)
    print(v2)
    

    2. 函数传参

    def func(arg):
      print(arg)
    def show():
      return 999
    
    func(show)   # 999 None
    

    3. 函数作为返回值

    def func():
      print(1,2,3)
    def bar():
      return func
    v = bar()  # func
    v()
    

    Note7(3)

    1. 注意funcfunc() 的区别
    2. 函数(实际是内存地址)可以放入set()中(不常用), 或dict中(一般用于values,也可以放在key中但不常用)
    3. 函数一旦定义,只要进行加载,就是不可变,可 hash
    # 10 个函数, 一般是建立字典
    def func():
      print('话费查询')
    def bar():
      print('***')
    def base():
      print('***')
    
    info = {
        'f1': func,
        'f2': bar,
        'f3': base
      }
    choice = input('please input your choice: ')
    name = info.get('choice')
     if not name:
      	print('输入不存在')
     else:
    		name()
    

    3. lambda表达式

    # 三目运算,为了解决简单的if...esle的情况
    # lambda,为了解决简单函数的情况
    eg:
    def func(a1, a2):
      return a1 + a2
    # 可以改写为,a1 + 100 即为return 值
    func = lambda a1, a2: a1 + 100
    
    # way1 直接使用
    func = lambda : 100
    func = lambda a: a*10
    func = lambda *args, **kwargs: len(args) + len(kwargs)
    # way2 使用全局变量
    DATA = 100
    func = lambda a: a + DATA
    func(1)
    # way3 使用父籍变量
    DATA = 100
    def func():
      DATA = 1000
      func1 = lambda a: a + DATA
      v = func1(1)
      print(v)
    func()
    # way4 使用条件判断 ########
    func = lambda n1, n2: n1 if n1 > n2 else n2
    
    # 练习1
    USER_LIST = []
    func1 = lambda x: USER_LIST.append(x)
    v1 = func1('alex')
    print(v1)			# None
    print(USER_LIST) # ['alex']
    
    # 练习2
    func1 = lambda x: x.strip()
    v1 = func1('   alex')
    print(v1)			# 'alex'
    
    # 练习3
    func_list = [lambda x: x.strip(), lambda y: y+100, lambda x,y: x+y]
    v1 = func_list[0]('   alex')
    print(v1)			# 'alex'
    

    Note8(2)

    1. 用于表示简单函数(一行解决的函数)。
    2. lambda 表达式会默认返回冒号:之后的值

    4. 内置函数(30)

    • 自定义函数

    • 内置函数(31)

      1. 强制转换(7):int(),str, bool, list,dict,tuple,set
      2. 输入输出(2):print, input
      3. 其他(5):type, id, range, open, len
      4. 数学(7)
        • abs,round,float(int(55.5)保留整数部分)
        • max,min,sum,
        • divmod(两数相除,得商和余数, 两个值)
    1. 面向对象相关(4):dir,super,issubclass,isinstance
    # divmod. 练习
    USER_LIST = []
    for i in range(1, 836):
      tem = {name':'hello-%s' % i, 'email':'XXXX%s@qq.com' %s}
      USER_LIST.append(tem)
    """
    	要求:
    		每页展示10条
    		根据用户输入的页码,查看
    """
    
    1. 进制转换(3):bin(0b,int<—>bin),oct(0o,int<—>oct),int(其他进制转int),hex(0x,int<—>hex)

       # base 默认为 10
        v1 = '0b1101'
        result = int(v1, base = 2)
        # 转8进制
        v1 = '0o1101'
        result = int(v1, base = 8)
        # 转16进制
        v1 = '0x1101'
        result = int(v1, base = 16)
      
        # ip 点分二进制,将十进制转为二进制并通过 . 连接ip = '192.168.12.79'
        ip = '192.168.12.79'
        li = ip.split('.')
        l = []
        for i in li:
            i = int(i)
            i = bin(i)
            i = str(i).replace('0b', '')
            i = i.rjust(8, '0')
            l.append(i)
        s = '.'.join(l)
        print(s)
      
    2. 编码相关

    • chr() :把int型数据,转换为unicode编码

      • ord():把unicode转换为字符
      # 生成验证码
      import random	# 导入一个模块
      def get_random_data(length=6):
        data = []
        for i in range(length):
            v = random.randint(65,90) # 得到一个随机数
            data.append(v)
      	return ' '.join(data)
        
      code = get_random_data()
      

    print(code)

    
    8. map / filter / reduce(py2)/zip
    
    - **map**,循环每个元素(第二个参数),然后让元素执行函数(第一个参数),将每个函数结果保存到新的list中,并返回。(批量修改数据)
    
    ```python
    # map操作的 func 是一个函数 v 必须是可迭代,
    v = [11, 22, 33]
    def func(arg):
      return arg + 100 
    result = map(func, v) # 将函数的返回值添加到空list中[111, 122, 133]
    print(list(result))
    # 使用lambda 改写
    result = map(lambda x: x+100, v)
      print(result)		# py2直接返回
    print(list(resutl)) # py3会返回一个object,可用list()查看
    
    • filter
    ```python
    # 结果为True的时候,才返回数据
    

    v = [1, 2, 3, 'welcome', 4, 'hello']
    result = filter(lambda x: type(x) == int, v) # 生成新list
    print(list(result))
    ```

    • reduce
    import functools
    v = [1, 2, 3, 4]
    result = functools.reduce(lambda x,y: x*y, v)
    print(result)
    
    • zip
      a = [1,2,3]
      b = [4,5,6]
      c = [4,5,6,7,8]
      zipped = zip(a,b)     # 打包为元组的列表
      [(1, 4), (2, 5), (3, 6)]
      zip(a,c)             
      # 元素个数与最短的列表一致
      [(1, 4), (2, 5), (3, 6)]
      zip(*zipped)          
      # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
      [(1, 2, 3), (4, 5, 6)]  
    

    5.5 函数闭包

    1. 函数闭包

    def func(name):
      def inner():
        print(name)
      return inner
    
    v1 = func('henry')
    v1()
    v2 = func('echo')
    v2()
    
    # 不是闭包
    def func(name):
      def inner():
        return 123
      return inner
    
    # 闭包:封装值 + 内层函数需要使用
    def func(name):
      def inner():
        print(name)
        return 123
      return inner 
    

    Note9(5)

    1. 闭包,为函数创建一块区域(内部变量供自己使用),为以后执行提供数据;
    2. 闭包是能够读取其他函数内部变量的函数。
    3. 执行完毕+内部数据不被其他程序使用会被销毁
    4. 应用:装饰器,SQLAlchemy源码
    5. 由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)

    2. 递归(效率较低)

    • 递归限制为1000次
    def func(i):
      print(i)
      func(i+1)
    
    # 斐波那契数列
    def func(a, b):
      print(b)
      func(a, a+b)
    
    # 递归
    def fun(a):
      if a == 5:
        return 100
      result = func(a+1) + 10
      return result
    v = func(1)
    
    # 注意
    def fun(a):
      	if a == 5:
        		return 100
      	result = func(a+1) + 10
    
    v = func(1)
    

    5.6 装饰器和推导式

    • 使用func.__name__获取被调用的func函数名,func为形参

    1. 装饰器(重点)

    def func():
      def inner():
        pass 
     	return inner
    
    v = func()
    print(v)   # inner 函数
    # ##############################
    def func(arg):
      def inner():
        print(arg) 
     	return inner
    
    v1 = func(1)   # 1
    v2 = func(2)   # 2
    # ##############################
    def func(arg):
      def inner():
        arg()
     	return inner
    
    def f1():
      print(123)
      
    v = fucn(f1)
    v()		# 123
    # ##############################
    def func(arg):
        def inner():
            arg()
    return inner
    def f1():
        print(123)
    return 666
    v1 = func(f1)
    result = v1() 
    # 执行inner函数 / f1含函数 -> 123 print(result) 	
    # None
    
    # ##############################
    def func(arg):
        def inner():
            return arg()
    return inner
    def f1():
        print(123)
    return 666
    v1 = func(f1)
    result = v1()   # 123 666
    
    • 装饰器示例
    def func(arg):
      def inner():
    		print('before')
        v = arg()
        print('after')
        return v
      return inner
    
    def index():
      print('123')
      return 666
    
    # 示例
    v1 = index()   # 123
    
    v2 = func(index)  # before 123 after
    v3 = v2()
    
    v4 = func(index)   # before 123 after
    index = v4
    index()
    
    index = func(index)  # before 123 after
    index()
    
    # 第一步,执行func函数,并将下面的函数当作函数传递,相当于func(index)
    # 第二部,将func返回值,重新赋值为下面的函数名,index = func(index)
    def func(arg):
        def inner():
            return arg()
        return inner
    
    @func
    def index():
        print(123)
        return 666
    
    print(index)  # <function func.<locals>.inner at 0x1054a16a8>
    

    应用示例

    # 计算函数执行时间
    def wrapper(func):
      	def inner():
          	start_time = time.time()
    				func()
    				end_time = time.time()
    				print(end_time - start_time)
            return func()
          return inner
    
    import time
     @ warpper   
    def func():
        time.sleep(2)
      	print(123)
      
     @ warpper   
    def func():
        time.sleep(1.5)
      	print(123)
    
    # 判断用户是否登陆
    

    Note10(2)

    1. 目的:在在不改变原函数的基础上,在执行函数前后自定义一些操作
    2. 场景:想要为函数扩展功能时
    • 编写装饰器
    # 装饰器的编写(示例)
    def wrapper(func):		# 必须有一个参数
      def inner():
        ret = func()
        return ret
     	return inner
    # 应用 index = wrapper(index)
    @wapper
    def index():
      pass
    @wapper
    def manage():
      pass 
    # 在执行函数,自动触发装饰器
    v = index()
    print(v)
    
    # 导入本目录下的其他py文件
    import a
    a.f1()
    a.f2()
    a.f3()
    
    • 编写格式
    def wrapper(func):
      	def inner(*args, **kwargs):
    		return func(*args, **kwargs)
      	return inner
    

    为什么要加*args,**kwargs?

    2. 关于参数

    # 让参数统一的目的:为装饰的函数传参
    def x(func):
      def inner(a, b):
        return func()
      return inner
    
    @x
    def index():
      pass
    
    index(1, 2)
    
    • 返回值
    # 装饰器建议写法
    def wrapper(function):
      	def inner(*args, **kwargs):
            v = funtion(*args, **kwargs)
            return v
      	return inner
    
    @wrapper
    def func():
    	pass
    
    • 带参数的装饰器
    # 第一步:v = wrapper(9)
    # 第二步:ret = v(index)
    # 第三步:index = ret
    def x(counter):
        def wrapper(function):
          	def inner(*args, **kwargs):
            	v = funtion(*args, **kwargs)
            	return v
          	return inner
         return wrapper
    
    @x(9)
    def index():
      	pass		
    
    # 示例:
    # 写一个带参数的装饰器,实现,参数是多少,被装饰器就要执行多少次,最终返回一个list
    def x(*args):
      def wrapper():
        def inner():
          li = [index() for i in range(args[0])]
          return li
        return inner
      return wrapper
    
    @x(9)
    def index():
      return 8
    
    v = index()
    print(v)
    
    • 元数据
    • 多个装饰器:@x1 @x2

    3. 推导式

    1. list推导式(生成式)

      • 格式(生成一个list)
      vals = [i for i in 'henry']
      v = [i for i in 可迭代对象 if 条件]  # 满足条件生成list
      v = [i if i > 5 else i+1 for i in 可迭代对象 if 条件]  
      # 满足条件生成list
      
      # 新浪
      def num():
        	return [lambda x: x * i for i in range(4)]
      print([m(2) for m in num()])
      
    2. set推导式

      • 格式
      # 满足条件生成set,会去重,条件判断可以省略
      v = {i for i in 可迭代对象 if 条件} 
      
    3. dict推导式

      • 格式
      # 满足条件生成dict,但需要key值和冒号:,条件判断可以省略
      v = { 'k' + str(i): i for i in 可迭代对象 if 条件}
      

    5.7 迭代器&生成器

    :int ,str, list…. / bytes(b'xxx'), datetime

    对象:由创建的数据

    类和对象

    1. 迭代器(class:iterator)

    • 展示list中所有数据

      1. 迭代器:对某种(str/list/tuple/dict/set) (序列)对象中的元素,进行逐个获取。
    1. 表象:具有__next__()方法,
    • list —> 迭代器:

      • v = iter([1, 2, 3, 4])
      • val = [1, 2, 3, 4].__iter__()
    • 迭代器获取每一个元素:v.next

    • 直到报错:StopIteration,表示迭代终止

      v = [1, 2, 3, 4]
      val = iter(v)
      value = val.__next__()
      print(value)
      
    • 甄别:数据中是否包含__next__()方法

      • for循环的内部,首先把数据转化为iter,反复执行iter.__next__(),取完不报错

    2. 可迭代对象

    • 具有__iter__()方法,必须返回一个迭代器(生成器)
    • for循环

    3. 生成器(函数的变异)(class:generator)

    • yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级
    • send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换
    1. 生成器基础
    def func():
      pass 
    func()
    
    # 生成器函数(内部是否包含yield)
    def func(arg):
      arg = arg + 1
      yield 1
      yield 2
      yield 100
    # 函数内部代码不执行,返回一个生成器
    val = func(100) 
    
    # 生成器:可以被for循环的,一旦开始循环,函数内部代码就开始执行
    for i in val:
      print(i)
    # 遇到第一个yield会把后面的值赋值给 i
    # 如果 yield 已经执行完毕,则意味着for循环结束
    
    # 边使用边执行
    def func():
      count = 1 
      while True:
      	yield count
        count += 1
    
    # v 只取yield值,是一个生成器对象
    v = func()
    for i in v:
      print(i)
      
    # 查看v中有哪些方法
    dir(v)
    

    Note11(4)

    1. 函数中如果存在yield,则该函数为生成器函数,调用生成器函数会返回一个生成器
    2. 只有被for循环时,生成器内部代码才会执行,每次循环都会获取yield的返回值
    3. 即使函数内部的yield函数永远执行不到,也是生成器
    4. 生成器也是一种特殊的迭代器,也是一个可迭代对象
    class Foo(object):
      def __iter__(self):
        return iter([1, 2, 3])
      	yield 1 
        yield 2
        
    obj = Foo(object)
    
    1. 生成器中send

    Note12(2)

    1. send方法,会触发一次next操作,yiled结果为其返回值
    2. 总的来说,send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互。
    3. 需要注意,在一个生成器对象没有执行next方法之前,由于没有yield语句被挂起,所以执行send方法会报错
    def func():
        print(123)
        n = yield('aaa')
        print('----->', n)
        yield 'bbb'
    
    data = func()
    next(data)
    v = data.send('太厉害了,直接传进去了')
    print(v)
    
    1. 生成器示例
    # 示例:读取文件
    def func():
        curse = 0
        while True:
            f = open('db','r','utf-8')
            f.seek(curse)
            data_list = []
          	for i in range(10):
            	line = f.readline()
                if not line:
                  	return
                data_list.append(line)
            curse = f.tell()
            f.close
            for row in data_list:
              	yield row
    
    # redis 示例
    import redis
    coon = redis.Redis(host='192.168.12.12')
    
    1. yield from 关键字
    # yield from (py3.3之后)
    def base():
      yield 88
      yield 99
     
    def bar():
      return 123
    
    def func():
      yield 1
      yield from base()
      yield from bar()   # 报错,int 不可迭代,如果可迭代,则循环取出
      yield 2
      yield 
    
    1. 生成器推导式
    v1 = [i for i in range(10)] # list推导式,立即产生数据
    def func():
      for i in range(10):
        yield i
    v2 = func()  # 与下面v2相同
    v2 = (i for i in range(10)) # 生成器推导式,不会立即产生数据
    
    1. 酸爽生成器

      • 所有生成器取一次就没有了

      • 不取不会执行,惰性运算

    # 示例1
    ret = filter(lambda n: n%3==0, range(10))
    print(len(list(ret)))				# 4
    print(len(list(ret)))				# 0
    
    # 示例2
    def add(n, i):
      return n + i
    
    def test():
      for i in range(4):
        yield i
        
    g = test()
    for n in [1, 10]:
      g = (add(n, i) for i in g)
      
    print(list(g))
    # [20 21 22 23 24]
    
    # 示例3
    def add(n, i):
      return n + i
    
    def test():
      for i in range(4):
        yield i
        
    g = test()
    for n in [1, 10, 5]:
      g = (add(n, i) for i in g)
      
    print(list(g))
    # [15, 16, 17, 18]
    

    5.8 异常处理

    1. 示例

    # 示例1
    try:
      val = input('请输入数字:')
      num = int(val)
    except Exception as e:
      print('操作异常')
    
    # 示例2
    import requests
    try:
      ret = requests.get('http://www.baidu.com')
    	print(ret.text)
    except Exception as e:
      print('请求异常')
    
    # 示例3
    def func(a):
      try:
        return a.strip()
      except Exception as e:
        pass
      return False
    
    v = func([1, 2, 3])
    print(v)
    
    # 练习1,函数接收一个list将list中的元素每个都加100
    def func(arg):
        li = []
        for items in arg:
            if items.isdecimal():
                li.append(int(items) + 100)
         return li
    
    # 写函数,接收一个list, 中全是url 访问地址,并获取结果
    import requests
    def	func(url_list):
      li = []
      try:
        for i in url_list:
          reponse = requests.get(i)
          li.append(reponse.text)
      except Exception as e:
        pass
      return li
    
    func(['http://www.baidu.com', 'http://www.google.com', 'http://www.bing.com'])
    
    # 比较异常 try 的位置不同,效果也不同
    import requests
    def	func(url_list):
      li = []
      for i in url_list:
          try:
              reponse = requests.get(i)
              li.append(reponse.text)
      		except Exception as e:
        			pass
      return li
    
    func(['http://www.baidu.com', 'http://www.google.com', 'http://www.bing.com'])
    
    
    # 得到的结果是text格式的文本文档
    reponse = requests.get('url', useragent:xxxxxx)
    

    2. 基本格式

    try:
      pass
    except ValueError as e:
      pass
    except IndexErro as e:
      pass
    except Exception as e:
      print(e)
    finally: 
      print('final')  # 无论对错都要执行的代码
    # e 代表异常信息,是Exception类的对象,有一个错误信息
    try:
      int('asdf')
    except Exception as e:
      print(e)
    
    try:
      int('asdf')
    except ValueError as e:
      print(e)
      
    try:
      int('asdf')
    except IndexError as e:
      print(e)
      
    # 即使遇到return 也会执行finally 
    def func():
      try:
        int('1')
        return
      except Exception as e:
        print(e)
      finally:
        print('final')
    

    3. 主动触发异常

    try:
      int('123')
      raise Exception('错误信息')   # 主动抛出异常
    except Exception as e:
      print(1)
    
    # 打开一个文件,
    def func():
      resutl = True
      try:
          with open('x.log', mode='r', encoding='utf-8') as f:
            	data = f.read()
          if 'henry' not in data:
            	raise Exception()
       except Exception as e:
         	result = False 
       return result
    

    4. 自定义异常

    # 示例1
    class MyException(Exception):
      pass
    try:
      raise MyException('haha,错了吧')
    except MyException as e:
      print(e)
    
    class MyException(Exception):
      def __init__(self, message):
          self.message = message
    try:
      raise MyExceptoin('123')
    except MyException as e:
      print(e.message)
    
  • 相关阅读:
    高阶函数
    如何理解data URL?
    JS对象的创建方式
    数组中的map方法
    奇怪的 Javascript
    什么场景不适合箭头函数
    协方差矩阵学习[转载]
    PAT 1140 Look-and-say Sequence [比较]
    PAT 1089 Insert or Merge[难]
    PAT 1096 Consecutive Factors[难]
  • 原文地址:https://www.cnblogs.com/henryw/p/11681381.html
Copyright © 2011-2022 走看看