zoukankan      html  css  js  c++  java
  • day4 函数对象 函数嵌套 名称空间与作用域 闭包函数 装饰器 迭代器 生成器 内置函数

    一、函数对象

    1 可以被引用
    2 可以当作参数传递
    3 返回值可以是函数
    3 可以当作容器类型的元素

    def foo():
        print('from foo')
    
    func=foo
    
    print(foo)
    print(func)
    func()
    
    输出结果如下:
    
    <function foo at 0x00000000026220D0>
    <function foo at 0x00000000026220D0>
    from foo
    

      

    二、函数嵌套

    python允许在定义函数的时候,其函数体内又包含另外一个函数的完整定义,这就是我们通常所说的嵌套定义。为什么?因为函数是用def语句定义的,凡是其他语句可以出现的地方,def语句同样可以出现。
    像这样定义在其他函数内的函数叫做内部函数,内部函数所在的函数叫做外部函数。当然,我们可以多层嵌套,这样的话,除了最外层和最内层的函数之外,其它函数既是外部函数又是内部函数。#函数的嵌套定义

    def f1():
    
        def f2():
            print('from f2')
            def f3():
                print('from f3')
            f3()
        f2()
    
    
    f1()
    输出结果如下:

    from f2
    from f3


    三、名称空间与作用域

    三种名称空间:

    内置名称空间:随着python解释器的启动而产生。
    print(sum)
    print(max)
    print(min)
    
    输出结果如下:
    <built-in function sum>
    <built-in function max>
    <built-in function min>
    
    dir()函数接受模块名作为参数,返回一个排好序的字符串列表,内容是一个模块里定义过的名字。便获得了内建模块里定义的名字:
    import builtins
    for i in dir(builtins): 
        print(i)
    输出结果:
    ArithmeticError
    AssertionError
    AttributeError
    BaseException
    BlockingIOError
    BrokenPipeError
    BufferError
    BytesWarning
    ChildProcessError
    ConnectionAbortedError
    ConnectionError
    ConnectionRefusedError
    ConnectionResetError
    DeprecationWarning
    EOFError
    Ellipsis
    EnvironmentError
    Exception
    False
    FileExistsError
    FileNotFoundError
    FloatingPointError
    FutureWarning
    GeneratorExit
    IOError
    ImportError
    ImportWarning
    IndentationError
    IndexError
    InterruptedError
    IsADirectoryError
    KeyError
    KeyboardInterrupt
    LookupError
    MemoryError
    ModuleNotFoundError
    NameError
    None
    NotADirectoryError
    NotImplemented
    NotImplementedError
    OSError
    OverflowError
    PendingDeprecationWarning
    PermissionError
    ProcessLookupError
    RecursionError
    ReferenceError
    ResourceWarning
    RuntimeError
    RuntimeWarning
    StopAsyncIteration
    StopIteration
    SyntaxError
    SyntaxWarning
    SystemError
    SystemExit
    TabError
    TimeoutError
    True
    TypeError
    UnboundLocalError
    UnicodeDecodeError
    UnicodeEncodeError
    UnicodeError
    UnicodeTranslateError
    UnicodeWarning
    UserWarning
    ValueError
    Warning
    WindowsError
    ZeroDivisionError
    __build_class__
    __debug__
    __doc__
    __import__
    __loader__
    __name__
    __package__
    __spec__
    abs
    all
    any
    ascii
    bin
    bool
    bytearray
    bytes
    callable
    chr
    classmethod
    compile
    complex
    copyright
    credits
    delattr
    dict
    dir
    divmod
    enumerate
    eval
    exec
    exit
    filter
    float
    format
    frozenset
    getattr
    globals
    hasattr
    hash
    help
    hex
    id
    input
    int
    isinstance
    issubclass
    iter
    len
    license
    list
    locals
    map
    max
    memoryview
    min
    next
    object
    oct
    open
    ord
    pow
    print
    property
    quit
    range
    repr
    reversed
    round
    set
    setattr
    slice
    sorted
    staticmethod
    str
    sum
    super
    tuple
    type
    vars
    zip
    

    全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入该空间

    x=1
    
    def func():
        money=2000
        x=2
        print('func')
    print(x)
    print(func)
    func()
    print(money)
    输出结果如下:
    1
    <function func at 0x0000000002493E18>
    func
    Traceback (most recent call last):
      File "D:/py17/day4/名称空间与作用域.py", line 59, in <module>
        print(money)
    NameError: name 'money' is not defined
    
    作用域:
    1. 全局作用域:内置名称空间,全局名层空间
    2. 局部作用:局部名称空间
    名字的查找顺序:局部名称空间---》全局名层空间---》内置名称空间
    x=1
    def func():
        x=2
        print(x)
        sum=123123
        print(sum)
    func()
    输出结果:
    2
    123123
    
    查看全局作用域内的名字:gloabls()
    查看局局作用域内的名字:locals()
    x=1000
    def func(y):
        x=2
        print(locals())
        print(globals())
    
    func(1)
    输出结果:
    {'x': 2, 'y': 1}
    {'__name__': '__main__', '__doc__': '
    作用域:
        1. 全局作用域:内置名称空间,全局名层空间
        2. 局部作用:局部名称空间
    ', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000002566828>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/py17/day4/名称空间与作用域.py', '__cached__': None, 'x': 1000, 'func': <function func at 0x0000000002153E18>}
    
    全局作用域:全局有效,在任何位置都能被访问到,除非del删掉,否则会一直存活到文件执行完毕

    局部作用域的名字:局部有效,只能在局部范围调用,只在函数调用时才有效,调用结束就失效
    x=1
    
    def f1():
        print(x)
    
    def foo():
        print(x)
    
    def f(x):
        # x=4
        def f2():
            # x=3
            def f3():
                # x=2
                print(x)
    
            f3()
        f2()
    
    f(4)
    输出结果:
    4  

    四、闭包函数

    1. 定义在内部函数
    2. 包含对外部作用域而非全局作用域的引用,
    3.该内部函数就成为闭包函数

    
    
    def f1():
        x = 1
        def f2():
            print(x)
    
        return f2
    闭包应用:惰性计算
    from urllib.request import urlopen
    
    def index(url):
        def get():
            return urlopen(url).read()
    
        return get
    
    oldboy=index('http://crm.oldboyedu.com')
    
    print(oldboy().decode('utf-8'))
    print(oldboy.__closure__[0].cell_contents)
    
    
    res=urlopen('http://crm.oldboyedu.com').read()
    
    print(res.decode('utf-8'))

    五、装饰器

    定义:本质是函数,(装饰其他函数),就是为其他函数添加附加功能。

    原则:1. 不能修改被装饰的函数的源代码。

             2. 不能修改被装饰的函数的调用方式。

    实现装饰器知识储备:

    1. 函数即'变量'

    2.高阶函数

    a. 把一个函数名当做实参传递给另外一个函数(在不修改被装饰函数的源代码的情况下为其添加功能)

    b. 返回值中包含函数名

    3. 嵌套函数

    高阶函数 + 嵌套函数 =》 装饰器

    import time
    
    def timmer(func):
        def wrapper(*args,**kwargs):
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time=time.time()
            print('run time is %s' %(stop_time-start_time))
        return wrapper
    
    @timmer
    def index():
    
        time.sleep(3)
        print('welcome to index')
    
    index()
    
    输出结果:
    welcome to index
    run time is 3.000171422958374 

    六、迭代器

     迭代的概念:  重复+上一次迭代的结果为下一次迭代的初始值。

           重复的过程称为迭代,每次重复即一次迭代,
          并且每次迭代的结果是下一次迭代的初始值。
    while True: #只满足重复,因而不是迭代
        print('====>')
    
    
    #下面才为迭代
    l = [1, 2, 3]
    count = 0
    while count < len(l):  # 只满足重复,因而不是迭代
        print('====>', l[count])
        count += 1
    
    l = (1, 2, 3)
    count = 0
    while count < len(l):  # 只满足重复,因而不是迭代
        print('====>', l[count])
        count += 1
    
    s='hello'
    count = 0
    while count < len(s):
        print('====>', s[count])
        count += 1
    

    为什么要有迭代器?对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式。

    可迭代的对象:内置__iter__方法的,都是可迭代的对象。

    # [1,2].__iter__()
    # 'hello'.__iter__()
    # (1,2).__iter__()
    #
    # {'a':1,'b':2}.__iter__()
    # {1,2,3}.__iter__()
    

    迭代器:执行__iter__方法,得到的结果就是迭代器,迭代器对象有__next__方法。

    i=[1,2,3].__iter__()
    
    print(i)
    #
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())
    print(i.__next__()) #抛出异常:StopIteration
    
    输出结果:
    <list_iterator object at 0x000000000261AFD0>
    1
    2
    3
    Traceback (most recent call last):
      File "D:/py17/day4/迭代器.py", line 57, in <module>
        print(i.__next__()) #抛出异常:StopIteration
    StopIteration
    i={'a':1,'b':2,'c':3}.__iter__()
    --------------------------------------------------
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())
    输出结果:

    Traceback (most recent call last):
    File "D:/py17/day4/迭代器.py", line 65, in <module>
    print(i.__next__())
    StopIteration
    a
    b
    c

    -----------------------------------------------------------------------

    dic={'a':1,'b':2,'c':3}
    i=dic.__iter__()
    while True:
    try:
    key=i.__next__()
    print(dic[key])
    except StopIteration:
    break
    输出结果:

    1
    2
    3

    ------------------------------------------------------------------------

    s={'a',3,2,4}

    s.__iter__() #iter(s)

    i=iter(s)
    print(next(i))
    print(next(i))
    print(next(i))
    print(next(i))
    #print(next(i))
    输出结果:

    2
    a
    3
    4

    --------------------------------------------------
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())
    输出结果:
    Traceback (most recent call last):
    File "D:/py17/day4/迭代器.py", line 65, in <module>
    print(i.__next__())
    StopIteration
    a
    b
    c
    
    -----------------------------------------------------------------------
    
    dic={'a':1,'b':2,'c':3}
    i=dic.__iter__()
    while True:
        try:
            key=i.__next__()
            print(dic[key])
        except StopIteration:
            break
    输出结果:
    1
    2
    3
    
    ------------------------------------------------------------------------
    
    s={'a',3,2,4}
    
    s.__iter__() #iter(s)
    
    i=iter(s)
    print(next(i))
    print(next(i))
    print(next(i))
    print(next(i))
    #print(next(i))
    输出结果:
    2
    a
    3
    4
    

      

    判断是不是可以迭代,用Iterable

    判断是不是迭代器,用Iterator 

    在Python中可以使用type()与isinstance()这两个函数判断对象类型,而isinstance()函数的使用上比type更加方便。

    from collections import Iterable,Iterator
    
    'abc'.__iter__()
    ().__iter__()
    [].__iter__()
    {'a':1}.__iter__()
    {1,2}.__iter__()
    
    f=open('a.txt','w')
    f.__iter__()
    
    
    #下列数据类型都是可迭代的对象
    print(isinstance('abc',Iterable))
    print(isinstance([],Iterable))
    print(isinstance((),Iterable))
    print(isinstance({'a':1},Iterable))
    print(isinstance({1,2},Iterable))
    print(isinstance(f,Iterable))
    输出结果:

    True
    True
    True
    True
    True
    True

    ----------------------------------------------------------------------------------

    #只有文件是迭代器对象
    print(isinstance('abc',Iterator))
    print(isinstance([],Iterator))
    print(isinstance((),Iterator))
    print(isinstance({'a':1},Iterator))
    print(isinstance({1,2},Iterator))
    print(isinstance(f,Iterator))
    输出结果:

    False
    False
    False
    False
    False
    True

    生成器   

    生成器函数:只要函数体包含yield关键字,该函数就是生成器函数生成器就是迭代器。

    生成器就是迭代器

    def foo():
        print('first')
        yield 1
        print('second')
        yield 2
        print('third')
        yield 3
        print('fourth')
        yield 4
        print('fifth')
        yield 5
    g=foo()
    
    print(next(g)) #触发迭代器g的执行,进而触发函数的执行
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    

      

    yield的功能:
    1.相当于为函数封装好__iter__和__next__
    2.return只能返回一次值,函数就终止了,
    而yield能返回多次值,每次返回都会将函数暂停,下一次next会从
    上一次暂停的位置继续执行。

    内置函数

    内置参数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii                                                                                                                      

  • 相关阅读:
    http与websocket(基于SignalR)两种协议下的跨域基于ASP.NET MVC--竹子整理
    让Visual Studio 2015 支持ASP.NET MVC4.0.0.1
    自定义滚动条CSS样式
    使用NuGet发布自己的类库包(Library Package)
    基于EF的数据外键关联查询
    基于EF创建数据库迁移
    用SQL命令查看Mysql数据库大小
    Python之MySQL数据操作
    Python之MySQL基础
    Python网络编程之黏包问题
  • 原文地址:https://www.cnblogs.com/menglingqian/p/6295944.html
Copyright © 2011-2022 走看看