python 闭包和迭代器

主要内容:

  • 1. 函数名的使用以及第?类对象
  • 2. 闭包
  • 3. 迭代器

1. 函数名的使用以及第?类对象

  函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量。

(1) 函数名的内存地址

def func():
    print("呵呵")
print(func)            #<function func at 0x000001EBCE5D6048>

(2)函数名可以赋值给其他变量

def func():
    print("呵呵")
print(func)
a = func      # 把函数当成?个变量赋值给另?个变量
a()           # 函数调?用 func()       #呵呵

(3)函数名可以当做容器类的元素

def func1():
    print("呵呵")
def func2():
    print("呵呵")
def func3():
    print("呵呵")
def func4():
    print("呵呵")
lst = [func1, func2, func3]
for i in lst:
    i()

(4)函数名可以当做函数的参数

def func():
    print("吃了了么")
def func2(fn):
    print("我是func2")
    fn()    # 执行传递过来的fn
    print("我是func2")
func2(func)     # 把函数func当成参数传递给func2的参数fn.

(5)函数名可以作为函数的返回值

def func_1():
    print("这里是函数1")
    def func_2():
            print("这里是函数2")
    print("这里是函数1")
    return func_2
fn = func_1()   # 执?函数1.  函数1返回的是函数2, 这时fn指向的就是上面函数2
fn()    # 执?上面返回的函数

(6) 一个设计模式

def panpan():
    print("我是潘潘. 我喜欢毒丈夫 ")
def xiaoping():
    print("我是小萍萍. 我喜欢毒丈夫 ")
def daguanren():
    print("大官人喜欢xxxx")
def wangpo(nv, nan): # 核心业务逻辑
    nv()
    nan()
wangpo(xiaohua, daguanren)             # 王婆代理了大官人和潘潘

(7)函数名既然是变量,变量名是任意的,在多次的赋值和调用过程中后续可能不知道初始的变量名,可以通过.__name__ 来得到初始的变量名

def chi():
    print("我是吃")
a = chi
haha = a
hehe = haha
bilibili= hehe
bilibili()
print(bilibili.__name__) # 函数名

(8)函数的注释

def play(wanjv1, wanjv2, wanjv3):
    ‘‘‘
        这是一个关于玩儿的函数
        :param wanjv1: 玩具1
        :param wanjv2: 玩具2
        :param wanjv3: 玩具3
        :return: 开心
    ‘‘‘
    print("我要玩儿荡秋千")
    return "开心"
# play("独木桥", "独轮车", "独眼龙")
print(play.__doc__) #  document   以文档的形式查看注释
print(str.join.__doc__)   #查看join里面是什么东西
#结果:
# 这是一个关于玩儿的函数
# :param
# wanjv1: 玩具1
# :param
# wanjv2: 玩具2
# :param
# wanjv3: 玩具3
# :return: 开心
#
# S.join(iterable) -> str

# Return a  string which is the  concatenation of the strings in the iterable.The separator between elements is S.

2. 闭包

  闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包

def func1():
    name = "alex"
    def func2():
        print(name)     # 闭包
    func2()
func1()       # alex

我们可以使用__closure__来检测函数是否是闭包. 使用函数名.__closure__返回cell就是闭包,返回None就不是闭包

def func1():
    name = "alex"
    def func2():
        print(name)     # 闭包
    func2()
    print(func2.__closure__)     #(<cell at 0x000001AF73627588: str object at 0x000001AF736B7378>,)
func1()       # alex

在函数外边调用内部函数

def outer():
    name = "alex"
    # 内部函数
    def inner():
        print(name)
    return inner
fn = outer()         # 访问外部函数, 获取到内部函数的函数地址
fn()                 # 访问内部函数

如果多层嵌套,只需要一层一层的往外层返回

def func1():
    def func2():
        def func3():
            print("嘿嘿")
        return func3
    return func2
func1()()()

闭包的好处: 

  • 当在外界访问内部函数时, 那这个时候内部函数访问的时间和时机就不?定了,因为在外部, 可以选择在任意的时间去访问内部函数.
  • 如果?个函数执行完毕, 则这个函数中的变量以及局部命名空间中的内容都将会被销毁. 在闭包中如果变量被销毁了, 那内部函数将不能正常执行.
  • python规定:如果你在内部函数中访问了外层函数中的变量,那么这个变量将不会消亡. 将会常驻在内存中,这样闭包可以保证外层函数中的变量在内存中常驻.

3. 迭代器

 str, list, tuple, dict, set. 那为什么我们可以称他们为可迭代对象呢, 因为他们都遵循了可迭代协议.

# 对的
s = "abc"
for c in s:
    print(c)

#  错的
for i in 123:
 print(i)结果:

Traceback (most recent call last):
 File "E:/Python_workspace/day 011/011整理.py", line 111, in <module>
  for i in 123:
TypeError: ‘int‘ object is not iterable

‘int‘ object is not iterable‘ 即如果整数类型对象是不可迭代的,iterable表示可迭代的,表示可迭代协议,我们可以通过dir函数来查看类中定义好的

    所有包含了__iter__的东西都可以使用for循环. 都可以进行迭代

