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方法取值,但是不直观,操作方法比较单一的数据集。
    • 当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。
posted @ 2020-04-17 02:22  Raoguozhong  阅读(100)  评论(0编辑  收藏  举报