一、函数名的应用

# 1,函数名就是函数的内存地址,而函数名()则是运行这个函数。
def func():
return print(func) # 返回一个地址 # 2,函数名可以作为变量。
def func1():
print(666) f1 = func1
f2 = f1
f2() # 就等于func1() 此时执行函数 # 3,函数名可以作为函数的参数。
def func1():
print(666) def func2(x):
x() func2(func1) # 输出666 func1作为实参传进func2中,此时在func2中x()等于func1() # 4,函数名可以当做函数的返回值。
def wraaper():
def inner():
print(666)
return inner ret = wraaper() # 执行函数wraaper(),得到返回值inner赋值给ret,这个inner是函数名
ret() # 输出666,ret()等于inner()
# (注意:这里要调用inner()只能是用ret(),因为inner()是wraaper()的嵌套函数,在全局命名空间中并没有声明,所以直接用inner()不能执行,) def func2():
print('in func2') def func3(x):
print('in func3')
return x f = func3(func2) # 给func3传进一个参数func2,返回func2赋值给f
f() # f()等于func2() # 5,函数名可以作为容器类类型的元素。
def f1():
print('f1') def f2():
print('f2') def f3():
print('f3') l = [f1, f2, f3]
d = {'f1': f1, 'f2': f2, 'f3': f3}
# 调用
l[0]() # 输出 f1
d['f2']() # 输出 f2 def func1():
print('in func1') def func2():
print('in func2') def func3():
print('in func3') def func4():
print('in func4') l1 = [func1,func2,func3,func4] #调用
for i in l1:
i() # 像上面的函数名这种,称为第一类对象。
# 第一类对象(first-class object)指:
# 1.可在运行期创建
# 2.可用作函数参数或返回值
# 3.可存入变量的实体。
# (如果不明白,那就记住一句话,就当普通变量用)

6、globals()        locals()
globals()    #返回全局变量(包含内置函数)的一个字典。
locals()      #返回当前位置的变量的字典。
例如:

def func1():
a = 2
b = 3
print(globals()) # 此时globals()在局部命名空间中,但也是返回全局命名空间的一个字典
print(locals()) # 此时locals()在局部命名空间中,所以返回的是局部命名空间的一个字典{'b': 3, 'a': 2} print(globals()) # 此时globals()在全局命名空间中,返回全局命名空间的一个字典
print(locals()) # 此时locals()在全局命名空间中,所以返回的是全局命名空间的一个字典
func1() # 结果: # {'__name__': '__main__', '__doc__': None(后面还有一大推东西,省略)...} # {'__name__': '__main__', '__doc__': None(后面还有一大推东西,省略)...} # {'__name__': '__main__', '__doc__': None(后面还有一大推东西,省略)...} # {'b': 3, 'a': 2}

总结:
globals()无论在哪个命名空间,返回的都是全局命名空间的一个字典
locals()在哪个命名空间就返回哪个命名空间的字典

def func1():
a = 2
b = 3
def inner():
c = 5
d = 6
print(globals()) #{'__name__': '__main__', '__doc__': None(后面还有一大推东西,省略)...}
print(locals()) #{'c': 5, 'd': 6}
inner()
func1()

二、闭包

1、内层函数引用外层函数的变量(非全局变量),这样该内部函数称就称为闭包函数。
(我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?
就把这个函数的名字返回就好了,这是闭包函数最常用的用法)

def wraaper():
name = '鬼见愁'
def inner():
print(name)
return inner f = wraaper()
f()

2、判断闭包函数的方法__closure__

# 1,是闭包返回值会有cell元素
def wraaper():
name = '鬼见愁'
def inner():
print(name)
print(inner.__closure__)
return inner
f = wraaper()
f() # 2,不是闭包就会返回None
name = '鬼见愁'
def wraaper():
def inner():
print(name)
print(inner.__closure__) # None
return inner
f = wraaper()
f() name = '番薯'
def wraaper(n):
n = '番薯'
def inner():
print(n)
print(inner.__closure__) # cell at 0x000002AD93BF76D8
inner()
return inner
wraaper(name)

'''
闭包作用:
  当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
  如果这个函数内部形成了闭包,
  那么它就不会随着函数的结束而消失。
'''

