四、global和nonlocal、函数名应用、格式化输出

一、面试的常见坑

  • 形参角度,默认参数的坑

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

# 默认参数的陷阱:
def func(name,sex='男'):
   print(name)
   print(sex)
func('alex')
#结果:
alex


# 陷阱只针对于默认参数是可变的数据类型:
def func(name,alist=[]):
   alist.append(name)
   return alist

ret1 = func('alex')
print(ret1,id(ret1))
ret2 = func('太白')
print(ret2,id(ret2))
#结果:共用一个列表
['alex'] 2289216485128
['alex', '太白'] 2289216485128

# 如果你的默认参数指向的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个。
def func(name,alist=[]):
   alist.append(name)
   return alist

print(func(10,))  # [10,]
print(func(20,[]))  # [20,]
print(func(100,))  # [10,100]
# print(func(20,[]))是name传值为10,alist传值为[],等同于新建立一个列表,不与print(func(10,))建立的列表用一个;print(func(100,)) 没有建立新列表,与print(func(10,))建立的列表用一个
# 相当于以下代码:
# l1 = []
# l1.append(10)
# print(l1)
# l2 = []
# l2.append(20)
# print(l2)
# l1.append(100)
# print(l1)

# 与上个代码对比:
def func(a, list= []):
   list.append(a)
   return list
ret1 = func(10,)    # ret1 = [10,]
ret2 = func(20,[])  # ret2 = [20,]
ret3 = func(100,)   # ret3 = [10,100]此时因为ret1用同一个列表,所以ret1也改变
print(ret1)  # [10,100] (与上个代码对比,此处ret1没先打印,因而被ret3改变,然后打印)
print(ret2)  # [20,]
print(ret3)  # [10,100]

 

  • 局部作用域的坑

在函数中,如果你定义了一个变量,但是在定义这个变量之前对其引用了,那么解释器认为:语法问题,你应该在使用之前先定义


count = 1
def func():
   print(count)
   count = 3
func()
# 代码在print(count)处飘红,local variable 'count' referenced before assignment,就是赋值前引用的本地变量“count”

 二、global nonlocal

    • global:

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


        name = 'alex'
        def func():
           name = '太白'
           print(name)
        func()
        print(name)
        # 结果:
        太白
        alex


        # 还是以上代码加入global,
        name = 'alex'
        def func():
           global name
           name = '太白'
           print(name)
        func()
        print(name)
        # 结果:
        太白
        太白


        name = 'alex'
        def func():
           global name
           name = '太白金星'
        print(name)       #alex
        print(globals())  #获取全局变量
        func()
        print(name)       #太白金星
        print(globals()   #获取全局变量
      2. 修改一个全局变量


        count = 1
        def func():
           #print(count) ,报错,在全局声明之前使用名称“count”
           global count
           count += 1
        print(count)     # 1
        func()
        print(count)     # 2
        #将全局变量的count = 1,在函数中改成了2
    • nonlocal:

      1. 不能够操作全局变量


        count = 1
        def func():
           nonlocal count
           count += 1
        func()
        # 会报错,nonlocal是不能用来操作全局变量的
      2. 局部作用域:内层函数对外层函数的局部变量进行修改


        def wrapper():
           count = 1
           def inner():
               nonlocal count
               count += 1
           print(count)   # 1
           inner()
           print(count)   # 2
        wrapper()

  三、函数名的运用

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

  • 函数名就是变量

  • 函数名可以作为容器类数据类型内容的元素

  • 函数名可以作为函数的参数

  • 函数名可以作为函数的返回值


#1.函数名指向的是函数的内存地址
def func():
   print(666)
func()

#2.函数名就是变量
def func():
   print(666)
f = func
f1 = f
f2 = f1
f()      #相当于func() 666
func()   #相当于func() 666
f1()     #相当于func() 666    
f2()     #相当于func() 666

def func():
   print('in func')
def func1():
   print('in func1')
func1 = func
func1()    #相当于func() in func

#3.函数名可以作为容器类数据类型的元素
def func1():
   print('in func1')

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

def func3():
   print('in func3')
l1 = [func1,func2,func3]
for i in l1:
   i()
#结果依次调用 func1,func2,func3
in func1
in func2
in func3

#4.函数名可以作为函数的参数
def func(a):
   print(a)
   print('in func')
b = 3
func(b)
print(func)


def func():
   print('in func')

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

func1(func)

# #5.函数名可作为函数的返回值
def func():
   print('in func')

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

ret = func1(func)
ret()

 

  四、新特性:格式化输出(3.6x以后的适用)

可以加表达式,可以结合函数写:


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

# 新特性:格式化输出
name = '太白'
age = 18
msg = f'我叫{name},今年{age}'
print(msg)

count = 7
print(f'最终结果:{count**2}')

name = 'barry'
msg = f'我的名字是{name.upper()}'
print(msg)

#加表达式:
dic = {'name':'alex','age':13}
msg = f'我叫{dic["name"]},今年{dic["age"]}'
print(msg)

#结合函数:
def _sum(a,b):
   return a+b
msg = f'最终结果为:{_sum(10,20)}'
print(msg)

# ! , : { } ;这些标点不能出现在{} 这里面。

优点:

    1. 结构更加简化

      1. 可以结合表达式、函数进行使用

      2. 效率提升很多

posted on 2019-05-25 10:26  雨后清明  阅读(222)  评论(0编辑  收藏  举报

导航