Python笔记12-函数的本质&闭包&变量的作用域

一、函数的本质【重点掌握】

函数就是一个变量,可以重新赋值,可以作为函数的参数,也可以作为函数的返回值

# 1.函数就是一个变量
print(abs(-66))   # 函数的调用,66
print(abs)        # 函数本身,<built-in function abs>
print(type(abs))  # <class 'builtin_function_or_method'>

r1 = abs(-66)
print(r1)
r2 = abs
print(r2)

# 注意1:函数本身是一个变量,函数名可以给其他变量直接赋值,赋值之后,可以使用该变量调用函数
print(r2(-88))    # 88

f = int
print(f('234'))

def test():
    print("test~~~~")
f = test
f()

# 2.函数名可以重新赋值
# 注意2:自定义变量名的时候,尽量避免和系统的关键字或函数名重名,如:list(),int(),str(),dict()
# abs = 'abc'
# print(type(abs))   # <class 'str'>
# print(abs(-99))


# 3.函数可以作为另一个函数的参数使用
numlist = ['fafa','agahaha','23']
numlist.sort(key=len)   # len(xx)
print(numlist)

def func1(a,b,f):
    total = f(a) + f(b)
    return total
r = func1(34,-6,abs)
print(r)

# 4.函数也可以作为另一个函数的返回值使用
def func1(a,b,f):
    total = f(a) + f(b)
    return f
f1 = func1(345,67,abs)
print(f1)  # <built-in function abs>
print(f1(-19))

# 总结:函数就是一个变量,函数名就是一个变量名,只要变量能进行的操作,函数都可以

二、闭包【重点掌握】

函数只是一段可执行代码,编译后就“固化”了,每个函数在内存中只有一份实例,得到函数的入口点便可以执行函数了。函数还可以嵌套定义,即在一个函数内部可以定义另一个函数,有了嵌套函数这种结构,便会产生闭包问题

# 1.需求:在func2函数中访问func1中的num1变量
# 方式一:设置返回值,通过调用函数获取返回值
# def func1():
#     num1 = 10
#     return num1
# def func2():
#     print(func1())
# func2()

# 方式二:进行函数的嵌套定义,就可以直接访问
def func1():
    num1 = 10
    def func2():
        print(num1)

print("*" * 50)

# 2.嵌套定义的函数如何调用
# 方式一:在外部函数中直接调用
def outer1():
    print("外部函数~~~~1111")
    num1 = 10
    def inner1():
        print("内部函数~~~~1111")
        print(num1)
    inner1()
outer1()

print("*" * 50)

# 方式二:给外部函数设置返回值。返回值为内部函数
def outer1():
    print("外部函数~~~~1111")
    num1 = 10
    def inner1():
        print("内部函数~~~~1111")
        print(num1)
    return inner1
f1 = outer1()
print(f1)   # <function outer1.<locals>.inner1 at 0x1084e16a8>
f1()

print("*" * 50)

# 3.闭包
"""
概念:如果两个函数嵌套定义,如果内部函数访问了外部函数中的变量,则会形成一个闭包
"""
# a.
def outer1():
    print("外部函数~~~~1111")
    num1 = 10
    def inner1():
        print("内部函数~~~~1111")
        print(num1)
    return inner1
f1 = outer1()
print(f1)
f1()

print("*" * 50)

# b.
def outer1(a):
    print("外部函数~~~~1111")
    num1 = 10
    def inner1():
        print("内部函数~~~~1111")
        print(num1,a)
    return inner1
f1 = outer1(8)
print(f1)
f1()

print("*" * 50)

# c.
def outer1(a):
    print("外部函数~~~~1111")
    num1 = 10
    def inner1(b):
        print("内部函数~~~~1111")
        print(num1,a,b)
    return inner1
f1 = outer1(8)
print(f1)
f1(78)

print("*" * 50)

# d.
def outer1(a):
    print("外部函数~~~~1111")
    num1 = 10
    def inner1(b):
        print("内部函数~~~~1111")
        print(num1,a,b)
        return a + b
    return inner1
f1 = outer1(8)
print(f1)
r = f1(78)
print(r)


"""
总结:
    a.闭包是一个函数的嵌套定义
    b.判断是否是闭包的特征:内部函数是否访问了外部函数中的变量
    c.闭包本质上还是一个函数,所以普通函数中使用的默认参数,关键字参数,不定长参数和返回值都可以使用
"""

三、变量的作用域【重点掌握】

1.作用域的分类

变量的作用域指的是变量可以使用的范围

程序的变量并不是在任意位置都可以访问,访问权限取决于这个变量是在哪里定义的

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。

【面试题】Python的作用域一共有4种,分别是

L:Local,局部作用域,特指内部函数

E:Enclosing,函数作用域【内部函数外的函数中】

G:Global,全局作用域

B:Built-in,内建作用域【内置作用域】  num = int("244")

查找方式:以L—>E—>G—>B,在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找

# 访问权限的大小:global > enclosing > local

# 1.不重名
num1 = 10        # 全局作用域:global,可以在当前文件的任意位置访问
def outer1():
    num2 = 20    # 函数作用域:enclosing,只能在外部函数中访问
    def inner1():
        num3 = 30   # 局部作用域:local,只能在内部函数中访问
        print(num1,num2,num3)
    print(num1,num2)
    return inner1
f1 = outer1()
f1()
print(num1)

print("*" * 50)

# 2.重名
# 注意:不同作用域内的变量重名的情况下,访问的时候遵循的是就近原则
num = 10
def outer1():
    num = 20
    def inner1():
        num = 30
        print("inner:",num)   # 30
    print("outer:",num)   # 20
    return inner1
f1 = outer1()
f1()
print('global:',num)  # 10

# 3.
"""
注意:
    Python中只有模块(module)、类(class)以及函数(def、lambda)才会引入新的作用域,
    其他的代码块,例如if/elif/else、try/except、for/while等是不会引入新的作用域的,
    也就是说这些语句内定义的变量,在外部也可以使用
"""
def func():
    n = 10
# print(n)

if 1:
    m = 19
print(m)

for _ in range(10):
    a = 24
print(a)

2.局部变量和全局变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中

# 注意:全局变量和局部变量是一个相对的定义
# 全局变量:可以在当前文件的任意位置被访问
# 局部变量:只能在指定的范围内被访问

# 1.
num1 = 34         # 全局变量
def test1():
    num2 = 10     # 局部变量


# 2.
num1 = 23         # 全局变量
def test2():
    num2 = 6      # 局部变量【函数作用域】
    def inner():
        num3 = 10  # 局部变量【局部作用域】


# 3.【面试题】
# a.下面的定义中,两个a表示不同的变量
# 不同作用域内的变量重名的情况下,访问【获取】的时候遵循的是就近原则
a = 15
def check():
    a = 88
    print(a)   # 88
check()
print(a)       # 15

print("*" * 50)

# b.
# a = 15
# def check():
#     a += 88  # UnboundLocalError: local variable 'a' referenced before assignment
#     print(a)
# check()
# print(a)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值