zoukankan      html  css  js  c++  java
  • python全栈 函数名 闭包及迭代器

    1,函数名的运用

    2.闭包

    3.迭代器

    一.函数名的运用

    1.函数名的命名规范和变量是一样的

     函数名其实就是变量名

    (1)函数名的内存地址

    例:

    def func():
        print("alex")
    print(func)
     #<function func at 0x0000000002033E18>

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

    例:

    def func():
     print("呵呵")
    print(func)
    a = func              # 把函数当成一个变量赋值给另一个变量
    a() 
     # 函数调用 func()
    函数名可以作为参数传递给函数
    def my():
        print("我是my")
    def proxy(fn):        # 代理模式. 装饰器
        print("在处理之前")
        fn()
        print("在处理之后")
    proxy(my)    #把函数名作为参数传递给另一个函数

    a = 10   b =a(赋值操作)    print(b)

    (3)函数名可以作为列表的元素进行存储.

    例:

    def func1():
            pass
    def func2():
            pass
    lst = [func1, func2]
    for el in lst:
    el()

    (4)函数名可以作为参数传递给函数.

    例:

     def func(): pass def proxy(fn): fn() proxy(func) 

    def func1():
        print("我是func1")
    def func2():
        print("我是func2")
    def func(fn, gn): # 函数名可以作为参数进行传递
        print("我是func")
        fn()
        gn()
        print("哈哈哈")
    func(func1, func2)

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

    例:

     def func(): def inner(): pass return inner func()() 

    def func():
        print("我是func")
        a = 10 # 变量
        def inner():
            print("我是inner")
        return inner
    # ret = func()    #(最后一行的转化过程源头)
    # ret()              #(最后一行的转化过程源头)
    func()() # 先运行func()  然后在返回值上加()
    def func_1():
         print("这里是函数1")
         def func_2():
             print("这里是函数2")
         print("这里是函数1")
         return func_2
    fn = func_1() # 执行函数1. 函数1返回的是函数2, 这时fn指向的就是上面函数2
    fn() # 执行上面返回的函数        

    二.闭包

    闭包:内层函数, 对外层函数(非全局)的局部变量的引用

    写法:

    def outer():
                    a = 10
                    def inner():
                        print(a)
                    return inner

    例:

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

    闭包的作用;

    (1) 保护你的变量不受侵害.

    例:

    a = 10            # 不安全的
    def outer():
        global a       #如果没有global 就无法引用外部变量,保证内部变量不外泄.不被侵犯
        a = 20
    def outer_2():
        global a
        a = 30
    outer_2()
    outer()
    print(a)

    (2)可以让一个变量常住内存.供后面的程序使用.

    例:

    def outer():
        a = 10            # 常驻内存,  为了inner执行的时候有值.
        def inner():
            print(a)        #
            return inner
    fn = outer()
    print("fdsafasd")
    print("fdsafasd")
    print("fdsafasd")
    fn()                    # 调用的时机是不定的.

    简易爬虫实例  涛哥珍藏校花美女大全

    例:

    # 超简易爬虫
    from urllib.request import urlopen
    def outer():
        # 常驻内存
        s = urlopen("http://www.xiaohua100.cn/index.html").read()
        def getContent(): # 闭包
            return s
        return getContent
    print("爬取内容.....")
    pa = outer()
    ret = pa()
    print(ret)
    # (过段时间)
    ret = pa()
    print(ret)
    # (又过一段时间调用)
    ret = pa()
    print(ret)
    # (又又过一段时间调用)
    ret = pa()
    print(ret)
    # ...............(此处省去 N + 1 次)

    (3)如何查看是否闭包.

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

    例:

    def func1():
         name = "alex"
         def func2():
             print(name)               # 闭包
         func2()
         print(func2.__closure__) 
    func1()
    
    # (<cell at 0x10c2e20a8: str object at
    0x10c3fc650>,)
     
    def func():
        a = 10
        def inner():
            print(a)
        print(inner.__closure__) # 如果打印的是None. 不是闭包. 如果不是None, 就是闭包
    func()
    
    
    #(<cell at 0x00000000026465B8: int object at 0x000000005286B560>,)

    三.迭代器.

    使用dir来查看该数据包含了那些方法

    用来遍历列表,字符串,元祖....可迭代对象

    可迭代对象: Iterable, 里面有__iter__()可以获取迭代器, 没有__next__()

    迭代器: Iterator, 里面有__iter__()可以获取迭代器, 还有__next__()

     数据必须是可迭代的

    例:

    # 对的
    s = "abc"
    for c in s:
         print(c)
    
    
    
    # 错的
    for i in 123:
         print(i)
        结果:
     Traceback (most recent call last):
         File "/Users/sylar/PycharmProjects/oldboy/iterator.py", line 8, in
     <module>
             for i in 123:
        TypeError: 'int' object is not iterable

    迭代数据类型和迭代器

    (1)可迭代对象可以使用__iter__()来获取到迭代器

    (2)迭代器里面有__next__()

    例:

    s = '123'
    for i in s:
        print(i)
    print(dir(str)) #  dir查看xx类型的数据可以执行哪些方法, __iter__  iterable
    print(dir(list)) # __iter__
    print(dir(int)) # 没有__iter__
    # 所有的带__iter__可以使用for循环的, 可迭代对象
    
    
    
    结果:
    1
    2
    3
    ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
    ['__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']
    ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

    查看一个对象是否是可迭代对象的方法:

    (偏方)

    print("__iter__" in dir(it))
    print("__next__" in dir(it))
    可以通过dir来判断数据是否是可迭代的, 以及数据是否是迭代器

    (官方方法)

     from collections import Iterable # 可迭代对象    from collections import Iterator # 迭代器 

    迭代器的特点:

    1. 只能向前.

    2. 几乎不占用内存, 节省内存(需要明天生成器)

    3. for循环

    4. 惰性机制 (面试题,难度系数比较高)

    例:

    s = "石可心喜欢赵一宁"
    it = s.__iter__() # 获取迭代器
    print(dir(it)) # 迭代器里有__iter__ 还有__next__
    
    
    print(it.__next__()) #
    print(it.__next__())    #
    print(it.__next__())#
    print(it.__next__())#
    print(it.__next__())#
    print(it.__next__())#
    print(it.__next__())#
    print(it.__next__())#

    重点: 迭代器模拟for循环(使用while循环+迭代器来模拟for循环(必须要掌握))

    for循环的内部机制.

      1. 首先获取到迭代器.

      2. 使用while循环获取数据

      3. it.__next__()来获取数据

      4. 处理异常 try:xxx          except StopIteration:

    写法:

    it = lst.__iter__() # 获取迭代器
    while 1:
        try:    # 尝试执行
            el = it.__next__()  # 获取下一个元素
            print(el)
        except StopIteration:   # 处理错误
            break
    
    
    #####  (   重    点   )   #####
  • 相关阅读:
    BZOJ-3940:Censoring(AC自动机裸题)
    BZOJ-3881:Divljak (AC自动机+DFS序+树链求并+树状数组)
    CodeForces
    CodeForces 547E:Mike and Friends(AC自动机+DFS序+主席树)
    CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
    CodeForces
    CodeForces
    BZOJ2726:任务安排(DP+斜率优化+二分)
    bzoj 2049: [Sdoi2008]Cave 洞穴勘测
    [SDOI2009]Bill的挑战
  • 原文地址:https://www.cnblogs.com/qq1426794755/p/9457572.html
Copyright © 2011-2022 走看看