zoukankan      html  css  js  c++  java
  • python3 函数 二

     

    1、函数嵌套

    1、1函数嵌套定义 :在一个函数的内部,又定义另外一个函数。

    def f1():
        x=1
        def f2():
            print('from f2')
        f2()
    f1()

    1、2函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数。

    def bar():   

        print('from bar')

    def foo():
        print('from foo')
        bar()
    foo()

     通过函数的嵌套使用,分解成操作减少重复代码,一次调用。

    2、名称空间与作用域

    名称空间

    2、1 名称空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方

    2、2内置名称空间:python自带的名字,在python解释器启动时产生,存放一些python内置的名字

    2、3全局名称空间:在执行文件时,存放文件级别定义的名字,Python中顶行写的。

    2、4局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的名称空间,用来存放该函数内定义的名字,该名字在函数调用时生效,调用结束后失效

    2、5加载顺序:内置名称空间------>全局名称空间----->局部名称空间

    2、6名字的查找顺序:局部名称空间------>全局名称空间----->内置名称空间

    作用域,作用的范围

    全局作用域:全局存活,全局有效
    局部作用域:局部存活,局部有效

    定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

    局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。

    def f1():

        x = 1

        y = 2

        print(locals())

        print(globals())

    f1()

    print(locals())

    print(globals())

    print(locals() is globals())

    修改全局变量的值

    x=1

    def f1():

        global x

        x=2

    f1()

    print(x)

    修改局部变量的值

    x = 0
    def f1():
        x = 1
        def f2():
            x = 2
            def f3():
                nonlocal x  #改的是函数正上方的值
                x = 3
            f3()
        f2()
    f1()

    优先掌握:作用域关系,在函数定义时就已经固定 ,于调用位置无关,在调用函数时,必须回到函数原来定义的位置去找作用域关系.

    x = 1

    def f1():

        def f2():

            print(x)

        return f2 x = 1

    def f1():

        def f2():

            print(x)

        return f2

    func = f1()

    func()

    func = f1()

    func()

    查看作用域:globals(),locals()

    global

    nonlocal

    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__

    locals 是函数内的名字空间,包括局部变量和形参

    enclosing 外部嵌套函数的名字空间(闭包中常见)

    globals 全局变量,函数定义所在模块的名字空间

    builtins 内置模块的名字空间

    3、闭包函数

    3、1 闭包函数: 定义在函数内部的函数

    3、2包含对外部作用域名字的引用,而不是对全局作用域名字的引用,那么该内部函数就称为闭包函数

    import requests

    def deco(url):

        def wrapper():

            return (requests.get(url).text)

        return wrapper

    get = deco('https://www.baidu.com')

    print(get())

    闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

    4、装饰器

    开放封闭原则:对拓展是开放的,对修改是封闭的

    装饰器:装饰他人的工具,装饰的目的是为他人添加新功能

    装饰器本身是任意可调用对象,被装饰的对象本身也可以是任意可调用的对象

    装饰器遵循的原则:1、不修改被装饰对象的源代码

             2、不修改被调用对象的调用方式

    装饰器的目的:在遵循1和2原则的前提下,为其他函数添加新功能

    @装饰器名:必须写在被装饰对象的正上方,且是单独一行

    示例:

    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 res

                return wrapper

            @timmer

            def foo():

                time.sleep(3)

                print('from foo')

            foo()

    装饰器语法:

            被装饰函数的正上方,单独一行

            @deco1

            @deco2

            @deco3

            def foo():

                pass

            foo=deco1(deco2(deco3(foo)))

    装饰器补充:wraps

    from functools import wraps

    def deco(func):

        @wraps(func) #加在最内层函数正上方

        def wrapper(*args,**kwargs):

            return func(*args,**kwargs)

        return wrapper

    @deco

    def index():

        '''去你妹的'''

        print('from index')

    print(index.__doc__)

    5、迭代器

    迭代器:是一个重复的过程,每一次重复,都是基于上一次的结果而来。

     s='hello'

    l=['a','b','c','d']

    t=('a','b','c','d')

    dic={'name':'egon','sex':'m',"age":18}

    set1={1,2,3}

    f=open('db.txt')

    迭代器对象本身也是可迭代对象

    l=['a','b','c','d']

    dic={'name':'egon','sex':'m',"age":18}

    iter_l=iter(l)

    iter_dic=iter(dic)

    while True:

         try:

             k=next(iter_dic)

             print(k,dic[k])

         except StopIteration:

             break

    可迭代对象:

    1 有__iter__,执行得到仍然是迭代本身

    2 有__next__

    迭代器对象的优点

    1、提供了一种统一的(不依赖于索引的)迭代方式

    2、迭代器本身,比起其他数据类型更省内存

    迭代器对象的缺点

    1、一次性,只能往后走,不能回退,不如索引取值灵活

    2、无法预知什么时候取值结束,即无法预知长度

    判断可迭代对象与迭代器对象

    print(isinstance(s,Iterable))    判断s数据类型是否是可迭代对象

    print(isinstance(s,Iterator))    只有文件是迭代器对象

    6、生成器

    生成器:

    在函数内部包含yield关键字,那么该函数执行的结果就是生成器(生成器就是迭代器)

     def func():

         print('first')

         yield 11111111

         print('second')

         yield 2222222

         print('third')

        yield 33333333

        print('fourth')

     g=func()

     print(g)

     from collections import Iterator

     print(isinstance(g,Iterator))

    yield的功能:

    1 把函数的结果做生迭代器(以一种优雅的方式封装好__iter__,__next__)

    2 函数暂停与再继续运行的状态是由yield,保存当前运行状态。

    def func(n):

            while True:

            yield n

            n+=1

    g=func(0)

    print(next(g))

    def my_range(start,stop):

        while True:

            if start == stop:

                raise StopIteration

            else:

    yield start

            start+=1

    g=my_range(1,3)

    for i in my_range(1,3):

    print(i)

    yield与return的比较?

    相同:都有返回值的功能

    不同:return只能返回一次值,而yield可以返回多次值

    import time

    def tail(filepath):

        with open(filepath, 'r') as f:

            f.seek(0, 2)

            while True:

                line = f.readline()

                if line:

                    yield line

                else:

                    time.sleep(0.2)

     def grep(pattern,lines):

        for line in lines:

            if pattern in line:

                print(line,end='')

    grep('error',tail('access.log'))

    7、三元表达式,列表推导式,生成器表达式

    三元表达式

    x=10

    res=x if x > 3 else 'no'

    print(res)

    列表解析

    l = ['egg%s'%i for i in range(10)]

    l=['egg%s' %i for i in range(10)  if i >=5]

    print(l)

    names = ['alex_sb','egon','wupeiqi_sb','yuanhao_sb']

    names_new = [name for name in names if name.endswith('sb')]

    print(names_new)

    生成器表达式

    g = ('egg%s'%i for i in range(10))  # 将中括号变成小括号即为生成器表达式

    # 迭代器同一时间在内存中只有一个值

    print(g)

    print(next(g))

    print(next(g))

    with open('a.txt',encoding='utf-8') as f:

         g=(len(line) for line in f)

         print(max(g))

  • 相关阅读:
    JavaScript的语法、数据类型、基本算数和逻辑运算操作
    ES6之常用开发知识点:入门(一)
    ES6中map数据结构
    VUE路径问题

    JS简易计算器的实现,以及代码的优化
    格雷编码
    H5网页布局+css代码美化
    jQuery---五角星评分案例
    Ajax工作原理及优缺点
  • 原文地址:https://www.cnblogs.com/qiangyuge/p/7247281.html
Copyright © 2011-2022 走看看