Python中的函数(二)--提高篇

1、全局变量和局部变量

1.1 局部变量:

·定义在函数内部的变量成为局部变量(函数的形参也是局部变量)
·局部变量只能在函数内部使用
·局部变量在函数调用时才能被创建,在函数调用之后会自动销毁

1.2 全局变量:

·定义在函数外部,模块内部的变量成为全局变量
·全局变量所有函数都可以直接访问(但函数内部不能将其赋值)

1.3 说明:

·局部变量只能在其被声明的函数内部访问,而全局变量可以再整个模块范围内访问
·在函数内部赋值语句不会对全面局变量造成影响

1.4 注

1)在函数内部可以通过 extend() 方法改变变量绑定的对象,从而改变全局变量的值,例如:L.entend(L2)。
但是全局变量地址没变,也就是 id(L)的返回值相同。此外使用 + += 等运算符都会产生错误。
2)全部变量只能用 del 删除

2、globals() /locals 函数

globals():返回当前>>全局作用域<<内变量的字典
locals() :返回当前>>局部作用域<<内变量的字典

示例:

a=1
b=2
c=3
def fn(c,d):
    e=300
    print("locals()返回",locals())    #locals()返回 {'d': 200, 'e': 300, 'c': 100}
    print("globals()返回",globals())  #globals()返回 {'__builtins__': <module 'builtins' (built-in)>, 'a': 1, '__spec__': None, 'b': 2, '__name__': '__main__', 'fx': <function fx at 0x7f3b12f45f28>, 'fn': <function fn at 0x7f3b11117ae8>, 'c': 3, '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>}
fn(100,200)

3、函数变量

函数名是变量,它在创建函数时绑定一个函数

示例1:此示例示意函数名fn是变量,它绑定一个函数对象

def fn():
    print("hello world")
f1 = fn
print(f1)   # 打印地址变量的地址:<function fn at 0x7f2c3eeb9f28>
print(f1()) 

输出如下:

<function fn at 0x0000021C33C04620>
hello world
None
解释:
第一行:打印函数变量f1的地址
第二行:先执行f1()函数,输出hello
第三行:执行fn()函数之后打印fn()函数的返回值,因为fn()函数没有return语句返回结果,所以默认返回为空,即输出 None

示例2:一个函数可以作为另一个函数的实参进行传递

def f1():
    print("hello f1")
def f2():
    print("hello f2")
def fx(fn):
    print(fn)       # 打印地址
    fn()            # 调用f1() 函数
fx(f1)

输出如下:

<function f1 at 0x0000025097744620>
hello f1
解释:
代码最后一行fx(f1)将函数f1作为fx的实参传递给了fx,此时第五行的fx()函数中的形参fn为f1,然后分别打印f1的地址、调用f1()函数

示例3.1:函数可以返回另一个函数

def get_function():
    s = input("请输入你要的操作:")
    if s=="求最大":
        return max    # 返回求最大值函数
    elif s=="求最小":
        return min    # 返回求最小值函数
    elif s=="求和":
        return sum    # 返回求和函数
L=[2,4,6,8,10]
f = get_function()
print(f(L))

输出如下(三种执行结果):

请输入你要的操作:求和
30
-----
请输入你要的操作:求最大
10
-----
请输入你要的操作:求最小
2

示例3.2:函数可以返回另一个函数——单位正整数加减乘除运算

def myadd(x,y):
    return x + y
def mysub(x,y):
    return x - y
def mymul(x,y):
    return x * y
def get_function(choise):
    if choise == "+":
        return myadd
    elif choise == "-":
        return mysub
    elif choise == '*':
        return mymul
def main():
    gongshi = input("请输入计算公式:")
    a = int(gongshi[0:1])   # 字符串切片
    b = int(gongshi[2:3])
    choise = gongshi[1:2]   # choise:运算符
    p = get_function(choise)   # p:函数变量
    print("结果是:",p(a,b))
main()

运行结果如下:

请输入计算公式:9*9
结果是: 81

4、函数的嵌套

4.1 定义:
函数嵌套定义是指一个函数里用def语句来创建另一个函数的情况

4.2 示例

def fn_outter():
    print("fn_outter()被调用")
    def fn_inner():
        print("fn_inner()被调用")
    fn_inner()  # 调用嵌套函数
    fn_inner()  # 二次调用
    print('fn_outter()调用结束')
fn_outter()

输出结果如下:

fn_outter()被调用
fn_inner()被调用
fn_inner()被调用
fn_outter()调用结束

5、python3 的四个作用域

作用域也叫名字空间,是访问变量时查找变量名的范围空间
四个作用域包括:

    作用域                  |    英文解释                   |   英文简写
