【Python】函数进阶

206 阅读4分钟

函数的嵌套:

简单理解就是,在一个函数里面,还有函数,即:可分为外函数、内函数;

嵌套函数是为函数内部服务的,比如:减少代码的重复,想要调用函数,需要使用函数名;内函数也如此,如果不用函数名调用函数,内函数则永远不会被执行。

如何在函数外部调用内函数?

1、不可以直接调用,需要先执行外函数中的代码块;

# 像这样,没有执行外部函数,Python会找不到内函数,所以会报错:func2 is not defined.,没有被定义。

def func1():
    print("这是外部函数")
    def func2():
        print("这是内部函数")
func2()   # 报错
调用内部函数的方法:

1、在外函数内部调用内函数,即函数名调用:

def func1():
    print('这是外函数')

    def func2():
        print('这是内函数')

    func2()   # 函数名调用内函数


func1()

2、使用 return 调用函数:

def func1():
    print('这是外函数')

    def func2():
        print("这是内函数")

    return func2


func1()()   # 执行func1()会返回func2,再func2()

3、在一个函数里调用别的函数:

def test_01():
    print('这是第一个函数')


def test_02():
    print('这是第二个函数')
    test_01()    # 在 test_02() 中调用 test_01()


test_02()

函数的作用域:

作用域又被称为命名空间,指变量起作用的范围。python 变量作用域可分为四种:局部作用域、嵌套作用域、全局作用域、内置作用域。

image.png

变量作用域:

"""作用域:局部变量 < 嵌套的父级变量 < 全局变量 < 内建函数"""
"""优先级:局部变量 > 嵌套的父级变量 > 全局变量 > 内建函数"""

一个程序的所有的变量并不是在哪个位置都可以访问的。访问权限取决于这个变量是在哪里赋值的。

变量的作用域决定了你在哪一部分程序,可以访问哪个特定的变量名称。 两种最基本的变量作用域如下:

  • 全局变量
  • 局部变量
# 嵌套的父级函数的局部使用域

def mytest_1():
    a = 3

    def mytest_2():
        a = 7
        print(a, id(a))     # 7 4330005864

    mytest_2()
    print(a, id(a))         # 3 4330005736


mytest_1()

全局变量与局部变量:

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

局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。

调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:

a = 1  # 全局变量


def func1():
    a = 2222  # 只能在函数的内部访问,即便与全局变量的名字一样,也不影响
    print(a)  # 2222
    return a


func1()
print(a)  # 1

当我们在代码里使用变量时,Python创建对象,改变对象或查找对象都是在一个所谓命名空间下进行的(一个保存变量名的地方)。

而函数除了打包代码之外,还定义了一个新的变量空间,一个函数所有的变量,都与函数的命名空间相关联:

  • def 内定义的变量名能够被 def 内的代码使用,不能在函数外部引用这样的变量名
  • def 之中的变量名与 def 之外的变量名并不冲突

也就是说:

  • 如果一个变量在def内被赋值,它就被定义在这个函数之内
  • 如果在def之外赋值,它就是整个文件全局的

函数中修改不了全局作用域的变量如需修改,加 global 关键字,声明变量为全局变量

x = 200  # 全局变量


def func2():
    global x    # 声明为全局变量
    x = 300
    print(x)   # 300


func2()
print(x)    # 300
def demo():
    b = 666

    def demo1():
        nonlocal b  # nonlocal 关键字用于在嵌套函数内部使用变量
        b = 777     # 重新开辟了内存空间,把原有的值注释掉 
        print(b, id(b))  # 777 4331991664

    demo1()
    print(b, id(b))      # 777 4331991664


demo()

debug: image.png

built-in:内建作用域

内建作用域是特指 python api 内置的一些操作,例如 len 、max 等函数,无需声明就可使用。

函数作用域的优先级图解:

image.png