一、函数对象

1、函数对象:函数名存放的就是函数的地址,所以函数名也是对象,称之为函数对象

a = 10
print(a,id(a))

def fn():
    num = 10
    print('fn fuction run')
print(fn())

b = a
print(b,id(b))

2、函数对象的四个应用

①可以直接被引用fn=cp_fn

def fn():
    num = 10
    print('fn function run')
print(fn)

def fn():
    num = 10
    print('fn function run')

func = fn
print(fn)
print(func)

②可以当做函数参数传递computed(cp_fn,a,b)

# 通过该函数可以对任意两个数的四则运算某一运算
def add(a,b):
    return a+b
def low(a,b):
    return a-b
def jump(a,b):
    return a*b
def full(a,b):
    return a/b
def computed(fn,a,b):   # fn代表四则运算的一种,res为运算结果
    res = fn(a,b)
    return res

while True:
    cmd = input('cmd:>>>')
    if cmd =='add':
        result=computed(add,100,200)
    elif cmd =='low':
        result=computed(low,100,200)
    elif cmd =='jump':
        result=computed(jump,100,200)
    elif cmd =='full':
        result=computed(full,100,200)
    else:
        print('输入有误')
    print(result)

③可以作为容器类型的元素

def add(a,b):
    return a+b
def low(a,b):
    return a-b
def jump(a,b):
    return a*b
def full(a,b):
    return a/b
def quyu(a,b):
    return a %b
def computed(fn,a,b):
    res = fn(a,b)
    return res
method_map={
    'add':add,
    'low':low,
    'jump':jump,
    'full':full,
    'quyu':quyu,
}

while True:
    cmd = input('cmd:')   # 用户输入的指令只要有对应关系,就会自动取走计算方法
    if cmd in method_map:          # 这样外界就不关心有哪些计算方法
        cp_f = method_map[cmd]
        result = computed(cp_fn,100,200)
        print(result)
    else:
        print('输入错误')
        break

④可以作为函数的返回值

def add(a,b):
    return a +b
def low(a,b):
    return a-b
def jump(a,b):
    return a*b
def full(a,b):
    return a/b
def quyu(a,b):
    return a%b

def computed(fn,a,b):
    res = fn(a,b)
    return res

method_map = {
   'add':add,
    'low':low,
    'jump':jump,
    'full':full,
    'quyu':quyu,
}
# 根据指令获取计算方法
def get_cp_fn(cmd):
    if cmd in method_map:
        return method_map[cmd]    # 返回的是method_map中的’cmd’对应的值cmd
    return jump                   # 输入有误就采用jump

while True:
    cmd = input('cmd:')
    if cmd =='quit':
        break
    cp_fn = get_cp_fn(cmd)
    result = computed(cp_fn,100,200)
    print(result)

 

二、名称空间

print(len('abc'))     # 结果为 3
len = len('abcsdf')
print(len)            # 结果为 6
del len
print(len('abc'))     # 结果为 3

def fn1():
    len = 100
    print(len)

def fn2():
    len = 200
    print(len)
fn1()
fn2()

1、定义:存放名字与内存空间地址对应关系的容器

2、作用:解决由于名字有限,导致名字重复发送冲突的问题

3、三种名称空间:

①build-in:内置名称空间,系统级,一个,随解释器执行而产生,解释器停止而销毁
②global:全局名称空间,文件级,多个,随所属文件加载而产生,文件运行完毕而终止
③local:局部名称空间,函数级,多个,随所属函数执行而产生,函数执行完毕而销毁
加载顺序:build-in>global>local

4、global关键词

  可以将local的名字提升为global的名字。一个文件中的global名字就是一个,所以函数内外部使用的名字都是一个

  注意:一定要调用函数,才能产生函数,并提升

# part1
len =1000
def fn():
    len = 200
    print(len)
fn()              # 结果为200
print(len)        # 结果为1000


# part2
l = []
def fn():
    l=[]
    l.append(200)
    print(l)
fn()             # 结果为 [200]
print(l)         # 结果为[]

# 定义一个函数,函数中有一个变量
def fn1():
    num = 200
    return num
fn1()
# 在定义一个函数,该函数使用上一个函数的变量
def fn2():
    print(num)
num = fn1()
fn2()


# part3
num = 100
def fn1():
    global num #100     # 将logal:num>global:num  # 将局部上升到全局
    num=200
    num=300
# num=300
def fn2():              # logal中的名字一旦global,就变成global的名字,一个文件中的global就是一个
    global num #300
    num = 400
    print(num)
# num=400
fn1()
print(num)     # 结果为300
fn2()
print(num)     # 结果为300 400 400

 

三、作用域

1、定义:名字起作用的范围

2、作用:解决名字可以共存问题

3、四种作用域

①build-in:内置作用域,所有文件所有函数
②global:全局作用域,当前文件所有函数
③local:局部作用域,当前函数
④enclosing:嵌套作用域,当前函数与当前函数的内部函数
len = 100
def outer():
    len = 200
    def inner():
        len =300
        print('1',len)     # 结果为300
    inner()
    print('2',len)         # 结果为200
outer()
print('3',len)             # 结果为100

del len
print('4',len)             # 4 <built-in function len>

4、不同作用域之间名字不冲突,以达到名字的重用

查找顺序:local>enclosing>glocal>build-in

 

四、函数的嵌套定义和闭包

1、函数的嵌套定义:将函数直接定义到另一个函数的内部,可以使用外部函数中的名字

def fn1():
    num = 200
    def fn2():   # fn2就可以直接使用fn1中的名字
        print(num)
    fn2()
fn1()

2、闭包:

①closure:被包裹的函数称之为闭包。定义在函数内部的函数

②完整的闭包结构:

将函数进行闭包处理

提升函数名的作用域,将内部函数对象作为外部函数的返回值

def a():
    def b():
        print("cc")
    return b
a()        #a()=b          
y = a()()    # a()() =b()
y             # 结果为 cc


def a():
    def b():
        def c():
            def d():
                print('dddd')
            return d
            print("ccc")
        return c
    return b
a()       # b
a()()     #b()
a()()()   #b()() = c()
a()()()
y=a()()()()
y         # 结果为 dddd