day4-Python-函数进阶

一、变量的作用域

根据变量的作用范围把变量分为:局部变量和全局变量。

def test(name,age,**kwargs):
    print(name)
    print(age)
    print(kwargs)
    test_1("test")
def test_1(source):
    print("from %s"%source)
test("bianbian",age=18,sex="girl",love="peng")

 结果:

bianbian
18
{'sex': 'girl', 'love': 'peng'}
from test

 test_1函数之后执行,没有问题;如果test_1函数之前执行会报错,因为test_1函数还没有被读到内存中,所以报错。

def test(name,age,**kwargs):
    print(name)
    print(age)
    print(kwargs)
    test_1("test")
test("bianbian",age=18,sex="girl",love="peng")
def test_1(source):
    print("from %s"%source)
结果:
bianbian
18
{'sex': 'girl', 'love': 'peng'}
Traceback (most recent call last):
  File "/Users/bianbian/PycharmProjects/test/test6.py", line 6, in <module>
    test("bianbian",age=18,sex="girl",love="peng")
  File "/Users/bianbian/PycharmProjects/test/test6.py", line 5, in test
    test_1("test")
NameError: name 'test_1' is not defined

 1、局部变量

指在局部生效,定义在函数体内的变量只能在函数里面生效,这个函数就是这个变量的作用域。

def test(name):
    print("before change:", name)
    name="pengpeng"
    print("after change:", name)

name="bian"
print("------调用test------")
test(name)
print("------打印name------")
print(name)

  结果:

------调用test------
before change: bian
after change: pengpeng #局部变量生效
------打印name------
bian

2、全局变量

在整个程序中都生效的变量,在整个代码的顶层声明。

love="pengpeng" # 定义全局变量
def test_1():
    print("love", love)
def test_2():
    love="shen"
    print("love", love)

print("------test_1------")
test_1()
print("------test_2------")
test_2()
print("------打印love------")
print("love", love)

  结果:

------test_1------
love pengpeng #打印的是全局变量
------test_2------
love shen #打印局部变量
------打印love------
love pengpeng #打印全局变量

 全局变量的优先级是低于局部变量的,当函数体内没有局部变量,才会去找全局变量。

3、修改变量作用域

(1)函数里面修改全局变量

现在global先声明一下全局变量,然后在函数中全局变量重新赋值

love="pengpeng" # 定义全局变量
def test_1():
    print("love", love)
def test_2():
    global love
    love="shen"
    print("love", love)

print("------test_1------")
test_1()
print("------test_2------")
test_2()
print("------打印love------")
print("love", love)  

 结果:

------test_1------
love pengpeng
------test_2------
love shen
------打印love------
love shen

(2)只在函数里面声明全局变量

love="pengpeng" # 定义全局变量
def test_1():
    global love
    love="shen"
    print("love", love)

print("------test_1------")
test_1()
print("------打印love------")
print("love", love)

  结果:

------test_1------
love shen
------打印love------
love shen

  最好不要用global这个关键字,防止别人串改自己的代码。

(3)修改列表

love =['bianbian',"pengpeng"] # 定义一个列表
def test_1():
    love[0]="shen"
    print(love)

print("------test_1------")
test_1()
print("------打印love------")
print(love)

  结果:

------test_1------
['shen', 'pengpeng'] #函数内的names输出
------打印love------
['shen', 'pengpeng'] #函数外的names输出

列表love被当做在函数中全局变量,重新赋值了,是可以被修改的。

 (4)小节

  • 只有字符串和整数是不可以被修改的,如果修改,需要在函数里面声明global。
  • 但是复杂的数据类型,像列表(list)、字典(dict)、集合(set),包括我们后面即将要学的类(class)都是可以修改的。

3、作用域小结

  • 在子程序(函数)中定义的变量称为局部变量,在程序一开始定义的变量称为全局变量。
  • 全局变量的作用域是整个程序,局部变量的作用域是定义该变量的子程序(函数)。
  • 当全局变量和局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其他地方,全局变量起作用。

二、递归

1、定义

一个函数在内部调用自身,这个函数被称为递归函数。

def test(n):
    print(n)
    if int(n/2) == 0:#结束符
        return n
    return test(int(n/2)) #调用函数自身
a = test(10)

  结果:

10
5
2
1

根据代码,最后一层,一定需要一个结束符,来结束。

def test(n):
    if n == 0:
        return n
    return n+test(n-1)
n=test(100)
print(n)
结果:
5050

test(n-1)返回的是(n-1)+test(n-2)......

2、递归特性总结

  • 必须要有一个明确的结束条件。
  • 每次进入更深一层的递归时,问题规模相比上次递归都应该少(问题规模:比如你第1次传进的是10,第2次递归应该是9...依次越来越少,不能越来越多)。
  • 递归的效率不高,递归层次过多会导致内存溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈贞,每当函数返回,栈就会减一层栈贞。由于栈的大小不是无限的,所以递归的次数过多,会导致栈溢出)。

第3点关于这个内存溢出说明:栈不是无限的,它是有限的,过多会导致内存溢出。如图:

三、高阶函数

变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,高阶函数功能就是:把函数本身当做一个参数,传到另一个函数中,然后在这个函数中做处理。

  

原文地址:https://www.cnblogs.com/bianfengjie/p/10742029.html