什么时候用到闭包?
例如:爬虫,装饰器等
下面是一个爬虫的小案例:

from urllib.request import urlopen
def index():
url = "http://www.xiaohua100.cn/index.html"
def get():
return urlopen(url).read()
return get xiaohua = index() # get
content = xiaohua() # get()
print(content.decode('utf-8'))

三、可迭代对象

可迭代的对象(数据类型)如下: 在python中,但凡带内置有__iter__()方法的数据类型(或者对象),都是可迭代的对象

1.列表类型

2.元组类型

3.集合类型

4.字典类型

5.文本类型(文本类型本身就是迭代器对象"具有__next__()"方法)

不可迭代的对象(数据类型)如下:

1.整数类型

2.浮点数类型

for i in 'abc':
print(i) for i in 123:
print(i) # 'int' object is not iterable,表示不是可迭代对象 # dir():返回一个列表,列表里面包含了传入的参数的属性、方法
dir('abc') # ['__add__', '__class__', '__contains__', '__iter__', __str__' ...]

判断一个对象是否是可迭代对象:

# 第一个方法
s1 = 'abc'
dic = {'name':'xiaoming'}
print('__iter__' in dir(s1))
print('__iter__' in dir(dic)) # 第二种方法
from collections import Iterable # 判断是否为可迭代对象
from collections import Iterator # 判断是否为迭代器 print(isinstance('xiaoming',Iterable)) # True
print(isinstance('xiaoming',Iterator)) # False print(isinstance('xiaoming',str)) # True
#isinstance() 应用比type()更广泛,isinstance()不仅可以判断你是不是可迭代对象,
#也可判断你是否迭代器,还可以判断你是什么类型的数据等等,而#type()只能判断你是什么数据类型

四、迭代器

1、对象内部含有__iter__方法且含有__next__方法就是迭代器

#文件句柄是迭代器:
f = open('register', encoding='utf-8')
print('__iter__' in dir(f)) #True
print('__next__' in dir(f)) #True #字典是可迭代对象,不是迭代器。
print('__iter__' in dir(dict)) #True
print('__next__' in dir(dict)) #False

2、可迭代对象与迭代器的区别:

  1. 可迭代对象的取值依赖索引
  2. 迭代器提供了一种不依赖索引取值的方式
  3. 迭代器非常节省内存
  4. 迭代器每次只会取一个值
  5. 迭代器单向的,一条路走到头
  6. 迭代器一定是可迭代对象,反之却不一定

3、可迭代对象如何转化成迭代器

可以使用函数 iter() 或者 __iter__() 获取相应的迭代器

lis = [1, 2, 3]  # 可迭代对象
ite1 = lis.__iter__() # 迭代器 <list_iterator object at 0x0000027A183BFFD0>
ite1 = iter(lis) # 迭代器 <list_iterator object at 0x0000027A183BFFD0>
print(ite1)

4、迭代器如何取值?

使用next() 或者 __next__() ,每使用一次next 取一个值

print(ite1.__next__())
print(ite1.__next__())
print(next(ite1))

5、while循环模拟for循环机制
1,将可迭代对象转化成迭代器。
2,调用__next__方法取值。
3,利用异常处理停止报错。

s1 = 'abcdefg'
iter1 = s1.__iter__()
while 1:
try:
print(iter1.__next__())
except StopIteration:
break

