Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器

mac2022-06-30  86

Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器

一丶关键字:global,nonlocal

global 声明全局变量:

​ 1. 可以在局部作用域声明一个全局变量

​ 2. 可以修改全局变量

# 解释器认为: 如果你在局部作用域对一个变量进行修改,局部作用域已经定义了好这个变量 # 异常: # UnboundLocalError: local variable 'count' referenced before assignment ####相当于局部声明的变量,剪切到全局 count=0 print(locals()) # count:0 def func(): global count #定义成全局变量 count+=1 # 此处由于 要修改count的值, 现在函数内没有定义count的变量, 如果想要修改全局变量count 需要global声明一下 print(locals()) # 查看当前(现在就是局部空间)空间的变量和值, 没count变量 func() print(locals()) # 查看当前(现在就是全局空间)空间的变量和值 ,count:1

nonlocal 局部作用域如果想对父级作用域的变量(python3x新加的功能):

​ 1.可以对父级别作用域的变量进行修改,并且在当前作用域创建 ​ 2.不能操作全局作用域

####复制 , 共用一块内存地址 def func(): count=0 #局部变量 def inner(): nonlocal count #inner函数内 修改 count 变量, 需要nonlocal声明 count+=3 print(count) print(id(count)) #id() 查看这个inene函数中count变的内存地址 -->1952940208(内存地址) print(locals()) #查看当前作用域中的变量和值 {'count': 3} inner() print(locals()) #{'inner':<function func.<locals>.inner at 0x00000140E1ABBD90>, 'count': 3} print(id(count)) #id() 查看这个func函数中count变的内存地址 1952940208(内存地址) func()

二丶形参中---默认参数的坑

###当你的默认参数的数据类型是可变的数据类型时 千万注意,使用的是同一个可变类型数据的内存地址 so看代码? #默认参数是字典 def func(a,b={}): b[a+1]=a return b print(func(1,)) print(func(2,)) print(func(3,)) print(func(5,)) #默认参数是列表类型 def func(a,b=[]): b.append(a) return b print(func(1,)) print(func(1)) print(func(1)) func(1,2) ###例题 #例1 def extendList(val,list=[]): #默认创建一个列表 list.append(val) return list list1 = extendList(10) # [10 ,'a'] # 往默认列表添加元素 list2 = extendList(123,[]) # [123,] # list被一个新的列表替换,新列表是一个空列表,so 只添加123 list3 = extendList('a') #[10,'a'] # 继续往默认的列表添加内容 print('list1=%s'%list1) ##上面的操作完成之后, list1 和list3 使用的是同一个内存地址, 共享一个列表 print('list2=%s'%list2) ##上面的操作完成之后, list2 使用的是新的列表,so . print('list3=%s'%list3) ##上面的操作完成之后, list1 和list3 使用的是同一个内存地址, 共享一个列表 # 例2 这道题和上面的题一样,但是 ,别忘记了print() 打印当前的操作完成之后的结果. def extendList(val,list=[]): list.append(val) return list print('list1=%s'% extendList(10)) # [10] # 往默认列表添加元素, 就直接打印 so .现在这个默认列表就只有 10 print('list2=%s'% extendList(123,[])) #[123] #往新的列表添加元素, so 和默认列表毫无关系 print('list3=%s'% extendList('a')) #[10,'a'] #往默认列表添加元素,之前已经添加了10 ,so 现在追加了'a'元素,so,现在默认列表就有[10,'a']

三丶函数名的应用

函数名:就是一个特殊的变量 , 别称:第一类对象

​ 函数名指向的是一个函数的内存地址,函数名加上()就能够执行函数

###废话不多说,上代码? ## 1. 函数名可以当做一个变量 ,具有变量的赋值功能 def func(): print('in func ') print(func) #打印函数func的内存地址 自己打 a=func # 将函数的内存地址给了a c=a #相当于c变量拿到 a 或者 func的函数内存地址 c() #相当于 c()=func(), 执行函数func() ## 2. 函数名容器类类型的元素 def func1(): print('in func1') def func2(): print('in func2') def func3(): print('in func3') li=[func1,func2,func3] for el in li: # 循环每个元素, el就是函数的内存地址 el() # 执行每个函数 #拓展?:你要是有2000个函数,你总不能写2k个"函数明()". 用for循环执行2k个函数 so easy # 3. 函数名 可以作为函数的实参 def func(argv): argv() #接收传来的函数名+() --->执行这个函数 print('in func') def inner(): print('in inner') func(inner) #把其他的函数的名作为参数传给func函数的argv # 4.函数名可以作为函数的返回值 def func(): print('in func') return inner #返回 其他函数的函数名, def inner(): print('in inner') func()() # 相当于func()=inner --->inner() 执行inner函数 #5. 函数名+() 可以执行函数 def func(): print('被执行了') func()

