函数的作用域
作用域又可以被称为命名空间,指变量起作用的范围。Python变量作用域可以分为四种,分别为局部作用域、嵌套作用域、全局作用域、内置作用域。
作用域 | 英文 |
---|---|
局部作用域 | Local |
嵌套作用域 | Enclosing |
全局作用域 | Global |
内置作用域 | Buiit-in |
变量作用域
一个程序的所有的变量并不是在哪个位置都可以访问的。访问权限决定于这个变量是在哪里赋值的。 变量的作用域决定了在哪一部分程序你可以访问哪个特定的变量名称。两种最基本的变量作用域如下:
全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。 局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在 函数内声明的变量名称都将被加入到作用域中。如下实例:
x = 2
def func(x):
x = 3
print(x)
func()
print x
来猜一猜他的运行结果
当我们在代码里使用变量时,Python创建对象,改变对象或查找对象都是在一个所谓命名空间下进行的(一个保存变量名的地方)。 而函数除了打包代码之外,还定义了一个新的变量空间,一个函数所有的变量,都与函数的命名空间相关联:
-
def 内定义的变量名能够被 def内的代码使用,不能在函数外部引用这样的变量名
-
def之中的变量名与def之外的变量名并不冲突
也就是说:
-
如果一个变量在def内被赋值,它就被定义在这个函数之内
-
如果在def之外赋值,它就是整个文件全局的
回到最开始的问题
x = 2
def func(x):
x = 3
尽管这两个变量名都是x,但是他们作用域(命名空间)可以把他们区别开。
作用域(命名空间)有助于防止程序之间变量名的冲突,而且,有助于函数成为更加独立的单元。
在Python中,函数定义了一个函数本地内的作用域,
而像x = 2这样赋值语句定义了一个全局作用域(模块级别的变量,使用范围仅限于单个文件)。
而像x = 3这样赋值语句定义了一个局部作用域(范围仅限于函数内部)。
01函数的嵌套调用
# def func1():
# print("这是外部函数")
# def func2():
# print("这是内部函数")
# func2()
# func1()
# 1.在外函数内部调用内函数,即用函数名调用
# def func1():
# print("这是外部函数")
# def func2():
# print("这是内部函数")
# func2() #函数名调用内函数
# func1()
# 2.可以用return调用内函数
def func1():
print("这是外部函数")
def func2():
print("这是内部函数")
return func2 # 返回了一个函数名 内函数名
"""
func2 = func1()
func2() = func1()() # 调用我的内函数func2()
"""
# print(func1())
func1()() # 等价于 func2()
# 在一个函数里面调用别的函数
def print1():
print("这是第一个函数")
def print2():
print("这是定义的第二个函数")
print1() #在print2()中调用print1()
print2()
02函数的作用域
基本语法 运算符 条件判断(if)与顺序执行(循环while for ) 基本数据类型(数值,字符串,列表,元组,字典,集合 ) 代码的顺序都是从上往下执行的 我们的循环 重复的从上往下
# E(enclosing):嵌套的父级函数的局部作用域
def mytest1():
b = 6 # 作为我mytest1的局部变量 相对而言 b=6 作为我的mytest2的全局变量
def mytest2():
# print(b, id(b),'2b')
nonlocal b # nonlocal 关键字用于在嵌套函数内部使用变量 用的比较少 很少去声明
b = 7 # 重新开辟了内存空间 注释掉直接打印b
print(b, id(b))
mytest2()
print(b, id(b))
03变量的作用域
# a = 1 # 全局变量
# def func1():
# # 局部变量
# # a = 2 # 只能在函数的内部访问
# print(a) # 2
# # return a
# func1()
# print(a) # 1
高阶函数
什么是高阶函数?
高阶函数:一个函数可以作为参数传给另外一个函数,或者一个函数的返回值为另外一个函数(若返回值为该函数本身,则为递归),满足其一则为高阶函数。
一个函数的函数名作为参数传给另外一个函数
def func():
print("定义一个普通函数")
def high_level(func):
print("定义一个高阶函数")
# 在函数内部,通过传入的函数参数调用
func()
high_level(func)
一个函数返回值(return)为另外一个函数(返回为自己,则为递归)
def func():
print("定义一个普通函数")
def high_level(func):
print("定义一个高阶函数")
return func
# return func() 这个是直接返回函数调用,递归函数就是如此
res = high_level(func)
# 高阶函数返回函数之后在调用func函数
res()
04高阶函数
"""装饰 给一个添加另一个函数的功能 """
"""一个函数返回值(return)为另外一个函数(返回为自己,则为递归)"""
def func():
print("定义一个普通函数")
def high_level(func):
print("定义一个高阶函数")
return func # 返回的传入的函数名
# return func() 这个是直接返回函数调用,递归函数就是如此
res = high_level(func) # func是一个普通函数的函数名 func = high_level(func)
# 高阶函数返回函数之后在调用func函数
res() # func()
内置高阶函数
map()函数
map函数接收的是两个参数,一个函数,一个序列,其功能是将序列中的值处理再依次返回至列表内。其返回值为一个迭代器对象--》例如:<map object at 0x00000214EEF40BA8>。其用法如图:
lis = [1, 2, 3, 4, 5]
def square(x):
return x ** 2
print(map(square,lis ), type(map(square, lis)))
res = map(square, lis)
for i in res:
print(i)
print(list(map(square, lis)))
filter()函数
filter函数也是接收一个函数和一个序列的高阶函数,其主要功能是过滤。其返回值也是迭代器对象,例如:<filter object at 0x000002042D25EA90>。
# 在一个list中,删掉偶数,只保留奇数
def is_odd(n):
return n % 2 == 1
print(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
print(list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])))
reduce()函数
reduce函数也是一个参数为函数,一个为可迭代对象的高阶函数,其返回值为一个值而不是迭代器对象,故其常用与叠加、叠乘等,图示例如下:
from functools import reduce
def fn(x, y):
return x + y
res = reduce(fn, [1, 3, 5, 7, 9])
print(res)