一、名称空间

# 什么是名称空间(namespaces)
	用于存放变量名与变量值绑定关系的地方(类似于民政局)

# 名称空间的分类(重要)
	1.内置名称空间
    	python解释器提前给你定义好的 
        	print()
            len()
            ...
    2.全局名称空间
    	在py文件中顶格编写的代码运行之后都会存入全局名称空间
        	name = 'jason'  # name全局
            def func():  # func全局
                pass
            if 1:
                a = 123  # a全局
            for i in range(10):
                print(i)  # i全局
            while True:
                a = 123  # a全局
    3.局部名称空间
    	函数体代码运行之后产生的都是局部名称空间
# 存活周期
	1.内置名称空间
    	python解释器启动与关闭而创建和销毁
     2.全局名称空间
    	随着py文件的运行与结束而创建和销毁
     3.局部名称空间
    	随着函数体代码的执行与结束而创建和销毁

二、名字的查找顺序

# 在查找名字的时候 要先确定自己当前在哪
	1.如果你在局部
    	局部 >>> 全局 >>> 内置
    2.如果你在全局
    	全局 >>> 内置
     
# 局部名称空间的嵌套 
'''函数在定义阶段名字的查找顺序就已经固定死了(特例)'''
x = 111
def f1():
    x = 222
    def f2():
        x = 333
        def f3():
            x = 444
            def f4():
                x = 555
                print(x)
                # x = 555  特例
            f4()
        f3()
    f2()
# 通过调用f1 执行所有的函数
f1()

三、名称空间的作用域

  • 名称空间与作用域的关系是在函数定义阶段(扫描语法时)就确立的,

    与什么时候调用以及调用位置无关

'''
作用域
	名称空间所能够作用的范围
  
内置名称空间
	程序任何阶段任何位置均可使用(全局有效)
全局名称空间
	程序任何阶段任何位置均可使用(全局有效)
局部名称空间	
	一般情况下只在各自的局部名称空间中有效
'''

四、global关键字与nonlocal关键字使用

  • 在函数内,无论嵌套多少层,都可以查看到全局作用域的名字,若要在函数内修改全局名称空间中名字的值,当值为不可变类型时,则需要用到global关键字

  • 对于嵌套多层的函数,使用nonlocal关键字可以将名字声明为来自外层嵌套函数定义的作用域(非全局)

# x = 111
# def index():
#     # 局部修改全局变量 需要使用关键字声明
#     global x
#     x = 222
# index()
# print(x)


# name_list = ['jason', 'kevin']
# def index():
#     name_list.append('heiheihei')
# index()
# print(name_list)
"""
如果想在局部修改全局数据
    如果数据为不可变类型则需要关键字global声明
    如果数据为可变类型则无需关键字global声明
"""
def index():
    # x = 111
    l1 = [11,22]
    def func():
        # 内部局部修改外部局部
        l1.append(333)
    func()
    print(l1)
index()
"""
如果想要在内部的局部修改外部局部的不可变类型数据
需要关键字nonlocal声明
"""

五、函数对象(函数名)

  • 在python中,函数是第一类对象,即函数可以当做数据传递,函数又称第一等公民

  • 本质:函数可以当变量用

"""函数名遇到括号就会调用!!!"""
# 用法1:函数名可以当做变量名赋值
# def index():
#     print('from index')
# a = index
# a()  # 本质就是在调用index函数

# 用法2:函数名还可以当做函数的实参
# def index():
#     print('from index')
# def func(a):
#     print(a)
#     a()
#     print('from func')
# func(index)

# 用法3:函数名还可以当做函数返回值
# def index():
#     print('from index')
# def func():
#     print('from func')
#     return index
# res = func()  # 调用func并接受func的返回值
# res()

# 用法4:函数名可以当做容器类型(内部可以存放多个数据)的元素
# def index():
#     print('from index')
# l = [111, 222, 333, index()]
# print(l)

'''举例小练习'''
def register():
    print('注册功能')
def login():
    print('登录功能')
def shopping():
    print('购物功能')
def transfer():
    print('转账功能')
def withdraw():
    print('提现功能')
def check_order():
    print('查看订单')
func_dic = {'1':register,
            '2':login,
            '3':shopping,
            '4':transfer,
            '5':withdraw,
            '6':check_order
            }
while True:
    print("""
    1.注册功能
    2.登录功能
    3.购物功能
    4.转账功能
    5.提现功能
    6.查看订单
    """)
    choice = input('请输入功能编号>>>:').strip()
    # 判断用户输入的编号在不在字典的k中
    if choice in func_dic:
        # 根据键获取值(函数名)
        func_name = func_dic.get(choice)
        # 函数名加括号调用
        func_name()
    else:
        print('功能编号不存在')

    # 下列代码的弊端在于功能较多时 代码过于复杂
    # if choice == '1':
    #     register()
    # elif choice == '2':
    #     login()
    # elif choice == '3':
    #     shopping()
    # else:
    #     print('写累了')

六、函数的嵌套调用

  • 套娃方式,一层接一层

# 嵌套调用:函数内部调用其他函数
# def index():
#     print('from index')
# def func():
#     index()
#     print('from func')
# func()

def my_max(a, b):
    if a > b:
        return a
    return b

def many_max(x,y,z,m):
    res = my_max(x,y)
    res1 = my_max(res,z)
    res2 = my_max(res1,m)
    return res2
ret = many_max(1,2,3,4)
print(ret)7

七、函数的嵌套定义

# 函数体内部定义其他函数
# 将复杂的功能全部隐藏起来 暴露一个简单的接口
def all_func(type):
    def register():
        print('注册功能')
    def login():
        print('登录功能')
    def transfer():
        print('转账功能')
    def shopping():
        print('购物功能')
    # 这里仅仅是延时嵌套定义的现象 暂不考虑优化
    if type == '1':
        register()
    elif type == '2':
        login()
    elif type == '3':
        transfer()
    elif type == '4':
        shopping()
    else:
        print('不知道啥功能')

all_func('3')

八、闭包函数

闭:指的该函数是定义在函数内的函数

包:指的就是该函数引用了一个外层函数作用域的名字(e作用域的名字)

闭:定义在函数内部的函数
包:内部函数使用了外部函数名称空间中的名字
# 只有符合上述两个特征的函数才可以称之为"闭包函数"

# def outer():
#     x = 222
#     def index():
#         print('from index', x)
#     return index

# 闭包函数其实是给函数传参的第二种方式
# 方式1:函数体代码需要用到数据 直接在括号内定义形参即可
# def index(username):
#     print(username)
# def my_max(a, b):
#     if a > b:
#         return a
#     return b
# 方式2:利用闭包函数
# def outer(x,y):
#     # x = 2
#     # y = 40
#     def my_max():
#         if x > y:
#             return x
#         return y
#     return my_max
# res = outer(2,40)
# print(res())
# print(res())

'''小演戏'''
import requests
url = 'https://www.baidu.com'
def outer(url):
    def get_content():
        # 爬取百度首页数据
        res = requests.get(url)
        if res.status_code == 200:
            with open(r'xxx.html','wb') as f:
                print('*'.center(30))
                f.write(res.content)
    return get_content

res = outer('https://www.baidu.com')
res()
res()
res()
res1 = outer('https://www.jd.com')
res1()
res1()
res1()
res1()

image

每天进步一小步 成功前进一大步

posted on 2021-11-15 19:16  耿蜀黍  阅读(49)  评论(0编辑  收藏  举报