今日内容:
1、*与**在形参与实参中的应用
2、函数对象
3、函数嵌套
4、名称空间与作用域
# *与**在形参与实参中的应用
'''
# 一:可变长参数
# 可变长指的是参数的个数不固定
# 站在实参的角度,实参是用来为形参赋值的,如果实参的个数不固定,那么必须要有对应的形参能够接收溢出实参
# ================================>在形参中用*与**<==============================
# 1.1 在形参名前加*:*会把溢出的'位置实参'存成元组,然后赋值其后的形参名
# def func(x,*y): # y=(2,3,4)
# print(x)
# print(y)
#
# func(1,2,3,4) # 1 (2, 3, 4)
# func(1) # 1 ()
# # func() # 报错,位置形参x必须被传值
# 示范:
# def add(*nums):
# res = 0
# for num in nums:
# res += num
# return res
#
# res=add(1, 2, 3)
# print(res)
# 1.2 在形参名前加**:**会把溢出的'关键字'实参存成字典,然后赋值其后的形参名
# def func(x, **y):
# print(x)
# print(y)
#
# func(1,a=111,b=222,c=333) # 1 {'a': 111, 'b': 222, 'c': 333}
# func(a=111, b=222, x=1, c=333) # 1 {'a': 111, 'b': 222, 'c': 333}
# ================================>在实参中用*与**<==============================
# def func(x, y, z):
# print(x, y, z)
# 1.3 在实参前加*:*会把其后的值打散成'位置实参'
# nums = [1, 2, 3]
# func(*nums) # func(1,2,3)
# 1.4 在实参前加**:**会把其后的值打散成'关键字实参'
# dic = {'y': 111, 'z': 222, 'x': 333}
# func(**dic) # func(y=111,z=222,x=333)
# ================================>在形参与实参中混用*与**<==============================
# def index(x, y, z, a, b, c):
# print("index===>", x, y, z, a, b, c)
#
# def wrapper(*args, **kwargs): # args=(1, 2, 3,) kwargs={"a":111,"b":222,"c":333}
# index(*args, **kwargs) # index(*(1, 2, 3,),**{"a":111,"b":222,"c":333})
# wrapper(1, 2, 3, a=111, b=222, c=333) # 输出 index===> 1 2 3 111 222 333
# 了解:
# 命名关键字形参(**)
# def func(x,y=222,*args,**kwargs):
# pass
# def func(x, y=222, *args, n=777, m, **kwargs): # m,n必须按照关键字实参的格式为其赋值,n不称为默认形参,但有默认值
# print(x) # 1
# print(y) # 2
# print(args) # (3,4,5)
# print("m===>", m)
# print("n===>", n)
# print(kwargs)
#
# func(1,2,3,4,5,m=6666666)
# func(1, 2, 3, 4, 5, n=88888, m=6666666, a=11, b=22, c=33)
'''
# 函数对象
'''
# 函数对象指的是函数可以被当成变量去使用
# def foo(): # foo = 函数的内存地址
# print('from foo')
# 1 可以被赋值
# f = foo
# print(f is foo)
# f()
# 2 可以当作参数传给一个函数
# def bar(func):
# print(func) # <function foo at 0x00000209770C51F0> 内存地址
# func() # from foo
#
# bar(foo)
# 3 可以当成一个函数的返回值
# def bar(func):
# return func
#
# res=bar(foo)
# print(res) # <function foo at 0x00000200ABD651F0> 内存地址
# print(bar(foo())) # None
# 4 可以当成容器类型的元素
# l = [foo]
#
# print(l) # [<function foo at 0x000001DDFF4951F0>]
# l[0]() # from foo
# 示例
# def login():
# print('登录中')
#
# def withdraw():
# print('提现中')
#
# def transfer():
# print('转账中')
#
# def recharge():
# print('充值中')
#
# func_dict = {
# '1': [login, '登录'],
# '2': [withdraw, '提现'],
# '3': [transfer, '转账'],
# '4': [recharge, '充值']
# }
# while True:
# print('0 退出')
# for k in func_dict:
# print(k, func_dict[k][1])
# choice = input('请输入操作编号:').strip()
# if choice == '0':
# break
# elif choice in func_dict:
# func_dict[choice][0]()
# else:
# print('输入错误')
'''
# 函数嵌套
'''
# 1 函数的嵌套调用
# def bar():
# print('from bar')
#
# def foo():
# print('from foo')
# bar()
#
# foo()
# 示例:
# def max2(x,y):
# if x > y:
# return x
# else:
# return y
#
# def max4(a,b,c,d):
# res1 = max2(a,b)
# res2 = max2(res1,c)
# res3 = max2(res2,d)
# print(res3)
#
# max4(1,2,3,4)
# 2 函数的嵌套定义
# def f1():
# print('from f1')
# # f2 = 函数的内存地址
# def f2():
# print("from f2")
# f1() # from f1
# 定义在函数内的函数特点是: 正常情况只能在函数体内调用
# from math import pi
#
# def circle(radius,mode=0):
# def perimiter(radius):
# return 2 * pi * radius
#
# def area(radius):
# return pi * (radius ** 2)
#
# if mode == 0:
# return perimiter(radius)
# elif mode == 1:
# return area(radius)
#
# res1=circle(3,0)
# res2=circle(3,1)
# print(res1)
# print(res2)
#
# def func():
# x = 10
# print(x)
# def f2():
# print('from f2')
# f2()
# func()
# print(x) # 报错
# x = 11
# def fun():
# x = 22
# def fun1():
# x = 33
# print(x)
# fun1()
# fun() # 33
'''
# 名称空间与作用域
'''
# 一 名称空间: 就是存放名字的地方
# 1 内置名称空间: 存放的是内置的名字,如print\input\len
# 生命周期: 解释器启动则产生,解释器关闭则销毁
# 2 全局名称空间: 存放的是顶级的名字
# 生命周期: python程序运行时则产生,python程序结束则销毁
# 3 局部名称空间:函数内的名字
# 生命周期: 调用函数时则产生,函数调用结束则销毁
# 名字的查找优先级:
# 从当前位置往外查找,如果当前是在局部:局部名称空间->全局名称空间->内置名称空间
# 从当前位置往外查找,如果当前是在全局:全局名称空间->内置名称空间
# 示范1:
# def func():
# len = 222
# print(len)
#
# # len = 111
#
# func()
# print(len)
# 名称空间可以理解为一层套一层的关系,一个非常重要的结论:名称空间的嵌套关系是函数定义阶段(即扫描语法时)就固定死的,与函数的调用位置无关
# x = 111
#
# def foo():
# print(x)
#
# def bar(f):
# x=222
# f()
#
# bar(foo) # 111
# 示例:
# x=0
# def f1():
# x=1
# def f2():
# # x=2
# print(x)
#
# f2()
#
# f1()
# 全局范围/全局作用域:内置名称空间+全局名称空间
# 特点:全局存活,全局有效
# 局部范围/局部作用域:局部名称空间
# 特点:临时存活,局部有效
# 了解:
# global(****)
# nonlocal(***)
# x = 10
# def func():
# global x
# x=22
#
# func()
# print(x)
# nonlocal生命周期是来自于外层函数的(***)
# x = 10
#
# def f1():
# x = 111
# def f2():
# nonlocal x
# x = 222
#
# f2()
# print(x)
#
# f1()
# print(x)
'''
# 作业
# 1、如下全局变量记录了当前登录用户,编写登录功能,一旦用户登录成功,则将全局变量赋值为当前登录的用户名
# login_user=None
# 2、针对之前编写的查询余额的功能,添加额外的逻辑:如果用户没有登录,则先执行登录功能
# login_user = None
# d = {}
# d1 = {}
# with open(r'F:\notepad\2020.7.01\day13\users.txt', mode='rt') as f:
# for line in f:
# name, pwd, money = line.strip().split(':')
# d[name] = pwd
# d1[name] = money
#
#
# def login():
# flag = True
# while flag:
# username = input('请输入用户名:')
# password = input('请输入密码:')
# if username in d.keys() and password == d[username]:
# global login_user
# login_user = username
# print('登录成功')
# flag = False
# else:
# print('用户名或密码错误')
# flag = False
#
#
# def check():
# if login_user != None:
# print(f'当前余额为{d1[login_user]}')
# else:
# print('用户未登录,请先进行登录')
# login()
#
#
# def info():
# if login_user == None:
# print('当前没有用户登录')
# else:
# print(f'当前用户为{login_user}')
#
#
# def exit():
# global login_user
# if login_user == None:
# print('当前还没有用户登入')
# else:
# login_user = None
# print('退出成功')
#
#
# func_dict = {
# '1': [login, '登录'],
# '2': [check, '查询余额'],
# '3': [info, '查看当前登入用户'],
# '4': [exit, '退出当前用户']
# }
# while True:
# print('0 退出')
# for i in func_dict:
# print('%s %s' % (i, func_dict[i][1]))
# choice = input('请输入操作编号:').strip()
# if choice == '0':
# break
# elif choice in func_dict.keys():
# func_dict[choice][0]()
# else:
# print('输入错误')