四丶python新特性字符串输出:f-string

新特性:f-strings 是python3.6 格式化输出新的写法,效率高,更简化,好用

####看代码? #### 用法格式 name='宇宙盖世无敌小keNai,?嘻嘻' s=f'我叫 {name}' # {变量,函数名(),表达式} ,除了特殊的字符如: ;分号 :冒号 ,逗号(变量前) ! #用法①: 直接操作字符串 s1='李四' s2=f'哒哒哒哒哒{s1.upper()}' print(s2) #用法②: 放置列表元素 li=['太白',18,176] s1=f'{li[0]},{li[1]} ,{li[2]}' print(s1) #用法③: 可以结合函数 def func(a,b): return a+b s=f'{func(1,2)}' print(s)

五丶可迭代对象

含义:

​ 可以重复的迭代的实实在在的东西

专业角度:

​ 内部__ iter __ 方法的对象,就是可迭代对象

#常见的可迭代对象: list , tuple ,dict ,str # 内置函数 ,查看所有方法,属性 ,得到的所有方法都以字符串的形式放在列表中 print(dir(str)) #验证是不是 可迭代对象 s1 = '不打广告' i = 100 print('__iter__' in dir(i)) # False print('__iter__' in dir(s1)) # True #常用的方法验证 xx 是不是一个可迭代对象 print('__iter__' in dir(str)) #可迭代对象的优缺点 #优点: 1.直观 2.操作方法多 #缺点: 1. 消耗内存较大 2. 不能迭代取值(索引)

六丶迭代器

含义:

​ 是一个可以迭代取值的工具

专业角度:

​ 内部含有 __iter__方法 并且含有 __next__方法 就是迭代器

#迭代器是看不到内存地址 ####可迭代对象转化成迭代器: #可迭代对象转化成迭代器 , 内置函数iter() 和 __iter__() 两种方式 li=[1,2,3] obj=iter(li) #把迭代对象转换成迭代器 objg=li.__iter__() #把迭代对象转换成迭代器 print(type(obj),type(objg)) #<class 'list_iterator'> print(obj) # <list_iterator object at 0x000002075D219518> 迭代器 ####迭代器可以迭代取值, 利用内置函数next()进行取值 . 取完值,值就消失了 li=[1,2,3] obj=iter(li) print(next(obj)) # 迭代一次,取值一次,值取完就没了.销毁 print(next(obj)) print(next(obj)) print(next(obj)) # 当迭代器中没有值可取了 ,会把报错 StopIteration ####利用while 模拟 for 循环内部循环可迭代对象的机制 #1.先将可迭代对象转换成迭代器 #2.利用next对迭代对象进行取值 #3.利用异常处理try一下 防止报错~~ #方法1 try: li = [1, 2, 3, 4, 5] li_itera = iter(li) while 1: print(li_itera.__next__()) except StopIteration: pass #方法2 li = [1, 2, 3, 4, 5] li_itera = iter(li) while 1: try: print(next(li_itera)) except: break #迭代器是一条路走到底(记录位置) li=[1,2,3,4,] obj=iter(li) for index in range(2): # 1 2 ,取完值,值就销毁 print(obj.__next__()) for index in range(1): # 3 print(obj.__next__())

七丶可迭代对象与迭代器的对比

####可迭代对象: 可迭代对象是一个操作比较灵活(比如列表,字典的增删改查,字符串的常用操作方法等),直观,效率相对高, 但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。 ####迭代器: 可以记录取值位置,以直接通过循环+next方法取,迭代器是一个非常节省内存,满足惰性机制, 但是相对效率低,操作方法比较单一的数据集。(可参考为什么python把文件句柄设置成迭代器)

转载于:https://www.cnblogs.com/dengl/p/11051725.html

最新回复(0)