day10:函数进阶

1,函数的命令空间(内置命名空间,全局命名空间,局部命名空间),内置大于全局大于局部

2,内置命名空间,就是Python解释器一启动就可以使用的名字,存储在内置命名空间中,内置的名字(print,input,list,tuple等等),启动解释器的时候加载到内存里面;

3,全局命令空间,是在程序从上到下被执行的过程中一次加载到内存的,放置了我们所有的变量名和函数名;

4,局部命名空间,就是函数内部定义的名字,当调用函数的时候,才会产生这个名称空间,随着函数执行的结束,这个名称空间就又消失了

5,在局部,可以使用全局,内置空间中的名字;在全局,可以使用内置空间中的名字,但是不能用局部中中的名字;在内置空间,不能使用局部或者全局的名字

6,在正产改的情况下,直接使用内置的名字,当我在全局中定义了和内置名字空间中同名的名字时,我们会使用全局的名字

7,当我自己有的时候,我就不找上一级要了,当我自己没有的时候,就找上一级要,上一级也没有,再找上一级,都没有,就报错

8,函数名的本质是函数的内存地址,函数名加上括号,是函数的调用,函数的内存地址加上括号也是函数的调用,估计没人会这么用

9,作用域有两种:全局作用域(内置和全局命名空间中的名字术语全局作用域),局部作用域,作用在局部(函数,局部名字空间中的名字术语局部作用域)

10,对于不可变数据类型,在局部可以直接查看全局作用域中的变量,但是不能修改,如果想要修改,需要在程序一开始的时候添加global声明。

11,如果一个局部函数内声明了一个global的变量,那么这个变量在局部的所有操作,都是对全局变量的操作

12,locals和globals 查看全局和局部变量,加上global就不在是局部变量了,globals()永远打印全局变量,locals根据所在位置输出

a = 1
def func():
    c =1
    a = 2
    # global a
    # a = 2
    print(locals())

func()

运行结果:
{'c': 1, 'a': 2}

a = 1
def func():
    c =1
    # a = 2
    global a
    a = 2
    print(locals())

func()
运行结果:
{'c': 1}

13,上一小节复习,所有的函数只定义不调用就一定不执行,先定义后调用,直接写函数名() 这样不接收返回值,返回值=函数名() 接收返回值 ,只写一个return是巍峨结束一个函数,返回一个值,结束了函数,且返回一个值

14,复习,形参来说,位置参数必须传,*args 可以接收零到多个按位置传入的参数,默认参数,可以不传,**kwargs:动态参数,可以接收任意多个按照关键字传递的参数。

15,复习,实参来说,调用的时候,按照位置传参数,按照关键字传参数,可以混用,但是位置必须在关键字之前,不能对一个参数重复赋值。

16,默认参数的陷阱问题,如果默认参数是一个可变的数据类型,那么每一次调用函数,的时候,如果不传值,就公用这个数据类型的资源

def func(li = []):
    li.append(1)
    print(li)

func()
func()
func()
func()
func([])  # 这儿因为传入了新的参数列表,不共用,所有其他的使用默认参数的,都共用那一个列表
func()

运行结果:
[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 1]
[1]
[1, 1, 1, 1, 1]

17,对于字典也是一样的,因为key 不能重复,所以每次值是可以更新的,同样有陷阱

def func(k,dict1={}):
    dict1[k]='v'
    print(dict1.items())

func(1)
func(3)
func(4)
func(5)
func(6,{})
func(7)

运行结果:
dict_items([(1, 'v')])
dict_items([(1, 'v'), (3, 'v')])
dict_items([(1, 'v'), (3, 'v'), (4, 'v')])
dict_items([(1, 'v'), (3, 'v'), (4, 'v'), (5, 'v')])
dict_items([(6, 'v')])
dict_items([(1, 'v'), (3, 'v'), (4, 'v'), (5, 'v'), (7, 'v')])

18,三元运算符

# 定义函数找出两个数中的最大值
def max_of_two(a,b):
    return a if a>b else b

#定义函数,找出三个数中的最大值
def max_of_three(a,b,c):
    z = max_of_two(a,b)  # 函数的嵌套调用
    return max_of_two(z,c)

print(max_of_three(3,4,5))

19,函数的嵌套定义

def outer():
    def inner():
        print("i am inner")

outer()   # 这样写并不会打印里面的那句话,因为只是定义了然,然后没有调用,就结束了
def outer():
    def inner():
        print("i am inner")
    inner()  # 加上这句话才会打印的

outer()   # 这样写并不会打印里面的那句话,因为只是定义了然,然后没有调用,就结束了

20,内部函数虽然不能直接修改外部函数的变量,但是可以看和使用

def outer():
    a = 1
    def inner1():
        b = 2
        print(a)
        print("i am inner")
        def inner2():
            print(a,b)
            print("i am inner2")
        inner2()
    inner1()  # 加上这句话才会打印的
