函数进阶以及名称空间的引入(****)

今日内容

函数对象、函数的嵌套调用与定义、名称空间、作用域、闭包函数

昨日补充内容:

定义函数的三种方式:

1.空函数:可以快速的帮助自己构建项目框架,使项目架构清晰明了

def func():

  pass

这种方式应用频率非常高

比如购物车功能:

def register():

    pass

def login():

    pass

def pay():

    pass

2.无参函数:

def func():

  print('from func')

3.有参函数:

def func(x,y,*args,**kwargs)

  print(x,y,*args,**kwargs)

命名关键字参数:在函数定义阶段,写在*** 可变长参数之间的形参

特点:

  • 1.在给命名关键字参数传值的时候,只能用关键字为其传值
  • 2.在定义阶段,给人的感觉好像是z是默认值参数,放在了m这个位置参数之前,且应该报错,其实z和m都是命名关键字参数,而不是默认值参数和位置参数
def func(x,y=1,*args,z=3,m,**kwargs)

  print(x,y)  # 1 2

  print(args)  # (3,4,5,6,7,8)

  print(z,m)  # z=88,m=99

  print(kwargs)  # {'0':11,'s':22}

func(1,2,3,4,5,6,7,8,z=88,m=99,o=11,s=22)

函数对象

函数是第一类对象:函数名指向的值可以被当作参数传递

特点:

1.函数名可以被传递

name = 'jason'

x = name

print(x)  # 'jason'

def func():

  print('from func')

  print(func)

f = func

func()

print(f)

f()  # f其实指向的也是 函数func指向的 函数体代码的内存地址

2.函数名可以被当作参数传递给其他函数

def func():

  print('from func')
def index(args):   print(args) args() print('from index') index(1) index(func)

3.函数名可以被当作函数的返回值

def index():

  print('from index')

def func():

  print('from func')

  若return 11

res = func()

print(res)  #  结果为 11

res()

  若return index

res1 = func()

print(res1)  # <function index at 内存地址>

res1()

4.函数名可以被当作容器类型的参数

def func();

print('func')  # <function func at 内存地址>

print(func())  # None

l = [1,2,func,func()]

print(l)  # [1,2,<function func at 内存地址>,None]

ATM+购物车项目

需求:循环打印项目功能,供用户选择,用户选择谁就执行谁

def register():

    username = input('username>>>:').strip()

    pwd = input('password>>>:').strip()

    print(username,pwd)

    print('register...')

def login():

    print('login...')

def transfer():

    print('transfer...')

def shopping():

    print('shopping...')

def pay():

    print('pay...')

msg = ''''''

    1 注册

    2 登陆

    3 转账

    4 购物

    5 支付

''''''

func_dict = {

    '1':register,

    '2':login,

    '3':transfer,

    '4':shopping,

    '5':pay

}

while True:

    print(msg)

    choice = input('请选择你想要执行的功能>>>:').strip()

    if choice in func_dict:

        func_dict.get(choice)() '''等价于函数名()'''

    else:

        print('功能暂时没有')

函数的嵌套调用

在函数内部调用其它函数

def index():

  print('index')

def func():

  index()

  print('func')

func()  # 结果为 index func
def index():

  func()

  print('index')

def func():

  print('func')

index()  # 结果为 func index

比较大小:

def my_max(x,y):

  if x > y:

    return x

  return y

def my_max4(a,b,c,d):

  res1 = my_max(a,b)  # 返回值为a,b中大的值

  res2 = my_max(res1,c)

  res3 = my_max(res2,d)

  return res3

print(my_max4(1,2,10,4))  # 结果为10

函数的嵌套定义(重要)

def outer():

  x = 1

  print('outer')

def inner():

  print('inner')

  print(x)  # 报错

  print(inner)  # 报错

outer()  # 结果为outer 
def outer():

  x = 1

  print('outer')

def inner():

  print('inner')

print(inner)  # <function inner at 内存地址>

inner()
def outer():

  x = 1

  print('outer')  # 结果为outer 

def inner():

  print('inner')

  return inner

res = outer()

print(res)  #  <function outerr.<locals>.inner at 内存地址> 

res()  # 结果为inner 

函数的嵌套定义及应用场景

'''

写一个函数

该函数用户可以通过传参的不同来控制函数执行不同的代码

'''

def all_func(type):

  def register():

    print('register')

  def login():

    print('login')

  def pay():

    print('pay')

  if type == '1':

    register()

  elif type == '2':

    login()

  elif type == '3':

    pay()

all_func('1')

all_func('2')

all_func('3')

名称空间是什么?(重要)

名称空间就是放名字的地方

详细解释:存放的是变量名与变量值的内存地址的绑定关系的地方

要想访问一个变量的值,就必须先去名称空间中拿到对应的名字,才能够访问变量的值

名称空间的分类:
  • 1.内置名称空间python解释器提前给你定义好的名字(事先已经存放到内置名称空间中了);比如(len、max、min等)
  • 2.全局名称空间文件级别的代码,具体如下
x = 1

if l == 1:

  y = 2

  print(y)

while True:

  z = 3

for i in [1,2,3]:

  print(i)

如上代码中x,y,z都会放到全局名称空间,if、while、for无论嵌套多少层,它们内部所创建的名字都是全局名称空间的

  • 3.局部名称空间函数体内创建的名字都属于局部名称空间
名称空间的生命周期:
  • 内置名称空间:只要python解释器一启动就立马创建;关闭python解释器时,就自动销毁
  • 全局名称空间:只要你右键运行py文件,会自动创建,py文件运行结束时自动销毁
  • 局部名称空间:函数被调用时自动创建,函数执行结束后立即销毁(动态创建、动态销毁)
名称空间的查找顺序(重要):

1.需要先确定你当前在哪(大前提)

  • 1):站在全局:全局>>>内置
  • 2):站在局部:局部>>>全局>>>内置

2.例题

函数在定义阶段查找名字的顺序就已经固定了,不会因为函数的调用位置变化而改变

len = '我是全局名称空间的len'

def func():

  len = '我是局部名称空间的len'

  print(len)

print(len)  # 这里是在全局
def func():

  len = '我是局部名称空间的len'

  print(len)

print(len)  # 这里是内置len, built-in function len 
len = '我是全局名称空间的len'

def func():

  len = '我是局部名称空间的len'

  print(len)

func()  # 这里是局部名称空间的len
len = '我是全局名称空间的len'

def func():

  print(len)

func()  # 这里是全局名称空间

作用域

全局作用域:

  • 全局有效:内置名称空间,全局名称空间

局部作用域:

  • 局部有效:局部名称空间

global、nonlocal

1.global在局部修改全局的变量

x =1

def func():

  x = 2

func()

print(x)  # 结果为1
x = []  # 因为列表是可变类型,所以能够从局部修改全局 

def func():

  x.append('嘿嘿嘿')

func()

print(x)
# global 可以在局部修改全局的不可变数据类型

x = 1

def func():

  global x   # 修改全局变量,而不是创建局部名称空间

  x = 2

func()

print(x)  # 结果为2 

2.nonlocal 局部修改局部

def func():

  x = 1

def index():

  x = 2

print(x)

func()  # 结果为1
def func():

x = 1

  def index():

    nonlocal x

    x = 2

  print(x)

func()  # 结果为2

'''

global:局部修改全局,如果想修改多个,逗号隔开

nonlocal:局部修改局部,如果想修改多个,逗号隔开

'''

posted @ 2019-07-10 16:11  泡泡茶壶i  阅读(219)  评论(0编辑  收藏  举报