七天学会Python基础-第五天2/2-global-fstring-迭代器
-
nonlocal global
-
global
-
在局部作用域声明一个全局变量
-
def func(): global name # 声明name为全局变量 name ="taibai" func() print(name)
-
-
在局部作用域修改一个全局变量
-
count=0 def func(): global count # 声明此处的变量count为全局变量 count+=1 func() print(count)
-
-
-
nonlocal
-
不能够操作全局变量
-
内层函数对外层函数的局部变量进行修改
-
def wrapper(): count=1 def inner(): nonlocal count # 声明此处的变量count为上一层的全局变量 count+=1 print(count) # 1 inner() print(count) # 2 wrapper() print(count)
-
-
-
-
函数名的运用(其实函数名就是一个变量,只不过函数名指向的是函数的内存地址)
-
函数名+()可以执行函数
-
函数名就是变量
-
def wrapper(): count=1 def inner(): nonlocal count # 声明此处的变量count为上一层的全局变量 count+=1 print(count) # 1 inner() print(count) # 2 f=wrapper f1=f f2=f1 f2() # 依然可以执行 f1() f() wrapper()
-
-
函数名可以作为容器类数据类型的元素
-
def func1(): print("in func1") def func2(): print("in func2") def func3(): print("in func3") lst=[func1,func2,func3] for i in l1: i()
-
-
函数名可以作为函数的参数
-
def func(): print("in func") def func1(x): x() print("in func1") func1(func) # in func in func1
-
-
函数名可以作为函数的返回值
-
def func(): print("in func") def func1(x): print("in func1") return x ret=func1(func) ret() # in func1 # in func
-
-
-
新特性:格式化输出(f-string)
-
字符串与变量拼接写法:
-
# 旧的写法 name="taibai" age=18 msg1="我叫%s,今年%s"%(name,age) msg2="我叫{},今年{}".format(name,age) # f-string msg3=f"我叫{name},今年{age}"
-
-
可以加表达式
-
dic={"name":"alex","age":"73"} msg=f"我叫{dic[dic['name']},今年{dic['age']}" # 除了字典,还可以用列表 count=7 print(f"最终结果:{count**2}") name="taibai" msg=f"我的名字是{name.upper}" # 结合函数写 def _sum(a,b): return a+b msg=f"最终的结果是:{_sum(10,20)}" print(msg) -
优点:
- 结构更简化。
- 可以结合表达式,函数进行使用
- 效率提升了很多
-
注意(暂作了解):
- 大括号中不能出现!,:
-
-
-
迭代器:
-
可迭代对象
- 字面意思:Python中一切皆对象。一个实实在在存在的值,对象。
- 可迭代:更新迭代。重复的,类似于循环的这样一个过程,更新迭代是每次重复都有新的东西。可以进行循环更新的一个实实在在的值。
- 专业角度:内部含有
'__iter__'方法的对象,就叫可迭代对象 - 目前学过的可迭代对象:str、list、tuple、dict、set、range、文件句柄
-
获取对象的所有方法并且以字符串的形式表现:dir
- dir(str1),返回一个列表,将这个对象的所有方法以字符串的形式放到一个列表中进行返回
-
判断一个对象是否是可迭代对象
print('__iter__' in dir(str1))
-
小结:
-
字面意思:可以进行循环更新的一个实实在在的值。
-
专业角度:内部含有
__iter__方法的对象,就是可迭代对象。 -
判断一个对象是不是可迭代对象:
__iter__ in dir(对象) -
目前学过的可迭代对象:str、list、tuple、dict、set、range
-
优点:
- 存储的数据直接能显示,比较直观。
- 拥有方法比较多,操作比较方便
-
缺点:
-
占用内存。
-
不能直接通过for循环,不能直接取直(索引,key除外)
-
l1=[1,2,3,4] for i in l1: print(i) # 在这里可以使用for循环是因为for循环内部进行了一步转化,转化成了迭代器
-
-
-
-
迭代器
-
迭代器的定义
- 更新迭代,器:工具:可更新迭代的工具
- 专业角度:内部含有
__iter__方法,并且含有__next__方法的对象就是迭代器。
-
判断一个对象是否是迭代器
-
可以判断是否是迭代器:
__iter__ and __next__在不在dir(对象),目前学到的只有文件句柄是一个迭代器,其余的只是可迭代对象 -
with open('文件1',mode='w',encoding='utf-8') as f: print('__iter__' in dir(f) and '__next__' in dir(f)) # True s='abc' print('__iter__' in dir(s) and '__next__' in dir(s)) # False
-
-
迭代器的取值
-
利用迭代器进行一个一个取值(个人理解为游标)
-
# 方式1 print(next(obj)) # 方式2 print(obj.__next__())
-
-
-
可迭代对象如何转化成迭代器
-
将可迭代对象抓化成迭代器
-
s1='abc' # 方式1 obj=iter(s1) # 方式2 obj=s1.__iter__() # 底层实现方式一样 print(obj) # <str_iterator object at 0x00000267C342CF70>
-
-
-
while循环模拟for循环机制
-
l1=[1,2,3,4,5,6,6,7,8,9] # 将可迭代对象转化为迭代器 obj=iter(l1) while 1: try: print(next(obj)) except StopIteration: break
-
-
小结
- 字面意思:更新迭代,器工具:可更新迭代的工具。
- 专业角度:内部含有
__iter__方法,并且含有__next__方法的对象就是迭代器。 - 迭代器的优点:
- 节省内存,非常节省内存。所以文件句柄使用迭代器
- 惰性机制,next一次,取一个值,绝不过多取值,(按需取值)
- 有一个迭代器模式可以很好解释上面这两条:迭代是数据处理的基石。扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项。这就是迭代器模式
- 迭代器的缺点:
- 速度慢,不能直观的查看里面的数据
- 取值时不走回头路,只能一直往下取值,每次迭代都会记住位置,下次继续
-
可迭代对象与迭代器的对比
- 可迭代对象
- 可迭代对象是一个操作方法比较多,比较直观,存储数据相对少(几百万个对象,8G内存是可以承受的)的一个数据集。
- 当你侧重于对数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
- 迭代器
- 是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法进行取值,但是不直观,操作方法比较单一(next)的数据集
- 当你数据量过大,大到足以撑爆你的内存或者你以节省空间为首选因素时,将数据集设置为迭代器是一个不错的选择。
- 可迭代对象
-
-
补充
-
默认参数参数的陷阱
- 这个陷阱只针对于默认参数是可变的数据类型
- 如果默认参数指向的是可变数据,那么无论你调用多少次这个默认参数,都是同一个,
- 在内存中这个数据永远是一个,也就是每次调用的这个可变数据id永远相同,这个默认参数既不在全局也不在局部
-
局部作用域的坑
-
count=0 def func(): print(count) count=0 -
此时就会报错(顶以前引用变量),若将第4行进行注释就没有错误,或者将第四行移动到打印语句上方
-
-

浙公网安备 33010602011771号