Python函数进阶

Python函数进阶


函数的参数类型

  • 不可变参数: 整数、字符串、元组
  • 可变参数: 列表,字典
  1. 传递不可变类型参数,不会影响参数本身
  2. 传递可变类型参数,会影响参数本身

命名空间

  • 命名空间:指的是保存程序中的变量名和值的地方

    • 局部命名空间:每个函数都有自己的命名空间,叫做局部空间,它记录了函数的变量,包括函数的参数和局部定义的变量

    • 全局命名空间:每个模块拥有它自已的命名空间,叫做全局命名空间,它记录了模块的变量,包括函数、类、其它导入的模块。

    • 内置命名空间:任何模块均可访问它,它存放着内置的函数和异常

    • 局部名称空间使用 locals() 函数来访问

    • 全局命名空间的访问使用 globals()函数访问

  • 命名空间加载顺序:内置-->全局-->局部

  • 命名空间查找顺序:局部-->全局-->内置

作用域

  • 作用域:指的是变量在程序中的可应用范围
    • Local:(函数内部)局部作用域
    • Enclosing:(嵌套函数的外层函数内部)嵌套作用域(闭包)
    • Global:(模块全局)全局作用域
    • Built-in:(内建)内建作用域

全局变量和局部变量

  • 全局变量是不可变数据类型,函数无法修改全局变量的值
  • 全局变量是不可变数据类型,函数无法修改全局变量的值
  1. global 关键字可以将局部变量变成一个全局变量
    格式: global 变量名称
  2. nonlocal 关键字可以修改外层(非全局)变量

Python内置函数

  • max(ITerable, key, default): 求迭代器的最大值
ret = max(1,2,3)
print(ret)

res = max(1,2,-3,key=abs)
print(res)

lst = [{"name":"dht","price":"100"},
{"name":"dwa","price":"234"}, 
{"name":"grf","price":"666"}]

def price_func(dic):    
    return dic["price"]
ret = max(lst,key=price_func)
print(ret)
  • map:有两个参数,第一个参数是一个函数,第二个参数是可迭代的内容函数会依次作用在可迭代内容的每一个元素上进行计算,然后返回一个新的可迭代内容
lst = [1,2,3,4,5]
def pingfang(x):    
    return x * x
ret = map(pingfang,lst)
for i in ret:    
    print(i)
  • filter:用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表
    该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进判然后返回 True 或 False,最后将返回 True 的元素放到新列表中
lst = [1,2,3,4,5,6,7,8,9,10]
def ou_num(num):    
    if num%2==1:        
        return True
ret = filter(ou_num,lst)
for i in ret:    
    print(i)
  • zip:函数接受任意多个可迭代对象作为参数,将对象中对应的元素打包成一个 tuple然后返回一个可迭代的 zip 对象.这个可迭代对象可以使用循环的方式列出其元素若多个可迭代对象的长度不一致,则所返回的列表与长度最短的可迭代对象相同
a = [1,2,3]
b =["a","b","c"]
ret = zip(a,b)
for i in ret:    
    print(i)

匿名函数

语法:变量名= lambda 参数:表达式(block)
参数:可选,通常以逗号分隔的变量表达式形式,也就是位置参数
表达式:不能包含循环、return,可以包含 if...else...

add = lambda x,y:x+y
print(add(1,2))

闭包

  • 闭包条件:
    1. 在一个外函数中定义了一个内函数
    2. 内函数里使用了外函数的临时变量
    3. 外函数的返回值是内函数的引用
 # 闭包函数的实例
 # outer是外部函数 a和b都是外函数的临时变量
 def outer( a ):
        b = 10
        # inner是内函数
        def inner():
            #在内函数中 用到了外函数的临时变量
            print(a+b)
        # 外函数的返回值是内函数的引用
        return inner

装饰器

装饰器:本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景

def print_execute_time(func):
    from time import time

    # 定义嵌套函数,用来打印出装饰的函数的执行时间
    def wrapper(*args, **kwargs):
        # 定义开始时间和结束时间,将func夹在中间执行,取得其返回值
        start = time()
        func_return = func(*args, **kwargs)
        end = time()
        # 打印方法名称和其执行时间
        print(f'{func.__name__}() execute time: {end - start}s')
        # 返回func的返回值
        return func_return

    # 返回嵌套的函数
    return wrapper