s = "我的哈哈哈"
print(dir(s))       # 可以打印对象中的?方法和函数
print(dir(str))     # 也可以打印类中声明的?方法和函数
s = "alex"
print(dir(s)) # 在字符串中发现了__iter__. 没有__next__
a = 123
print(dir(a)) # 在int中没有__iter__ 没有__next__
lst = [1, 2, 3,]
print(dir(lst)) # 在list中也有__iter__

  (1)调用了__iter__(), 访问__iter__()可以得到迭代器

lst = [1, 2, 3, 4, 5, 6]
it = lst.__iter__()  # iterator 迭代器
while 1:
    try:
        print(it.__next__())
    except StopIteration:
        print("结束了")
        break
for el in lst:
    print(el)
else:
    print("结束了")

(2) 迭代器给所有的数据类型提供了一种统一的遍历的方式(可迭代协议), Iterable, __iter__()

lst = [1, 2, 3, 4, 5]
print("__iter__" in dir(lst))    #True
print("__next__" in dir(lst))    #False
lst = [1, 2, 3, 4, 5]
it = lst.__iter__()
print("__iter__" in dir(it)) #  迭代器里面是有__iter__的.  迭代器一定是可迭代的     #True
print("__next__" in dir(it))                                                     #True
#
for el in it: # 迭代器可以使用for循环
    print(el)

 Iterable: 可迭代对象. 内部包含__iter__()函数       

 Iterator: 迭代器. 内部包含__iter__() 同时包含__next__(). 

from collections import Iterable # 可迭代的
from collections import Iterator # 迭代器
#
lst = ["周润发","麻花藤","刘伟"]
print(isinstance(lst, Iterable)) # instance  实例, 对象    #True
print(isinstance(lst, Iterator)) # instance  实例, 对象    #False
#
it = lst.__iter__()
print(isinstance(it, Iterable)) # instance  实例, 对象      #True
print(isinstance(it, Iterator)) # instance  实例, 对象       #True

 迭代器的特点:             

  • 1. 节省内存.           
  • 2. 惰性机制           
  • 3. 不能反复, 只能向下执行

原文地址:https://www.cnblogs.com/avit/p/10209814.html

时间: 2024-07-31 18:51:02

python 闭包和迭代器的相关文章

关于函数的默认值与python闭包以及迭代器

# 在函数中如果默认值参数是一个可变的数据类型, 如果有人调用的时候改变了他. 其他位置看到的也跟着改变了 def fn(val,list=[]): list.append(val) return list print(fn(5)) # 这个位置我们给val传值了打印的结果一定是[5] print(fn(6)) # 这个位置我们继续传值发现结果是[5, 6],那么也就是说函数中参数的默认值是同一个,而不是每次调用函数生产新的默认值 # # 在函数中如果默认值参数是一个可变的数据类型, 如果有人调

闭包,迭代器,生成器,列表推导式

1:函数名的应用   1, 函数名就是函数的内存地址.    2, 函数名可以作为变量.    3, 函数名可以作为函数的参数.    4, 函数名可以作为容器类类型的元素.    5,函数名可以当做函数的返回值. 2:globals() locals() globals() # 返回全局变量的一个字典. locals()  返回 当前位置 的局部变量的字典. 1 name = 'leiwenxuan' 2 def fun(): 3 a = 2 4 b = 3 5 6 print(globals

Python - 三大器 迭代器,生层器,装饰器

目录 Python - 三大器 迭代器,生层器,装饰器 一. 容器 二. 可迭代对象(iterable) 三. 迭代器 四. 生成器 五. 装饰器 1. 定义 六. 闭包 Python - 三大器 迭代器,生层器,装饰器 在介绍三大器之前先来了解一下容器和可迭代对象... 一. 容器 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存

python基础之迭代器协议和生成器

一 递归和迭代 略 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象. 三 python中强大的for循环机制 for循环的本

Python闭包与函数对象

1. Python闭包是什么 在python中有函数闭包的概念,这个概念是什么意思呢,查看Wikipedia的说明如下: “ In programming languages, closures (also lexical closures or function closures) are a technique for implementing lexically scoped name binding in languages with first-class functions. Ope

python函数:迭代器和生成器

python函数:迭代器和生成器 迭代器和生成器是函数中的一大重点,务必掌握,何为迭代?何为迭代器? 预习: 处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕(使用生成器) 一.迭代器 for i in 50:     print(i) #运行结果: # Traceback (most recent call last): #   File "G:/python/python代码/八月/day2 迭代器生成器/3迭代器.py", line 8, in &

python闭包和装饰器(转)

一.python闭包 1.内嵌函数 >>> def func1(): ... print ('func1 running...') ... def func2(): ... print ('func2 running...') ... func2() ... >>> func1() func1 running... func2 running... 内部函数func2作用域都在外部函数func1作用域之内 如果试图在外部函数的外部调用内部函数将会报错 >>&

Python闭包的学习

Python闭包的学习 什么是闭包? 借用维基上解释:在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外.所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体.闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例. 好吧,看了这段定义的确不是还不能立即理解闭包到底是什么.不过,闭包并不是很难理解,往下看几个小例子就能明

Python之路——迭代器与生成器

一.迭代器 1 # -*- encoding:utf-8 -*- 2 3 4 # dir([1,2].__iter__())是列表迭代器中实现的所有方法,dir([1,2])是列表中实现的所有方法 5 # print(dir([1,2].__iter__())) 6 # print(dir([1,2])) 7 # print(set(dir([1,2].__iter__()))-set(dir([1,2]))) # {'__length_hint__', '__setstate__', '__n