07_Python函数进阶_全栈开发学习笔记

# 1. 命名空间

## 1.1 命名空间的种类

命名空间共有有三种

1) 内置命名空间 —— python解释器

就是python解释器一启动就可以使用的名字存储在内置命名空间中

内置的名字在启动解释器的时候被加载进内存里

<br>

2) 全局命名空间 —— 我们写的代码但不是函数中的代码

是在程序从上到下被执行的过程中依次加载进内存的

放置了我们设置的所有变量名和函数名

<br>

3) 局部命名空间 —— 函数

就是函数内部定义的名字

当调用函数的时候,才会产生这个名称空间,随着函数执行的结束,这个命名空间就又消失了。

<br>

## 1.2 三种命名空间之间的加载与取值顺序

加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

* 在局部:可以使用全局、内置命名空间中的名字

* 在全局:可以使用内置命名空间中的名字,但是不能用局部中使用

* 在内置:不能使用局部和全局的名字的

<br>

## 1.3 命名空间的其他说明

1) 在正常情况下,直接使用内置的名字

2) 当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字

3) 当我自己有的时候 我就不找我的上级要了

4) 如果自己没有,就找上一级要,上一级没有再找上一级,如果内置的名字空间都没有,就报错

5) 多个函数应该拥有多个独立的局部名字空间,不互相共享

范例1:(对应1、2、3、4)

```python

def max(l):

    print("in max func")

print(max([1,2,3]))

```

执行结果

```

in max func

None

```

<br>

范例2:(对应4)

```

def input():

    print("in inpput now")

def func():

    input()

func()

```

执行结果

```

in inpput now

```

<br>

范例3:(对应4)

```python

def input():

    print("in inpput now")

def func():

    input = 1

    print(input)

func()

```

执行结果

```

1

```

<br>

范例4:(对应5)

```python

def fun1():

    a = 1

def func2():

    print(a)

print(func2())

```

执行结果

```

Traceback (most recent call last):

  File "E:/python_project/S9/hello.py", line 8, in <module>

    print(func2())

  File "E:/python_project/S9/hello.py", line 6, in func2

    print(a)

NameError: name 'a' is not defined

```

----------

# 2 作用域

## 2.1 作用域的种类

作用域共两种

1) 全局作用域 —— 作用在全局 —— 内置和全局名字空间中的名字都属于全局作用域  —— globals()

范例1:

```python

a = 1

def func():

    print(a)

func()

```

执行结果:

```

1

```

<br>

* 对于不可变数据类型,在局部可以查看全局作用域中的变量,但是不能直接修改

* 如果想要修改,需要在程序的一开始添加global声明

* 如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效

范例2:global关键字(但使用global方式不安全,尽量少用)

```python

a = 1

def func():

    global a

    a += 1

func()

print(a)

```

执行结果:

```

2

```

<br>

2) 局部作用域 —— 作用在局部 —— 函数(局部名字空间中的名字属于局部作用域) —— locals()

<br>

## 2.2 作用域的方法两则(不常用)

globals() 永远打印全局的名字

locals() 输出什么 根据locals所在的位置,在全局输出全局,在局部输出局部

范例:

```python

a = 1

b = 2

def func():

    x = "aaa"

    y = "bbb"

    print(locals())

func()

print(globals())

```

执行结果:

```

{'x': 'aaa', 'y': 'bbb'}

{'a': 1, '__package__': None, '__builtins__': <module 'builtins' (built-in)>, '__spec__': None, '__file__': 'D:/temp_study/python01/test.py', '__loader__': <_frozen_importlib.SourceFileLoader object at 0x0000000003C64D68>, 'b': 2, '__name__': '__main__', 'func': <function func at 0x000000000331CB70>, '__doc__': None, '__cached__': None}

```

----------

# 3 函数的嵌套与作用域链

## 3.1 函数的嵌套调用

范例:

```python

def my_max(a,b):

    return a if a > b else b

def three_max(x,y,z):    # 函数的嵌套调用

    c = my_max(x,y)

    return my_max(c,z)

print(three_max(1,2,3))

```

执行结果

```

3

```

<br>

## 3.2 函数的嵌套定义

1) 函数嵌套定义的正常流程

范例:

```python

def outer():    # 第一步

    def inner():    # 第三步

        print("inner")    # 第五步

    inner()    # 第四步

outer()    # 第二步

```

执行结果

```

inner

```

<br>

2) 内部函数可以使用外部函数的变量

范例:

```

def outer():

    a = 1

    def inner():

        print(a)

        print("inner")

    inner()

outer()

```

执行结果

```

1

inner

```

<br>

3) 三层嵌套

范例1:

```

def outer():

    a = 1

    def inner():

        print(a)

        print("inner")

        def inner2():

            print("inner2")

        inner2()

    inner()

outer()

```

执行结果:

```

1

inner

inner2

```

<br>

范例2:

```python

def outer():

    a = 1

    def inner():

        b = 2

        print(a)

        print("inner")

        def inner2():

            print(a,b)

            print("inner2")

        inner2()

    inner()

outer()

```

执行结果:

```

1

inner

1 2

inner2

```

<br>

### 3.2.1 nonlocal()

nonlocal 只能用于局部变量 找上层中离当前函数最近一层的局部变量。

声明了nonlocal的内部函数的变量修改会影响到离当前函数最近一层的局部变量。

对全局:无效

对局部:也只是对最近的一层有影响

范例1:

```

a = 1    # 这是全局变量

def outer():

    a = 1    # 这是局部变量

    def inner():

        b = 2

        print(a)

        print("inner")

        def inner2():

            nonlocal a    # 声明了一个上面第一层局部变量(离它最近的局部变量)

            a += 1    # 不可变数据类型的修改

            print("inner2")

        inner2()

    inner()

    print("**a** :",a)

outer()

print("全局:",a)

```

执行结果

```

1

inner

inner2

**a** : 2

全局: 1

```

<br>

范例2:

```python

a = 1

def outer():

    a = 1

    def inner():

        a = 2

        print(a)

        print("inner")

        def inner2():

            nonlocal a

            a += 1

            print("inner2")

        inner2()

        print("##a##:",a)

    inner()

    print("**a** :",a)

outer()

print("全局:",a)

```

执行结果

```

2

inner

inner2

##a##: 3

**a** : 1

全局: 1

```

<br>

范例3:

```python

a = 0

def outer():

    # a = 1

    def inner():

        a = 2

        def inner2():

            nonlocal a

            print(a)

        inner2()

    inner()

outer()

```

执行结果

```

2

```

<br>

## 3.3 作用域链

在内部函数使用变量的时候,是从小局部到大局部到全局到内置名字的过程一级一级往上找,找到最近的一个就使用----作用域链

范例1:

```python

def f1():

    a = 1

    def f2():

        print(a)

    f2()

f1()

```

执行结果:

```

1

```

<br>

范例2:

```python

def f1():

    a = 1

    def f2():

        def f3():

            print(a)

        f3()

    f2()

f1()

```

执行结果:

```

1

```

<br>

范例3:

```python

def f1():

    a = 1

    def f2():

        a = 2

    f2()

    print('a in f1 : ',a)

f1()

```

执行结果:

```

a in f1 :  1

```

----------

# 4 函数名的本质

函数名本质上就是函数的内存地址

范例1:可以被引用

```python

def func():

    print(123)

# func()  #函数名就是内存地址

func2 = func    # 函数名可以赋值

func2()

```

执行结果

```

123

```

<br>

范例2:可以被当作容器类型的元素

```python

def func():

    print(123)

func2 = func

func2()

l = [func,func2]    # 函数名可以作为容器类型的元素

print(l)

for i in l:

    i()

```

执行结果

```

123

[<function func at 0x000002604CB969D8>, <function func at 0x000002604CB969D8>]

123

123

```

<br>

范例3:可以当作函数的参数

```python

def func():

    print(123)

def wahaha(f):

    f()

wahaha(func)    # 函数名可以作为函数的参数

```

执行结果

```

123

```

<br>

范例4:可以当作函数的返回值

```

def func():

    print(123)

def wahaha(f):

    f()

    return f          #函数名可以作为函数的返回值

qqxing = wahaha(func)  # 函数名可以作为函数的参数

qqxing()

```

执行结果

```

123

123

```

`不明白?那就记住一句话,就当普通变量用`

第一类对象(first-class object)指

1.可在运行期创建

2.可用作函数参数或返回值

3.可存入变量的实体。

----------

# 5 闭包(函数)

闭包:嵌套函数,内部函数调用外部函数的变量

```python

def outer():

    a = 1

    def inner():

        print(a)

```

<br>

## 5.1 闭包的常用形式

```python

def outer():

    a = 1

    def inner():

        print(a)

    return inner

inn = outer()

inn()

```

执行结果

```

1

```

<br>

## 5.2 \__closure\__

判断闭包函数的方法__closure__

范例:

```python

def outer():

    a = 1

    def inner():

        print(a)

    print(inner.__closure__)

outer()

print(outer.__closure__)

```

执行结果:

```

(<cell at 0x00000000026C02E8: int object at 0x000000005BB180C0>,)    # 输出的__closure__有cell元素 :是闭包函数

None    # 输出的__closure__为None :不是闭包函数

```

<br>

## 5.3 闭包函数的模拟案例

不闭包的案例:

```python

from urllib.request import urlopen

ret = urlopen("https://www.baidu.com").read()

print(ret)

```

执行结果:

```

b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'

```

<br>

闭包案例:

```python

from urllib.request import urlopen

def get_url():

    url = "https://www.baidu.com"

    def get():

        ret = urlopen(url).read()

        print(ret)

    return get

get_func = get_url()

get_func()

```

执行结果:

```

b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343