函数对象,函数嵌套,名称空间

一、定义函数的三种方式

  1、空函数:可以快速帮助你构建项目框架,使项目架构清晰明了(应用频率非常高)

# 购物车功能
def register():
    pass
def login():
    pass
def shopping():
    pass
def pay():
    pass

  2、无参函数

def func():
    print('from func')

  3、有参函数

def func(x,y,*args,**kwargs):
    pass

  

二、命名关键字参数(了解)

  在函数定义阶段,写在*与**可变长参数之间的形参,在给关键字参数传值的时候,只能用关键字为其传值,在定义阶段,给你感觉好像是z是默认值参数,放在了m这个未知参数的前面,应该报错,其实z和m都是命名关键字参数,不是默认值参数和位置参数

def func(x, y = 1, *args, z = 3, m, **kwargs):
    print(x, y)
    print(args)
    print(z, m)
    print(kwargs)
func(1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, z = 99, m = 999, o = 9999, i = 99999)

  

三、函数对象

函数时第一类对象:函数名指向的值可以被当做参数传递

1、函数名可以被传递

# 变量值的传递
name = 'jason'
x = name
print(x)
print(id(name))
print(id(x))
# 输出
jason
45859872
45859872

# 函数名指向的值的传递
def func():
    print("from func")
f = func
print(f)
print(func)
print(id(f))
print(id(func))
# 输出
<function func at 0x02BBA660>
<function func at 0x02BBA660>
45852256
45852256

  2、函数名可以被当做参数传递给其他函数

def func():
    print("from func")
def index(args):
    print(args)
    print("from index")
index(func)
# 输出
<function func at 0x0096A660>
from func
from index

  3、函数名可以被当做函数的返回值

def index():
    print("index")
def func():
    print("func")
    return index
res = func()
print(res)
res()
# 输出
func
<function index at 0x0295A660>
index

  4、函数名可以被当做容器类型的参数

def func():
    print("func")
print(func())
l = [1, 2, func, func()]
print(l)
# 输出
func
None
func
[1, 2, <function func at 0x00DEA660>, None]

  

四、函数的嵌套调用

  在函数内部调用其他函数,可以将复杂的逻辑简单化

def index():
    func()
    print("index")
def func():
    print("func")
index()
# 输出
func
index

# 比较4个数的大小,由比较两个数的大小实现
def my_max(x, y):
    if x>y:
        return x
    return y

def my_max4(a, b, c, d):
    res1 = my_max(a, b)
    res2 = my_max(res1, c)
    res3 = my_max(res2, d)
    return res3
print(my_max4(2, 10, 4, 6))
# 输出
10

  

五、函数的嵌套定义

def outer():
    x = 1
    print("outer")
    def inner():
        print("inner")
    print(inner)
    return inner
res = outer()
print(res)
res()
# 输出
outer
<function outer.<locals>.inner at 0x02E936F0>
<function outer.<locals>.inner at 0x02E936F0>
inner

"""
函数内定义函数应用场景
写一个函数
该函数用户可以通过传参的不同控制函数执行不同的功能
"""

  

六、名称空间

1、名称空间是什么?

  存放变量名与变量值的内存地址的绑定关系的地方,要想访问一个变量,必须先去名称空间中拿到对应的名字,才能够访问变量的值

name = "jason"
print(name)
print(id(name))
# 输出
jason
49923104

2、名称空间的分类

  ①、内置名称空间:Python解释器提前给你定义好的名字(已经存放到内置名称空间中了)

  len、max、min

  ②、全局名称空间:文件级别的代码

x = 1

if 1 ==1:
    y = 2

while True:
    z = 3
    break

print(x, y, z)
# 输出
1 2 3

# if for while无论嵌套多少层,它们内部所创建的名字都属于全局名称空间

  ③、局部名称空间:函数体内创建的名字都属于局部名称空间

3、名称空间的生命周期

内置名称空间:只要Python解释器一启动立马创建,关闭Python解释器时自动销毁

全局名称空间:只要你运行Python文件就会自动创建,程序运行结束时自动销毁

局部名称空间:函数被调用的时候自动创建,函数执行结束立即销毁(动态创建动态销毁)

4、名称空间的查找顺序

  ①、首先确定你当前在哪

    站在全局:全局 >> 内置

    站在局部:局部 >> 全局 >> 内置

  ②、函数在定义阶段查找名字的顺序就已经固定了,不会因为函数的调用位置变化而变化

5、名称空间的作用域

①、作用域

  全局作用域(全局有效):内置名称空间 全局名称空间

  局部作用域(局部有效):局部名称空间

②、在局部修改全局变量的值

  如果是可变类型,如列表、字典等,可以直接修改,不论嵌套层数

  如果是不可变类型,如字符串等,不可以直接修改,必须使用global加变量名,将这个变量申明为全局变量,才可以修改,修改多个用逗号隔开

③、在局部修改局部变量的值(嵌套函数的内层修改外层的变量)

  如果是可变类型,如列表、字典等,可以直接修改,不论嵌套层数

  如果是不可变类型,如字符串等,不可以直接修改,必须使用nonlocal加变量名,将这个变量申明为非局部变量,才可以修改,修改多个用逗号隔开

posted @ 2019-07-10 16:39  竣~  阅读(208)  评论(0编辑  收藏  举报