python学习(函数名,闭包和迭代器)

一. 函数名的运用.

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

  1. 函数名的内存地址

def func():    
    print("呵呵") 
print(func)
 
#结果: <function func at 0x1101e4ea0>

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

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

#结果:
#<function func at 0x000002BECECA1F28>
#呵呵

  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("我是func")
func2(func)     # 把函数func当成参数传递给func2的参数fn.

#结果:
#    我是func2
#    吃了么
#    我是func

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

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

#结果:
#    这里是函数1
#    这里是函数3
#    这里是函数2

二. 闭包

  1. 什么是闭包?

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

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

    可以使用__closure__来检测函数是否是闭包. 如果有返回值就是闭包,如果返回None就不是闭包.

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

  2. 闭包的好处

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

三 . 迭代器

  可迭代对象: str, list, tuple, set, f, dict

  所有的额以上数据类型中都含有一个函数__iter__(),所有保留__iter__()的数据类型都是可以迭代的数据类型.  Iterable

  这是查看⼀个对象是否是可迭代对象的第⼀种办法. 我们还可以通过isinstence()函数来查 看⼀个对象是什么类型的 

  dir()来查看一个对象,数据类型中包含了哪些东西

lst = [1,2,3]   # list
print(dir(lst))

#结果:
#['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']


lst = [1,2,3]   # list
s = "王xx"
print("__iter__" in dir(s))         #判断__iter__函数是否在某一个数据类型中   
print("__iter__" in dir(lst))    
print("__iter__" in dir(123))

#结果:
#    True
#    True
#    False   


lst = [1, 2, 3]
it = lst.__iter__()
print(isinstance(it, Iterable)) # 判断是否是可迭代的 迭代器一定是可迭代的
print(isinstance(it, Iterator)) # 判断是否为迭代器, 迭代器里面一定有__next__(), __iter__()

print("__iter__" in dir(lst))   # 确定是一个可迭代的
print("__next__" in dir(lst))   # 确定不是一个迭代器,因为__next__函数不在lst内

#结果:
#    True
#    True
#    True
#    False

  如果对象中有__iter__函数. 那么我们认为这个对象遵守了可迭代协议. 就可以获取到相应的迭代器. 这里的__iter__是帮助我们获取到对象的迭代器. 我们使⽤迭代器中的__next__()来获取到⼀个迭代器中的元素.

  迭代器特点:

    1. 节省内存

    2. 惰性机制

    3. 只能一直向前直行,不能反复

    

猜你喜欢

转载自www.cnblogs.com/dong-/p/9326039.html