第十一天
默认参数的坑
陷阱是针对默认参数是可变参数的数据类型
def func(name,alist=[])
alist.append(name)
return alist
ret1=func("alex")
print(ret1)
# ["alex"]
ret2=func("太白金星")
print(ret2)
#["alex","太白金星"] ret1 和ret2 id 一样 他俩是一个
因为第二个函数的
//默认参数没有变,
所以还是使用上面的那一个
//若过你的默认参数指向的是可变的数据参数,那么无论你调用多少次这个默认参数,都是同一个
def func (a,list=[]):
list.append(a)
return list
print(func(10,)) //[10]
print(func(20,[])) // [20] #这一次默认参数传值了
print(func(100,)) // [10,100]
#//默认参数没有传值 直接使用第一次改变之后的 list
#对比一下
l1=[]
l1.append(10,)
//[10]
l2=[]
l2.append(20,)
//[20]
l1.append(100,)
//[10,100]
#改变一下形式
def func (a,list=[]):
list.append(a)
return list
print(func(10,))
print(func(20,[]))
print(func(100,))
print(ret1) // [10,100]
print(ret2) //[20]
print(ret3) //[10,100]
#三个执行之后再打印 所以 ret1 和ret3 是一个东西
作用域的坑
count=1
def func():
print(count)
count= 3
func() # //报错 他会认为你是先打印 再定义 #//和下面的是同一种类型的
// print(a)
a=1 #//报错 他会认为你是先打印 再定义
//
count=1
def func():
print(count)
# count= 3 //删除这一行 就不会报错
func()
#//这个没有一点问题
global在局部作用域声明一个全局变量
想要在全局里面使用 局部的变量
#//想要在全局里面使用 局部的变量
def func():
name= "小屋"
print(name)
func()
print(name) #//报错 函数使用之后 name 就销毁了
#// 全局里面找不到 所以报错了
#// 带global的
def func():
global name
name= "小屋"
func() #// 需要让func()函数先执行
print(name) #//函数已经执行了,全局变量里面已经有一个name //所以打印name 的时候 就找到了
#打印出 "小屋"
修改一个全局变量
count=1
def func():
global count
count+=1
func() #//不会报错
nonlocal 局部作用域 内层函数对外层函数的局部变量进行修改
//注意不能修改全局变量
def a ():
count= 1
def inner():
nonlocal count+=1
print(count) #//count 1
inner()
print(count) #//count 2
a()
函数名
1函数名指向的是函数的内存地址
函数名就是一个变量
func
函数名+() 直接运行一次函数
func()
// 实际上是内存地址加括号 才会执行函数
2函数名就是变量
def func():
print(666)
f=func
f1=f
f2=f1
f2() //可以执行函数
func f f1 f2 全部指向那个内存地址
def func1():
print(1)
def func2():
print(2)
func2=func1
func2() #执行的是第一个函数
3函数名可以作为容器类型的变量
def func1():
print(1)
def func2():
print(2)
def func3():
print(3)
l1=[func1,func2,func3] #//一下子执行三个函数
for i in l1:
i()
4函数名可以作为函数的参数
def func():
print("in func")
def func1(x):
x()
print("in func1")
func1(func)
5函数名可以作为函数的返回值
def func():
print("func")
def func1():
print("func1")
return x
ret=func1()
ret() # func()
#打印 func1 func
新特性:格式化输出
- 优点 格式简化
- 可以结合表达式,函数进行使用
- 效率提升很多
name="小屋"
age=18
msg=f"我叫{name},今年{age}"
print(msg)
#//还可以加表达式
dic={"name"="小屋","age"=18}
msg=f"我叫dic["name"],今年dic["age"]"
print(msg)
#//我叫小屋 今年18
count=7
print(f"最终结果是:{count**2}")
#//最终结果是:49
结合函数写
def _sum(a,b):
return a+b
msg=f"最终结果是:{_sum(10,20)}"
print(msg)
迭代器
可迭代对象
目前学过的可迭代对象: str list tuple dict set range文件句柄
对象 :一个实实在在的值
可迭代:更新迭代.重复的,循环的一个过程更新迭代都有新的内容.可以进行循环更新的一个实实在在的值
专业角度:内部含有'iter'方法的对象,可迭代对象
获取一个对象的所有方法:dir()
s1="asdasdasd"
print(dir(s1))
判断是否是可迭代对象
print ('_ iter _ ' in dir(s1) ) #// 如果是True 则是可迭代对象
优点:
- 存储的数据直接显示,比较直观.
- 拥有的方法比较多,操作方便
缺点:
-
占内存
-
不能直接通过for 循环,不能直接取值(索引,key)
迭代器
字面意思:更新迭代的工具
专业角度:内部含有"_ iter_" 方法,并且含有 "_ _ next__"方法的对象就是迭代器
判断
"_ iter_" and "_ _ next__" in dir(对象)
可迭代对象可以转换成迭代器 obj=iter(s1)
s1="asdf"
obj=iter(s1)
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
#2
l1=[1,2,3,4]
obj=iter(l1)
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj))
优点:
- 节省内存
- 惰性机制 next 一次只取一个值
缺点:
- 速度慢
- 不走回头路
可迭代对象和迭代器比较
- 可迭代对象是一个操作方式比较多 ,比较直观,存储数据较少的(几百万格对象,8g内存是可以承受的)的一个数据集
- 当侧重于数据可以灵活处理,并且内存足够,将数据及设置为可迭代对象是明确的选择
- 是一个非常节省内存 可以直接通过next方法取值 但是不直观 操作方法比较单一的数据集
- 当你的数据量过大,大到足以撑爆你的内存 为首选因素时,将数据集设置为迭代器是一个不错的选择
使用while 进行迭代
利用while 循环模拟for循环 对可迭代对象进行取值的机制
l1=[1,2,3,4,5,6,7]
obj=iter(l1)
while 1:
try:
print(next(obj))
except StopIteration:
break
对代码有疑问欢迎交流
一个python爱好者 :
微信:at8685b

浙公网安备 33010602011771号