python-函数对象-函数嵌套-名称空间-作用域-闭包函数-装饰器

一、函数对象

  1. 函数可以被引用
  2. 函数可以作为函数的参数
  3. 函数可以作为函数的返回值
  4. 可以被存储到容器类型中

引用

def func1():
    print("run")
a = func1() #run

可以当参数传给另外一个函数

def func1():
    print('run')

def func2(f):
    f()

func2(func1) #run

可以当作一个函数的返回值

def func1():
    print('run')
def func3():
    return func1

f = func3()
f()
print(f) #<function func1 at 0x000001A62CDD2E18>
print(func1) #<function func1 at 0x000001A62CDD2E18>

可以当作容器类型的元素

def func4():
    print("func4 run")

list = [func4]
list[0]() #func4 run

示范1:

def login():
    print("登陆")
def register():
    print("注册")
def shopping():
    print("购物")

res =  input("请选择功能名称:")
funcdic = {"login":login,"register":register,"shopping":shopping}

if res in funcdic:
    funcdic[res]()
else:
    print("输入有误!")

示范2:

def register():
    print('注册')
    
def login():
    print('登陆')
    
def shopping():
    print('购物')
    
def pay():
    print('支付')

func_dic={
    '1':register,
    '2':login,
    '3':shopping,
    '4':pay
}

while True:
    print("""
    0 退出
    1 注册
    2 登陆
    3 购物
    4 支付
    """)
    choice=input('>>>: ').strip()
    if choice == '0':break
    if choice in func_dic:
        func_dic[choice]()
    else:
        print('输入错误的指令')

二、函数嵌套

  1. 嵌套定义:在一个函数中定义了另一个函数
  2. 嵌套调用:在一个函数中调用了另一个函数
  3. 注意:定义在函数内的函数只能函数内使用 外界不能访问

示范1:

def func1():
    print("func1")

def func2():
    print("func2")
    func1()

func2() #func2、func1

示范2:

def func1():
    print("func1")

    def func2():
        print("func2")

    func2()    #内部函数只能内部函数调用

func1() #func1、func2

示范3:

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)

print(circle(10,0))
print(circle(10,1))

示范4:

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)
    return res3

print(max4(1,2,3,4))

三、名称空间

  1. 什么的名称空间:存储名称的空间

  2. 名称空间的分类:

    1. 内置名称空间:存储解释器自带的一些名称与值的对应关系(python解释器启动时创建 所有代码全部执行完毕 关闭解释器时 销毁)

    2. 全局名称空间: 只要你的名字的定义是顶着最左边写的就在全局空间,除了内置的函数内的 都在全局中(执行py文件创建全局名称空间 关闭解释器时 销毁)

    3. 局部名称空间:只要是函数内的名称就是局部的(调用函数时创建 函数执行完毕就销毁)

      • 名称空间的加载顺序

      内置的 -> 全局的 ->局部的

      • 名称的查找顺序

      局部的 -> 全局的 -> 内置的

四、作用域(作用范围)

  1. 什么是作用作用域:域指的是区域、范围的的意思

  2. 全局的名称空间和内置的名称空间在使用上没什么区别,局部的和全局的内置的就区别了,局部定义的只能在局部使用

  3. 给三个空间划分范围:

    ​ 全局的和内置可以划分为同一个范围,globals()表示的全局范围 就是所谓的全局作用域

    ​ 局部的单独划分为一个范围,locals()表示局部作用域

    注意:你在全局中使用locals看到的就是全局的内容与globals没有区别

    print(locals())
    print(globals())
    
print(dir(globals()["__builtins__"])) #查看全局作用域中的内容

a = 'ssssssssss'
print(globals()) #返回当前位置的全部全局变量

示范1:

def func():
    a = 100
    print(locals())

func() #查看局部变量的内容 {'a': 100}

示范2:

age = 18
def func2():
    # 明确声明  要使用全局中的age
    global age
    age = 19
    print(age)

func2() # 19
print(age) # 19

示范3:

l=[]
def func():
    l.append(111)
    l.append(222)
func()
print(l) #[111, 2222]

示范4:

a = 1
def func3():
    a = 10
    def inner():
        # 明确声明要使用上一中的a,如果上一层没有,则找上上层,但是注意不能找到全局中的
        nonlocal a
        a = 100
        print(a)
    inner()
    print("这是func3中a",a)

func3() #inner内部a的值为100 func3外部函数a的值为100
print(a) #全局变量a的值为1

总结:

global适用于函数内部修改全局变量的值

nonlocal适用于嵌套函数中内部函数修改外部变量的值

五、闭包函数

  1. 闭包函数也是一个函数
  2. 与普通函数的区别:
    1. 定义在另一个函数中的
    2. 在这个内部的函数中使用了外部的名称

示范1

age = 20
# 如下就是一个闭包函数
def fun1():
    age = 18
    def inner():
        print("hello")
        print(age)
    # 在返回这个内部的函数时,不是单纯的返回函数,还把函数中访问到的局部名称一起打包了
    # 相当于将内部函数与访问的数据打包在一起了,闭包这个名字就是这么得来的
    return inner
f = fun1() # f 就是inner
f() #打印hello、18
c = 1000
def func2():
    a = 1
    b = 10
    def inner():
        print(a)
        print(b)
        print(c)
    return inner

f = func2()
f() #分别打印1、10、1000

#__closure__用于访问闭包时打包的数据
print(f.__closure__[0].cell_contents) #1
print(f.__closure__[1].cell_contents) #10

六、装饰器

  1. 什么时装饰器:给一个已有的对象(一个函数) 添加新的功能

    装饰器本身可以是任意可调用对象

    被装饰对象本身也可以是任意可调用对象

  2. 为何要用装饰器:开放封闭原则:对修改封闭,对扩展开发

    简单的说:装饰器就是 一个用于给其他函数增加功能的函数

示范1

import time
def download2():
    start_time = time.time()
    print("开始下载xxx.mp4")
    time.sleep(2)
    print("xxxx.mp4 下载完成!")
    end_time = time.time()
    print("下载耗时", (end_time - start_time))

download2()

示范2

import time

def download():
    print("开始下载xxx.mp4")
    time.sleep(2)
    print("xxxx.mp4 下载完成!")

def outter(func):
    a = 1
    print(locals(),"xxxxxx")
    def inner():
        #在调用原始函数前 增加新功能
        func()

    # print(inner)
    return inner

download = outter(download)
download()
import time

def outter(func):
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs)
        return res
    return wrapper

@outter
def index():
    time.sleep(1)
    print('welcome to index page')
    return 1234

#index()
print(index())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值