第11日学习

  1. 函数的坑

    • 如果你的默认参数指向的是可变的数据类型,无论调用多少次默认参数,都是同一个

      #例1
      def func(name,nlist=[]):
        nlist.append(name)
        return nlist
      ret1=func('aa')
      print(ret1) #['aa']
      ret2=func('bb')
      print(ret2) #['aa','bb']
      #例2
      def func(name,nlist=[]):
        nlist.append(name)
        return nlist
      ret1=func('aa')
      print(ret1) #['aa']
      ret2=func('bb',[])
      print(ret2) #['bb']
      ret3=func('cc')
      print(ret3) #['aa','cc']
      print(ret1) #['aa','cc']
      print(ret2) #['bb']
      print(ret3) #['aa','cc']
    • 在函数中,如果你定义了一个变量,但是在定义这个变量之前对其引用了,那么解释器认为:语法问题

      count=1
      def func():
        print(count) #语法错误
        count=3
      func()
  1. 函数名的应用

函数名指向的是函数的内存地址,函数名+()就可以执行函数

  • 函数的内存地址

    def func():       
      print("呵呵")
    print(func) # 结果: <function func at 0x1101e4ea0>
  • 函数名相当于变量

    def func():        
      print("呵呵")    
    print(func)
    a = func # 把函数当成一个变量赋值给另一个变量
    a() # 函数调用 func()
  • 函数名可以作为容器类的元素

    def func1():
      print("in func1: 嘻嘻")
    def func2():
      print("in func2: 哈哈")
    def func3():
      print("in func3: 咯咯")
    def func4():
      print("in func4: 吱吱")
    lst = [func1, func2, func3, func4]
    for i in lst:
      i()
  • 函数名可以作为函数的参数

    def func1():
      print('in func1')

    def func2(f):
      print('in func2')
      f()

    func2(func1)
  • 函数名可以作为函数的返回值

    def func1():
      print('in func1')

    def func2(f):
      print('in func2')
      return f

    ret = func2(func1)
    ret() # ret, f, func1 都是指向的func1这个函数的内存地址
  1. 格式化输出

format

name='合格'
age=18
msg='我叫%s,今年%s' %(name,age)
msg1='我叫{},今年{}'. format(name,age)

f-string

1.任意表达式
print(f'{3*21}') # 63

name = 'barry'
print(f"全部大写:{name.upper()}") # 全部大写:BARRY
# 字典
teacher = {'name': '太星', 'age': 18}
msg = f"The teacher is {teacher['name']}, aged {teacher['age']}"
print(msg) # The comedian is 太星, aged 18
# 列表
l1 = ['太星', 18]
msg = f'姓名:{l1[0]},年龄:{l1[1]}.'
print(msg) # 姓名:太星,年龄:18.
2.插入表达式
def sum_a_b(a,b):
  return a + b
a = 1
b = 2
print('求和的结果为' + f'{sum_a_b(a,b)}')
3.多行f
name = 'barry'
age = 18
ajd = 'handsome'

# speaker = f'''Hi {name}.
# You are {age} years old.
# You are a {ajd} guy!'''

speaker = f'Hi {name}.'\
        f'You are {age} years old.'\
        f'You are a {ajd} guy!'
print(speaker)
4.细节问题
print(f"{{73}}") # {73}
print(f"{{{73}}}") # {73}
print(f"{{{{73}}}}") # {{73}}
m = 21
# ! , : { } ;这些标点不能出现在{} 这里面。
# print(f'{;12}') # 报错
# 所以使用lambda 表达式会出现一些问题。
# 解决方式:可将lambda嵌套在圆括号里面解决此问题。
x = 5
print(f'{(lambda x: x*2) (x)}') # 10

总结:f-string的格式化输出更加简洁,方便,易读。而且他的处理速度对之前的%s 或者format 有了较高的提升,所以尽量使用此种格式化输出

  1. 可迭代对象

    • 定义

      在python中,但凡内部含有‘_ _ iter _ _’方法的对象,都是可迭代对象

      例如:str list tuple dic set range 文件句柄等

    • 查看对象内部方法

      s1 = 'abcx'
      i = 100
      print(dir(s1)) #通过dir() 去判断一个对象具有什么方法

      print('__iter__' in dir(i))  # False
      print('__iter__' in dir(s1))  # True
    • 优缺点

      可迭代对象的优点:

      可以直观的查看里面的数据

      可迭代对象的缺点:

      1. 占用内存。

      1. 可迭代对象不能迭代取值(除去索引,key以外)。

      那么这个缺点有人就提出质疑了,即使抛去索引,key以外,这些我可以通过for循环进行取值呀!对,他们都可以通过for循环进行取值,其实for循环在底层做了一个小小的转化,就是先将可迭代对象转化成迭代器,然后在进行取值的。

  1. 迭代器

    • 定义

      在python中,内部含有'_ _ Iter _ '方法并且含有' _ _ next _ _'方法的对象就是迭代器

    • 判断是否为迭代器

      o1 = 'asex'
      o2 = [1, 2, 3]
      o3 = (1, 2, 3)
      o4 = {'name': 'da白','age': 18}
      o5 = {1, 2, 3}
      f = open('file',encoding='utf-8', mode='w')
      print('__iter__' in dir(o1))  # True
      print('__iter__' in dir(o2))  # True
      print('__iter__' in dir(o3))  # True
      print('__iter__' in dir(o4))  # True
      print('__iter__' in dir(o5))  # True
      print('__iter__' in dir(f))  # True
      # hsagn
      print('__next__' in dir(o1))  # False
      print('__next__' in dir(o2))  # False
      print('__next__' in dir(o3))  # False
      print('__next__' in dir(o4))  # False
      print('__next__' in dir(o5))  # False
      print('__next__' in dir(f))  # True
      f.close()
    • 可迭代对象转化成迭代器、迭代器取值

      #方法一:
      l1 = [1, 2, 3, 4, 5, 6]
      obj = l1.__iter__()
      print(obj)
      #方法二:
      obj=iter(l1)
      print(obj)

      #迭代取值
      print(next(obj))  #1
      print(next(obj))  #2
      print(next(obj))  #3
      print(next(obj))  #4
      print(next(obj))  #6
      print(next(obj))  #6
    • 优缺点

      优点:

      • 节省内存(迭代器在内存中相当于只占一个数据的空间:因为每次取值都上一条数据会在内存释放,加载当前的此条数据)

      • 惰性机制( next一次,取一个值,绝不过多取值)

      缺点:

      • 不能直观的查看里面的数据,速度慢

      • 取值时不走回头路,只能一直向下取值

  1. 可迭代对象和迭代器对比

    可迭代对象:

    是一个私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。

    应用:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。

    迭代器:

    是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。

    应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。(可参考为什么python把文件句柄设置成迭代器)。

  2.  

 

posted @ 2020-03-12 23:02  枫nian丶  阅读(73)  评论(0)    收藏  举报