# 定义一个随机数求和的方法,传入参数是随机数的个数,加上刚才定义的装饰器
@print_execute_time
def cal_sum(size):
    from random import random
    li = [random() for i in range(size)]
    return sum(li)

cal_sum(1000000)

迭代器

  • 迭代:

    迭代是访问集合元素的一种方式,可以将某个数据集内的数据“一个挨着一个的取出来”, 就叫做迭代

  • 可迭代对象:

    • 可以通过循环遍历取出元素的对象就是可迭代对象

    • 通过isinstance()判断一个对象是否是可迭代对象

    #isinstance(obj,Iterable)
    print(isinstance([],list))
    print(isinstance([],Iterable)) #True
    print(isinstance(123,Iterable)) #False
    for i in 123:
        pass
    
  • 迭代器:帮我我们在迭代遍历时记录访问的位置,以便每次迭代都可以返回下一条数据,拥有__iter__方法和__next__方法的对象就是迭代器

  • __iter____next__方法

    iter()函数把可迭代对象中的迭代器取出来,内部调用__iter__方法
    next()函数通过迭代器获取下一位置的值,内部调用__next__方法
    string = "hello"
    # for i in string:
    #     print(i)
    #获取迭代器
    iter1 = iter(string)
    #使用next()函数获取元素
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    
  • 迭代器实现斐波那契数列

    class Fib:
        def __init__(self,n):
            self.n = n #第几个数
            self.a = 1
            self.b = 1
            self.index = 0 #记录位置
        def __iter__(self):
            return self
        def __next__(self):
            if self.index<self.n:
                num = self.a
                self.a,self.b = self.b,self.a+self.b
                self.index+=1
                return num
            else:
                raise StopIteration
    fib = Fib(5)
    # for i in fib:
    #     print(i,end=' ')
    iter1 = iter(fib)
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    

生成器

  • 概念:生成器的本质就是迭代器

    ​ 生成器包括两种:生成器函数和生成器表达式

  • 一个包含 yield 关键字的函数就是一个生成器函数。并且 yield 不能和 return 共用,并且 yield 只能用在函数内

    (1).生成器函数执行之后会得到一个生成器作为返回值,并不会执行函数体

    (2).执行了__next__()方法之后才会执行函数体,并且获得返回值

    (3).next()内置方法,内部调用生成器函数的__next__()方法

    (4).yield 和 return 相同的是可以返回值,但是不同的是 yield 不会结束函数

    def func():
        print("--func--")
        yield 1
    g = func()
    # print(g)
    print(next(g))
    
    def func():
        print("--func--")
        yield 1
        print("func2")
        yield 2
    g = func()
    # print(g)
    print(next(g))
    print(next(g))
    
    
  • 生成器实现斐波那契数列

    def fib(n):
        a,b = 1,1
        index = 0
        print("----1-----")
        while index<n:
            print("----2-----")
            yield a
            a,b = b,a+b
            index+=1
            print("----3-----")
    g = fib(5)
    # for i in g:
    #     print(i,end=' ')
    print(next(g))
    print(next(g))
    print(next(g))
    
  • send()

    send 获取下一个值的效果和 next()基本一致,只是在获取下一个值的时候,给上一 yield 的位

    置传递一个数据

    使用 send 的注意事项

    (1).第一次使用生成器的时候 是用 next 获取下一个值

    (2).最后一个 yield 不能接受外部的值

    def generator():
        print("a")
        count = yield 1
        print("--->",count)
        print("b")
        yield 2
        print("c")
    g = generator()
    print(g.__next__())
    print(g.__next__())
    
    def generator():
        print("a")
        count = yield 1
        print("--->",count)
        print("b")
        yield 2
        print("c")
    g = generator()
    # print(g.__next__())
    print(g.send(10))
    
    
  • yield from 循环遍历容器类型

    def func():
        for i in "hello":
            yield i
        for j in range(3):
            yield j
    f = func()
    print(next(f))
    
    def func():
        yield from "hello"
        yield from range(3)
    f = func()
    for i in f:
        print(i,end=' ')
    
  • 生成器表达式

    • 格式:将列表推导式[ ] 改成()即可
    lst = [i for i in range(1,10)]
    print(lst)
    iter1 = iter(lst)
    print(next(iter1))
    print(next(iter1))
    
    g = (i for i in range(1,10))
    print(g)
    print(next(g))
    print(next(g))
    print(list(g))
    
posted @ 2020-05-09 19:08  慕|白  阅读(194)  评论(0)    收藏  举报