• Python全栈-第十一课 学习笔记


    Python第十一课 学习笔记

    补充和global nonlocal

    • 补充

    • 默认参数的陷阱

    • # 默认参数的陷阱:
      def func(name,sex='男'):
      	print(name)
      	print(sex)
      func('jarvis')
      
      # 陷阱只针对于默认参数是可变的数据类型:
      def func(name,alist=[]):
      	alist.append(name)
      	return alist
      
      ret1 = func('one')
      print(ret1,id(ret1))  # ['one']
      ret2 = func('two')
      print(ret2,id(ret2))  # ['one','two']
      
      # 如果你的默认参数指向的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个。
      def func(a, list=[]):
      	list.append(a)
      	return list
      print(func(10,))  	# [10]
      print(func(20,[]))  # [20]
      print(func(100,))  	# [10,100]
      
      def func(a, list= []):
      	list.append(a)
      	return list
      ret1 = func(10,)  	# ret1 = [10]
      ret2 = func(20,[])  # ret2 = [20]
      ret3 = func(100,)  	# ret3 = [10,100]
      print(ret1)  		# [10,100]  re1和re3使用的同一个列表
      print(ret2)  		# [20]
      print(ret3)  		# [10,100]
      
    • 局部作用域的坑

    • count = 1
      def func():
      	count += 1
      	print(count)
      func()
      
      # 函数中,如果你定义了一个变量,但是在定义这个变量之前对其引用了,那么解释器认为:语法问题(先引用后定义)
      # 你应该在使用之前先定义。
      count = 1
      def func():
      	print(count)
      	count = 3
      func()
      
    • global nonlocal

    • # global
      # 在局部作用域声明一个全局变量。
      name = 'jarvis'
      
      def func():
          global name
          name = 'one'
          print(name)
      func()
      print(name)
      
      # 修改一个全局变量
      count = 1
      def func():
          global count
          count += 1
          
      print(count)   
      func()
      print(count)
      
      # nonlocal
      # 不能够操作全局变量。
      count = 1
      def func():
          nonlocal count
          count += 1
      func()				#报错
      # 局部作用域:内层函数对外层函数的局部变量进行修改。
      def wrapper():
          count = 1
          def inner():
              nonlocal count
              count += 1
          print(count)
          inner()
          print(count)
      wrapper()
      

    函数名的运用

    • # 函数名 + ()就可以执行此函数。
      def func():
      	print(666)
      
      func()
      # 函数名指向的是函数的内存地址。
      a = 1
      a()
      func() 					#报错
      
      def func():
      	print(666)
      
      print(func,type(func))  # <function func at 0x000001BA864E1D08>
      func()
      
      # 函数名就是变量
      def func():
      	print(666)
      
      f = func
      f1 = f
      f2 = f1
      
      f()
      func()
      f1()
      f2()
      
      def func():
      	print('in func')
      
      def func1():
      	print('in func1')
      
      func1 = func
      func1()
      
      # 函数名可以作为容器类数据类型的元素
      def func1():
      	print('in func1')
      
      def func2():
      	print('in func2')
      
      def func3():
      	print('in func3')
      
      l1 = [func1,func2,func3]
      for i in l1:
      	i()
      
      # 函数名可以作为函数的参数
      def func():
      	print('in func')
      
      def func1(x):
      	x()  				# func()
      	print('in func1')
      
      func1(func)
      
      # 函数名可以作为函数的返回值
      def func():
          print('in func')
      
      def func1(x): 			# x = func
          print('in func1')
          return x
      
      ret = func1(func)  		# func
      ret()  					# func()
      
      

    新特性:格式化输出

    • 格式化输出

    • # %s format
      name = 'jarvis'
      age = 18
      msg = '我叫%s,今年%s' %(name,age)
      msg1 = '我叫{},今年{}'.format(name,age)
      
      # 新特性:格式化输出
      name = 'jarvis'
      age = 18
      msg = f'我叫{name},今年{age}'
      print(msg)
      
      # 可以加表达式
      dic = {'name':'jarvis','age': 18}
      msg = f'我叫{dic["name"]},今年{dic["age"]}'
      print(msg)
      
      count = 7
      print(f'最终结果:{count**2}')
      name = 'jarvis'
      msg = f'我的名字是{name.upper()}'
      print(msg)
      
      # 结合函数写:
      def _sum(a,b):
          return a + b
      
      msg = f'最终的结果是:{_sum(10,20)}'
      print(msg)
      # ! , : { } ;这些标点不能出现在{}这里面
      # 优点
      # 结构更加简化
      # 可以结合表达式,函数进行使用
      # 效率提升很多
      

    迭代器

    • 可迭代对象

      • 字面意思:对象:python中一切皆对象。一个实实在在存在的值,对象。
      • 可迭代:更新迭代。重复的,循环的一个过程,更新迭代每次都有新的内容,可以进行循环更新的一个实实在在的值。
      • 专业角度:可迭代对象:内部含有'__iter__'方法的对象,可迭代对象。
      • 目前学过的可迭代对象:str list tuple dict set range 文件句柄
    • 获取对象的所有方法并且以字符串的形式表现:dir()

    • 判断一个对象是否是可迭代对象

      s1 = 'fjdskl'
      l1 = [1,2,3]
      print(dir(s1))
      print(dir((l1)))
      print('__iter__' in dir(s1))
      print('__iter__' in dir(range(10)))
      
    • 可迭代对象小结

      • 字面意思:可以进行循环更新的一个实实在在的值。

      • 专业角度: 内部含有'__iter__'方法的对象,可迭代对象。

      • 判断一个对象是不是可迭代对象: '__iter__' in dir(对象)

      • str list tuple dict set range

      • 优点:

        • 存储的数据直接能显示,比较直观
        • 拥有的方法比较多,操作方便
      • 缺点:

        • 占用内存
        • 不能直接通过for循环,不能直接取值(索引,key)
    • 迭代器的定义

      • 字面意思:更新迭代,器:工具:可更新迭代的工具。
      • 专业角度:内部含有'__iter__'方法并且含有'__next__'方法的对象就是迭代器。
      • 可以判断是否是迭代器:'__iter__' and '__next__' 在不在dir(对象)
    • 判断一个对象是否是迭代器

      with open('文件1',encoding='utf-8',mode='w') as f1:
          print(('__iter__' in dir(f1)) and ('__next__' in dir(f1)))
      
    • 迭代器的取值

      #可迭代对象可以转化成迭代器
      s1 = 'fjdag'
      obj = iter(s1)  	# s1.__iter__()
      print(obj)
      print(next(obj)) 	# print(obj.__next__())
      print(next(obj)) 	# print(obj.__next__())
      print(next(obj)) 	# print(obj.__next__())
      print(next(obj)) 	# print(obj.__next__())
      print(next(obj)) 	# print(obj.__next__())
      #多一个就会报错
      
      l1 = [11,22,33,44,55,66]
      obj = iter(l1)
      print(next(obj))
      print(next(obj))
      print(next(obj))
      print(next(obj))
      print(next(obj))
      print(next(obj))
      
    • 可迭代对象如何转化成迭代器

      iter([1,2,3])

    • while循环模拟for循环机制

      l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652]
      # 将可迭代对象转化成迭代器。
      obj = iter(l1)
      while 1:
          try:
              print(next(obj))
          except StopIteration:
              break
      
    • 小结

      • 字面意思:更新迭代,器:工具:可更新迭代的工具。
      • 专业角度:内部含有'__iter__'方法并且含有'__next__'方法的对象就是迭代器。
      • 优点:
        • 节省内存
        • 惰性机制,next一次,取一个值
      • 缺点:
        • 速度慢
        • 不走回头路
    • 可迭代对象与迭代器的对比

    • 可迭代对象

      • 可迭代对象是一个操作方法比较多,比较直观,存储数据相对少(几百万个对象,8G内存是可以承受的)的一个数据集。
      • 当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
    • 迭代器
      • 迭代器是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
      • 当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。
  • 相关阅读:
    2020 牛客 NOIP 赛前集训营 提高级(第四场) B-色球 平衡树模板
    P4084 [USACO17DEC]Barn Painting G
    CSP-S 2020
    CQOI 2020省选
    我回来了
    hdu3605(二分图多重匹配伪模板)
    舞动的夜晚(二分图的必须边和可行边)
    poj3436(最大流+拆点)
    P2954([USACO09OPEN]移动牛棚Grazing2,dp)
    CSP-S 2020 游记
  • 原文地址:https://www.cnblogs.com/rgz-blog/p/12717226.html
Copyright © 2020-2023  润新知