----------------------------|-------------------------------|-----------
局部作用域(函数内)        |  Local(function)            |   L
外部嵌套函数作用域          |  Enclosing function locals    |   E
函数定义所在模块作用域      |  Global(module)             |   G
python内置模块的作用域      |  Builtin(Python)            |   B
----------------------------|-------------------------------|-----------

示例:

v = 100             # 全局
def fun1():
    v = 200         # 外部嵌套函数作用域
    print("fun1.v=",v)
    def fun2():
        v = 300     # 局部作用域
        print("fun2.v=",v)
    fun2()
fun1()
print("全局变量v=",v)

输出如下:

fun1.v= 200
fun2.v= 300
全局变量v= 100

6、变量名查找规则

1)在访问变量时,先查找本地变量,然后是包裹此函数外部的函数内的变量,之后是全局变量,最后是内建作用域内的变量。即: L —–> E ——> G ——-> B
2)在默认情况下,变量名赋值会在当前作用域内创建变量和修改变量

7、global语句

7.1 作用:
告诉解释执行器,global语句声明的一个或多个变量,这些变量的作用域为模块级的作用域,也称作全局作用域。在全局声明global,将赋值变量映射到文件内部的作用域
7.2 语法

global 变量名1,变量名2

7.3 示例

v = 100
print('v = ',v)
def fn():
    global v    # 告诉解释执行器(python3),v是全局变量,不是局部变量,
    v = 200     # 修改全局变量的v值
fn()
print('v = ',v)

输出如下:

v =  100
v =  200

7.4 global说明:

1)全部变量如果要在函数内部被赋值,则必须经过全局声明(否则会被认为时局部变量)
2)全局变量在函数内部可以直接被访问
3)不能先声明局部变量再用global声明为全局变量,此做法不符合规则
4)global 变量列表里的变量名不能出现在函数的形参列表里,否则会导致global全局变量名与形参列表内的 局部变量名冲突

8、nonlocal语句

8.1 作用:
告诉解释执行器,nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量
8.2 语法:

nonlocal 变量名1,变量名2

8.3 示例

v = 100
def f1():
    v = 200
    print("f1.v=",v)
    def f2():
        nonlocal v      #定义为外部函数嵌套函数内的变量 E
        v = 300
        print("f2.v=",v)
    f2()
    print("调用f2后的f1.v=",v)
f1()
print("全局变量v=",v)

输出如下:

f1.v= 200
f2.v= 300
调用f2后的f1.v= 300
全局变量v= 100

8.4 说明:

1)nonlocal 语句只能在被嵌套函数的内部进行使用
2)对nonlocal变量进行赋值,将会对外部嵌套函数作用域内的变量进行操作
3)当有两层或者两层以上的函数嵌套时,访问nonlocal变量只对最近的一层变量进行操作
4)nonlocal语句中的变量列表里的变量名,不能出现在此函数的形参列表中

9、lambda 匿名函数

9.1 def 语句语法:

def 函数名(形参):
    语句块

9.2 lambda 表达式

9.2.1 作用:

创建一个匿名函数对象
同 def 类似,单不提供函数名

9.2.2 语法;

lambda[形参名1,形参名2,……]:表达式

9.2.3 示例

def myadd1(x,y):
    return x+y
myadd2 = lambda x,y:x+y     # 作用等同于 def 语句
print('20+30=',myadd1(20,30))
print('40+50=',myadd2(40,50))

输出如下:

20+30= 50
40+50= 90

9.2.4 说明:

1)lambda 只是一个表达式,它用来创建一个函数
2)当lambda 表达式调用时,先执行(:)后的表达式,并返回表达式的结果的引用
3)lambda 表达式创建的函数只能包含一条表达式
4)lambda 比函数简单且可以随时创建和销毁,有利于减少程序的耦合度

10 eval() 函数

10.1 作用:
把一个字符串当成一个表达式来执行,返回表达式执行后的结果
10.2 格式:

eval(source,glbals = None,locals = None)

10.3 示例:

eval('1+2+3')       # 6

11 exec() 函数:
11.1 作用:
把一个字符串当成程序来执行

11.2 格式:

    exec(source,glbals = None,locals = None)

11.3 示例:

s = '''x=100
       y=200
       print('x+y=',x+y)
       del x,y
    '''
exec(s)    # 300
----------------------------------------------

12 函数的可重入性
12.1 定义:
当一个函数的输入一定,则输出必然一定的函数成为可重入函数

12.2 说明:
可重入函数内一定不会访问局部变量以外的变量

12.3 示例:

# 可重入函数,推荐使用
def  myadd(x,y):
    return x+y
print(myadd(100,200))    # 300
# ----------------------------
# 不可重入函数,难以控制
y = 200
def myadd(x):
    return x+y
print(myadd(100))   # 300
y = 300
print(myadd(100))   # 400

13 高阶函数 High Order Function
13.1 什么是高阶函数:

满足下列条件中的一个的函数即为高阶函数
1)函数接受一个或者多个函数作为参数传入
2)函数返回一个函数

13.2 Python内置的高阶函数:

·map
·filter
·sorted

14 map函数:
14.1 语法:

map(func,*iterable)     返回一个可迭代对象,此可迭代对象用函数func对可迭代对象
                        iterable中的每一个元素作为参数计算后得到新的数据

14.2 示例:

def pow2(x):
    return x**2
for x in map(pow2,range(1,10)):
    print(x,end=' ')

输出如下:

1 4 9 16 25 36 49 64 81 

示例2:

def mypow(x,y):
    return x**y
for i in map(mypow,[1,2,3,4],(4,3,2,1)):
    print(i,end=' ')

输出如下:

1 8 9 4

15 filter 函数 (filter:过滤)
15.1 语法:

filter(function,iterable)

15.2 作用:

1)筛选可迭代对象 iterable 中的数据,返回一个可迭代对象,此可迭代对象只返回iterable 中符合条件的数据
2)function 将对 iterable 中提供的每个数据进行求布尔值,如果为True则保留,为False则丢弃此数据

15.3 示例

# 判断x是否为奇数,是返回True,else 返回False
def isodd(x):
    return x%2 == 1
for x in filter(isodd,range(10)):
    print(x,end = ' ')

输出如下:

1 3 5 7 9

示例2:

# 判断素数
def isprime(x):
    for i in range(2,x):
        if x%i==0:
            break
    else:
        return x
L = list(filter(isprime,range(2,100)))
print(L)

输出如下:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]    

16 sorted() 函数

16.1 作用:
将可迭代的数据进行排序,生成排序后的列表
16.2函数参考格式:

sorted(iterable,key=None,reverse=False)

16.3 说明;

iterable 可迭代对象
key  函数是用来提供一个值(身高/姓名/成绩 等等,序号一个函数提供,
     返回的一定可以进行值比较),将这个值作为排序的数据,如果不给
     出key函数,则依据数据的值进行比较和排序 
reverse  标志用来设置是否降序排序

16.4 示例

a = [1, 9, 8, 2, 3, 6, 5, 4, 7]
a = sorted(a)
print(a)    # [1, 2, 3, 4, 5, 6, 7, 8, 9]
a = sorted(a, reverse=True)
print(a)   # [9, 8, 7, 6, 5, 4, 3, 2, 1]
b = [5, -4, 3, -2, 1, 0]
b = sorted(b, key=abs)
print(b)    # [0,1,-2,3,-4,5]   #根据绝对值进行排序

17 递归函数
17.1 递归是指 函数直接或间接的调用自身
17.2 示例:

# 函数直接调用自身
def f():
    f()     # 直接调用自身
f()
print("递归完成")
-----------------------------
# 函数间接调用自身
def fa():
    fb()    # 间接调用自身
def fb():
    fa()
fa()
print("递归完成")

17.3 递归说明:

·递归一定要控制递归的层数,当符合某一条件时要停止递归调用
·几乎所有递归都能用while循环代替

17.4 递归的优缺点:
1)优点:
可以把问题简单化,让思路更清晰,代码更简洁
2)缺点:
递归因系统环境影响大,当递归深度太大时,可能会得到不可预知的结果

17.5 递归调用分为两个阶段:

1)递推阶段:
从问题出发,按递归公式递推,从未知到已知,最终达到递归停止条件
2)回归阶段:
按递归终止条件得出结果,逆向逐步带入递归公式,回归到原问题求解

17.6 示例:

def recursion(n):
    print("递归进入第%d层" %n)
    if n==1:
        print("递归退出第%d层" %n)
        return
    recursion(n-1)
    print("递归退出第%d层" %n)
recursion(5)

输出如下:

递归进入第5层
递归进入第4层
递归进入第3层
递归进入第2层
递归进入第1层
递归退出第1层
递归退出第2层
递归退出第3层
递归退出第4层
递归退出第5层

5.闭包
闭包是指引用函数外部变量的函数
如果一个内嵌函数访问了外部嵌套函数的变量 这个内嵌函数就是闭包

闭包必须满足三个条件:

1)必须有个内嵌函数
2)内嵌函数必须引用外部函数中的变量
3)外部函数的返回值必须是内嵌函数

示例:

def make_power(y):
    def fn(x):
        return x**y     # 用处:例如:实现x**2,x**3,x**4 用闭包完成避免多次重写函数!!
    return fn
pow2 = make_power(2)
print("5**2= ",pow2(5))
pow2 = make_power(7)
print("3**7= ",pow2(3))
pow2 = make_power(10)
print("2**10= ",pow2(2))

输出如下:

5**2=  25
3**7=  2187
2**10=  1024

猜你喜欢

转载自blog.csdn.net/E_I_D_/article/details/82559644