outer()

运行结果:
1
i am inner
1 2
i am inner2

21,本空间有的变量,不会向上一层去找了就,申明了global的变量,只会对全局里面的变量进行操作

a =1
def outer():
    a = 10
    def inner1():
        a = 100 # 本空间有的变量,不会向上去找了就
        print(a)
        print("i am inner")
        def inner2():
            global a # 不可变数据类型的修改,这样定义只是修改全局变量的a 并不会修改函数内的a
            a +=1  # 不可以这样修改
            print(a)
            print("i am inner2")
        inner2()
    inner1()  # 加上这句话才会打印的
outer()

运行结果:
100
i am inner
2
i am inner2

22,不可变数据类型的修改,如果想要修改上层函数内部的变量,而不是全局变量,可以用nonlocal,会一层层往上找,但是不会用全局空间里面的变量

nonlocal只应用于局部变量,找上层中离当前函数最近的一层的局部变量,声明了nonlocal的内部函数的变量修改会影响到离当前函数最近一层的局部变量

对全局无效,对局部也只是对最近的有这个变量的一层有效。

a =1
def outer():
    a = 10
    def inner1():
        a = 100 # 本空间有的变量,不会向上去找了就
        print(a)
        print("i am inner1")
        def inner2():
            nonlocal a
            a +=1  
            print(a)
            print("i am inner2")
        inner2()
    inner1()  # 加上这句话才会打印的
outer()

运行结果:
100
i am inner1
101
i am inner2
a =1
def outer():
    a = 10
    def inner1():
        # a = 100 # 本空间有的变量,不会向上去找了就
        print(a)
        print("i am inner1")
        def inner2():
            nonlocal a
            a +=1
            print(a)
            print("i am inner2")
        inner2()
    inner1()  # 加上这句话才会打印的
outer()

运行结果:
10
i am inner1
11
i am inner2
a =1
def outer():
    # a = 10 #注释掉
    def inner1():
        # a = 100 # 注释掉
        print(a)
        print("i am inner1")
        def inner2():
            nonlocal a
            a +=1
            print(a)
            print("i am inner2")
        inner2()
    inner1()  # 加上这句话才会打印的
outer()

运行结果:
  File "/Users/guolixiao/PycharmProjects/lisa's_practise/boys/10.2.py", line 28
    nonlocal a
    ^
SyntaxError: no binding for nonlocal 'a' found

23,后端语言有好多种,Python/java/C/C++/JAVA/PHP,每个语言占得分量差不多,前端语言有HTML/CSS/JS, 其中JS占据着举足轻重的地位。

24,函数名就是变量地址,函数名可以赋值,函数名可以作为容器类的元素

def func():
    print("happy day")

func2 = func # 注意不加括号才表示地址,加了括号表示调用
li = [func2,func]
for i in li:
    print(i)
    i()

# 其实就理解为普通变量用
运行结果:
<function func at 0x10638e840>
happy day
<function func at 0x10638e840>
happy day

25,函数名可以作为函数的参数

def func():
    print("happy day")

def wahaha(f):
    f()
    
wahaha(func)
运行结果:
happy day

26,函数名可以作为返回值

def func():
    print("happy day")

def wahaha(f):
    f()
    return f  #函数名可以作为返回值
qqxing=wahaha(func)
qqxing()

运行结果:
happy day

27,函数名可以在运行是创建,可以当函数参数或者返回值,可以做容易类型的元素,可存入变量的实体

28,闭包:嵌套函数,内层函数使用外层函数的变量,不适用的话,就不是闭包

def outer():
    a = 1
    def inner():
        print(a)

# 这就是一个闭包

29,双下函数决定是否是闭包 __clousure__

def outer():
    a = 1
    def inner():
        print(a)
    print(inner.__closure__)
outer()

运行结果:
(<cell at 0x10c269e88: int object at 0x10c01ec00>,)


def outer():
    a = 1
    def inner():
        print(1)  #不再调用a 
    print(inner.__closure__)
outer()

运行结果:
None
def outer():
    a = 1
    def inner():
        print(a)
    print(inner.__closure__)
outer()
print(outer.__closure__)

运行结果:
(<cell at 0x10edb6e88: int object at 0x10eb6ac00>,)
None

30,如何在外部使用内部的函数?return

def outer():
    a = 1
    def inner():
        print("inner")
        print(a)
    return inner

inn = outer()
inn()

运行结果:
inner
1

31,写一个闭包的简单例子

from urllib.request import urlopen

def get_url():
    url = "http://www.xiaohuar.com/"
    def get():
        ret=urlopen(url).read()
        print(ret)
    return get

get_func = get_url()
get_func()
get_func()

# 实现了一个简单的闭包

 

转载于:https://www.cnblogs.com/lisa-blog/p/10067898.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值