python之函数闭包、可迭代对象和迭代器的更多相关文章

  1. 11.Python初窥门径(函数名,可迭代对象,迭代器)

    Python(函数名,可迭代对象,迭代器) 一.默认参数的坑 # 比较特殊,正常来说临时空间执行结束后应该删除,但在这里不是. def func(a,l=[]): l.append(a) return ...

  2. python函数之可迭代对象、迭代器的判断

    怎么判断一个对象是可迭代对象还是迭代器 例子 from collections import Iterable, Iterator lst = ['Today is Wednesday', 'Tomo ...

  3. Python - 分支循环、可迭代对象与迭代器

  4. python 迭代器(一):迭代器基础(一) 语言内部使用 iter(...) 内置函数处理可迭代对象的方式

    简介 在 Python 中,所有集合都可以迭代.在 Python 语言内部,迭代器用于支持: 1.for 循环2.构建和扩展集合类型3.逐行遍历文本文件4.列表推导.字典推导和集合推导5.元组拆包6. ...

  5. python迭代-如何使用生成器函数实现可迭代对象

    如何使用生成器函数实现可迭代对象 问题举例: 实现一个可迭代对象的类,它能迭代出给定范围内 的所有素数: pn = PrimeNumbers(1, 30) for x in pn: print(x) ...

  6. Python可迭代对象、迭代器和生成器

    Python可迭代对象.迭代器和生成器 python 函数 表达式 序列 count utf-8 云栖征文 python可迭代对象 python迭代器 python生成器 摘要: 8.1 可迭代对象( ...

  7. Python之列表生成式、生成器、可迭代对象与迭代器

    本节内容 语法糖的概念 列表生成式 生成器(Generator) 可迭代对象(Iterable) 迭代器(Iterator) Iterable.Iterator与Generator之间的关系 一.语法 ...

  8. 完全理解Python迭代对象、迭代器、生成器

    在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...

  9. python可迭代对象和迭代器和生成器

    可迭代对象 刚开始我认为这两者是等同的,但后来发现并不是这样:下面直接抛出结论: )可迭代对象包含迭代器. )如果一个对象拥有__iter__方法,其是可迭代对象:如果一个对象拥有next方法,其是迭 ...

随机推荐

  1. java-Enumeration,单向队列Queue及双向队列Deque等容器简单使用

    1.Enumeration容器使用: package com.etc; import java.util.Enumeration; import java.util.Vector; /* Enumer ...

  2. Django---forms表单使用(1)

    使用过Django的同学应该都比较清楚,Django的表单功能是十分强大的,可以完成数据的校验等功能. 下面讲下常用的表单类型.我们讲下创建表单到前台可以正常显示的步骤: 一.创建表单类(可以直接在v ...

  3. 四大机器学习编程语言对比:R、Python、MATLAB、Octave

    本文作者是一位机器学习工程师,他比较了四种机器学习编程语言(工具):R.Python.MATLAB 和 OCTAVE.作者列出了这些语言(工具)的优缺点,希望对想开始学习它们的人有用. 图源:Pixa ...

  4. SVN系列操作(二)&svn不显示图标的解决方法

    接着上一篇文章,我们继续来操作一下SVN: 有同学反馈,我在本地上看到不SVN的图标,先解决一下这个问题. svn不显示图标的解决方法: 1.WIN+R,输入regedit,打开注册表 2.找到HKE ...

  5. 如何获取Debug Android Hash Key

    在接入FaceBook第三方登录的时候,需要获取Android Hash Key. Android Hash Key即密钥散列有两种,一种是开发秘钥散列,一种是发布秘钥散列.这里主要介绍如何获取开发秘 ...

  6. 自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral

    自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral Intro 新增加一个 Controller 的时候,经常忘记在 Controller 上增加 ApiVers ...

  7. Linux中逻辑卷的快照与还原

    有关逻辑卷的其他操作,请看: Linux中对逻辑卷的建立 Linux中对逻辑卷进行扩容与缩小 Linux中对逻辑卷的移除 LVM还有快照的功能,类似windows的系统还原点.其特点: 1.快照卷的容 ...

  8. spring基本知识

    什么是spring: spring就是以IOC反转控制和AOP面向切面编程为内核,使用基本的JavaBean来完成以前由EJB完成的工作. spring框架的优点: (1)方便耦合,简化开发:spri ...

  9. Python装饰器、内置函数之金兰契友

    装饰器:装饰器的实质就是一个闭包,而闭包又是嵌套函数的一种.所以也可以理解装饰器是一种特殊的函数.因为程序一般都遵守开放封闭原则,软件在设计初期不可能把所有情况都想到,所以一般软件都支持功能上的扩展, ...

  10. 局部敏感哈希(Locality-Sensitive Hashing, LSH)

    本文主要介绍一种用于海量高维数据的近似最近邻快速查找技术——局部敏感哈希(Locality-Sensitive Hashing, LSH),内容包括了LSH的原理.LSH哈希函数集.以及LSH的一些参 ...