码迷,mamicode.com
首页 > 编程语言 > 详细

python 6期 函数(二)

时间:2017-07-30 12:45:19      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:url   保护   ima   ret   closure   本质   内存   int   开始   

函数的命名空间

定义:可以理解为一个容器,在这个容器中可以装许多标识符。不同容器中的同名的标识符是不会相互冲突

命名空间的三种形式

内置命名空间     全局命名空间        局部命名空间 

内置   在创建函数的时候生成的,存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法

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

 加载顺序:

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

取值顺序:

   (1) 在局部调用:局部命名空间->全局命名空间->内置命名空间

1 x = 1
2 def f(x):
3     print(x)
4 
5 print(10)

  (2)在全局调用:全局命名空间->内置命名空间

技术分享
1 x = 1
2 def f(x):
3     print(x)
4 
5 f(10)
6 print(x)
 

函数作用域

定义   作用域就是作用范围

分类 

1  全局作用域:   包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效  

2局部作用域:    局部名称空间,只能在局部范围生效

作用域中的关键字

globals和locals

 
技术分享
1 def func():
2     a = 12
3     b = 20
4     print(locals())
5     print(globals())
6 
7 func()
技术分享

global关键字

技术分享
1 a = 10
2 def func():
3     global a
4     a = 20
5 
6 print(a)
7 func()
8 print(a)
技术分享

作用域总结:

站在全局看:
使用名字:
如果全局有:用全局的
如果全局没有:用内置的


 

 

 

函数的嵌套和作用域链

  函数的嵌套调用

技术分享
1 def f1():
2     print(‘f1‘)
3 def f2():
4     a = 10
5     f1()              
6 f2()
7 #代码从上到下读取,f2()调用会调用f2()函数体的内容,最后发现f1()然后调用f1()开始执行函数体的内容最后输出f1
技术分享

  

函数的嵌套:
为了保护内部函数,确定内部函数只能在外部函数中被调

 
技术分享
 1 def animal():
 2     def tiger():
 3         print(‘bark‘)
 4     print(‘eat‘)
 5     tiger()
 6 animal()           #函数嵌套调用
 7 
 8 
 9 eat
10 bark
技术分享

 

技术分享
技术分享
 1 def f1():
 2     def f2():
 3         def f3():
 4             print("in f3")
 5         print("in f2")
 6         f3()
 7     print("in f1")
 8     f2()
 9     
10 f1()
技术分享

  函数的作用域链

技术分享
1 ef f1():
2     a = 1
3     def f2():
4         print(a)
5     f2()
6 
7 f1()
技术分享
技术分享
1 def f1():
2     a = 1
3     def f2():
4         a = 2
5     f2()
6     print(‘a in f1 : ‘,a)
7 
8 f1()
技术分享

  nonlocal关键字

技术分享
 1 def f1():
 2     a = 1
 3     def f2():
 4         nonlocal a
 5         a = 2
 6     f2()
 7     print(‘a in f1 : ‘,a)
 8 
 9 f1()         
10 #函数会使用自己本身的a的赋值,f2()函数体里面的赋值用完会从内存删除掉,想保留要加入nonlocal 加变量名才能会取f2()函数体里a的赋值
技术分享

 

函数名的本质

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

  1.可以被引用

技术分享
 1 def func():
 2     print(‘func‘)
 3 print(func)
 4 f=func
 5 print(f)
 6 f()
 7 
 8 <function func at 0x000001C390B4B9D8>
 9 <function func at 0x000001C390B4B9D8>
10 func
11 
12 
13 #会指向函数的内存地址,不会取用函数里面的值,只有加()才能调用函数
技术分享

  2.可以被当作容器类型的元素

技术分享
 1 def func():
 2     print(‘func‘)
 3 print(func)
 4 f=func
 5 print(f)
 6 l = [f]
 7 print(l)
 8 l[0] == f
 9 l[0]()
10 
11 
12 <function func at 0x0000025B3C73B9D8>
13 <function func at 0x0000025B3C73B9D8>
14 [<function func at 0x0000025B3C73B9D8>]
15 func
技术分享

  3.可以当作函数的参数和返回值

1 第一类对象(first-class object)指
2 1.可在运行期创建
3 2.可用作函数参数或返回值
4 3.可存入变量的实体。

 

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

闭包

1.闭 内部的函数
2.包 包含了对外部函数作用域中变量的引用

闭包的常用形式

1 def hei():
2     x = 20
3     def inner():
4         print(x)  #局部的
5     return inner

闭包函数:

内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
函数内部定义的函数称为内部函数

由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?返回呀!

我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?

是不是直接就把这个函数的名字返回就好了?

这才是闭包函数最常用的用法

技术分享
1 def func():
2     name = ‘eva‘
3     def inner():
4         print(name)
5     return inner
6 
7 f = func()
8 f()
技术分享

判断闭包函数的方法.__closure__

技术分享
技术分享
 1  def func():
 2      name = ‘eva‘
 3      def inner():
 4          print(name)
 5      print(inner.__closure__)
 6      return inner()
 7 func()    #看输出是否有cell元素有就是闭包函数
 8 
 9 
10 (<cell at 0x000002711EE465B8: str object at 0x000002711EEDA500>,)
11 eva
12 
13 
14 
15 
16 #输出的__closure__为None :不是闭包函数
17 name = ‘egon‘
18 def func2():
19     def inner():
20         print(name)
21     print(inner.__closure__)
22     return inner
23 
24 f2 = func2()
25 f2()
26 
27 
28 None
29 egon
技术分享

 

  闭包函数的嵌套

技术分享
 1 def wrapper():
 2     money = 1000
 3     def func():
 4         name = ‘eva‘
 5         def inner():
 6             print(name,money)
 7         return inner
 8     return func
 9 
10 f = wrapper()
11 i = f()
12 i()
技术分享

闭包函数在网络上的应用

技术分享
 1 from urllib.request import urlopen
 2 
 3 def index():
 4     url = "http://www.xiaohua100.cn/index.html"
 5     def get():
 6         return urlopen(url).read()
 7     return get
 8 
 9 xiaohua = index()
10 content = xiaohua()
11 print(content)
技术分享

小结:

命名空间:

  有三种命名空间从大到小的范围顺序:内置命名空间、全局命名空间、局部命名空间

作用域(包括函数的作用域链):

  调用时,如果在自己的空间内有,就用自己的。如果没有就使用大范围的。不能从大范围中用小范围的。

函数的嵌套:

  嵌套调用

  嵌套定义:定义在内部的函数无法直接在全局被调用

函数名的本质:

  就是一个变量,保存了函数所在的内存地址

闭包:

  内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数

python 6期 函数(二)

标签:url   保护   ima   ret   closure   本质   内存   int   开始   

原文地址:http://www.cnblogs.com/bypp/p/7252434.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!