第十一天

默认参数的坑

陷阱是针对默认参数是可变参数的数据类型

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

新特性:格式化输出


  1. 优点 格式简化
  2. 可以结合表达式,函数进行使用
  3. 效率提升很多
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 则是可迭代对象


优点:

  1. 存储的数据直接显示,比较直观.
  2. 拥有的方法比较多,操作方便

缺点:

  1. 占内存

  2. 不能直接通过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))

优点:

  1. 节省内存
  2. 惰性机制 next 一次只取一个值

缺点:

  1. 速度慢
  2. 不走回头路

可迭代对象和迭代器比较

  • 可迭代对象是一个操作方式比较多 ,比较直观,存储数据较少的(几百万格对象,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
posted @ 2020-02-26 00:32  小丁变优秀  阅读(207)  评论(1)    收藏  举报