zoukankan      html  css  js  c++  java
  • 整理------函数

    函数参数顺序

    位置参数 > *args > 默认值参数 > **kwargs
     
    动态参数的另一种传参方式  :  在实参位置上给一个序列,列表,可迭代对象前面加个*表示把这个序列按顺序打散
    l = [11,22,33,44]
    s = "臣妾做不到"
    def fun(*args):
        print(args)     
    fun(*l)       #fun打印结果为:      (11, 22, 33, 44)
    fun(*s)       #fun打印结果为:     ('臣', '妾', '做', '不', '到')
    在形参的位置上的* 表示把接收到的参数组合成一个元组
    如果是一个字典, 那么也可以打散. 不过需要用两个*
    def fun(**kwargs):
        print(kwargs)
    dic = {'a':1, 'b':2}
    fun(**dic)      #   {'a': 1, 'b': 2}
    函数的注释:
    def chi(food, drink):
    """
    这里是函数的注释, 先写一下当前这个函数是干什么的, 比如我这个函数就是一个吃
    :param :param food: 参数food是什么意思
    :param :param drink: 参数drink是什么意思
    :return :return: 返回的是什么东东
     """
    print(food, drink)
    return "very good"
    命名空间
    在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了, 至于函数内部的变量和逻辑, 解释器是不关心的. 也就是说一开始
    的时候函数只是加载进来, 仅此而已, 只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕而被清空.


    命名空间分类:
    1. 全局命名空间--> 我们直接在py文件中, 函数外声明的变量都属于全局命名空间
    2. 局部命名空间--> 在函数中声明的变量会放在局部命名空间
    3. 内置命名空间--> 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置命名空间
    加载顺序:
    1. 内置命名空间
    2. 全局命名空间
    3. 局部命名空间(函数被执行的时候)
    取值顺序:
    1. 局部命名空间
    2. 全局命名空间
    3. 内置命名空间
    我们可以通过globals()函数来查看全局作用域中的内容, 也可以通过locals()来查看局部作
    用域中的变量和函数信息
    print(globals())    #{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00466590>, '__spec__': None, 
                '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/ZYP/PycharmProjects/python_ui/test_tools/test.py', '__cached__': None}
    def func(): a = 10 print(locals()) #{'a': 10} func()
    对于可变数据类型可以直接进行访问. 但是不能改地址. 说白了. 不能赋值
    l = [11,22,33,44]
    def fun():
        l.append(55)
        print(l)    #      [11, 22, 33, 44, 55]
    fun()
    print(l)         #      [11, 22, 33, 44, 55]
    a = 2
    def w():
        a +=1
        print(a)
    w()      #报错,不能赋值
    迭代器
    闭包
    闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包
    def func1():
      name = "zyp"
      def func2():
        print(name) # 闭包
      func2()
    func1()
    结果:
    zyp
    我们可以使用__closure__来检测函数是否是闭包. 使用函数名.__closure__返回cell就是闭包. 返回None就不是闭包
    def func1():
        name = "zyp"
        def func2():
            print(name) # 闭包
        func2()
        print(func2.__closure__)
    func1()
    结果:
    zyp
    闭包的作用就是让一个变量能够常驻内存. 供后面的程序使用
     
    生成器和迭成器表达式
    生成器
    什么是生成器.生成器其实就是迭代器
    在python中有三种方式来获取生成器:
    1. 通过生成器函数
    2. 通过各种推导式来实现生成器
    3. 通过数据的转换也可以获取生成器
    def func():
    print("111")
    return 222
    ret = func()
    print(ret)
    结果: 
    111
    222
    将函数中的return换成yield就是生成器
    def func():
    print("111")
    yield 222
    ret = func()
    print(ret)
    结果: 
    <generator object func at 0x10567ff68>
    运行的结果和面⾯不一样. 为什么呢. 由于函数中存在了yield. 那么这个函数就是一个生成器函数. 这个时候. 我们再执行这个函数的时候. 就不再是函数的执行了. 而是获取这个生成器我们可以直接执行__next__()来执行以下生成器.
    def func():
        print("111")
        yield 222
    ret = func()
    print("ret",ret)
    a = ret.__next__()
    print("a",a)
    
    结果
    ret <generator object func at 0x0209AF60>
    111
    a 222
    那么我们可以看到, yield和return的效果是一样的. 有什么区别呢? yield是分段来执行一个函数. return呢? 直接停止执行函数.
    def func():
    print("111")
    yield 222
    print("333")
    yield 444
    gener = func()
    ret = gener.__next__()
    print(ret)
    ret2 = gener.__next__()
    print(ret2)
    ret3 = gener.__next__() # 最后⼀个yield执⾏完毕. 再次__next__()程序报错, 也就是
    说. 和return⽆关了.
    print(ret3)
    结果:
    111
    Traceback (most recent call last):
    222
    333
    File "/Users/sylar/PycharmProjects/oldboy/iterator.py", line 55, in
    <module>
    444
    ret3 = gener.__next__() # 最后⼀个yield执⾏完毕. 再次__next__()程序报错, 也
    就是说. 和return⽆关了.
    StopIteration
    当程序运行完最后一个yield. 那么后面继续进行__next__()程序会报错.
    生成器有什么作用呢?
    占内存少,用多少取多少
    send和__next__()⼀样都可以让生成器执行到下一个yield.
    def eat():
        print("我吃什么啊")
        a = yield "馒头"
        print("a=",a)
        b = yield ""
        print("b=",b)
        c = yield "菜盒"
        print("c=",c)
        yield "GAME OVER"
    gen = eat() # 获取⽣成器
    ret1 = gen.__next__()
    print(ret1)
    ret2 = gen.send("胡辣汤")
    print(ret2)
    ret3 = gen.send("狗粮")
    print(ret3)
    ret4 = gen.send("猫粮")
    print(ret4)
    
    
    结果
    我吃什么啊
    馒头
    a= 胡辣汤
    饼
    b= 狗粮
    菜盒
    c= 猫粮
    GAME OVER
    send和__next__()区别:
    1. send和next()都是让生成器向下走一次
    2. send可以给上面个yield的位置传递值, 不能给最后一个yield发送值. 在第一次执行生成器代码的时候不能使用send()

    列表推导式, 生成器表达式以及其他推导式
    列表推导式
    lst = [i for i in range(1, 15)]
    print(lst)
    常用写法:
    [ 结果 for 变量 in 可迭代对象]

    我们还可以对列表中的数据进行筛选筛选模式:
    [ 结果 for 变量 in 可迭代对象 if 条件 ]
    # 获取1-100内所有的偶数
    lst = [i for i in range(1, 100) if i % 2 == 0]
    print(lst)
    生成器表达式和列表推导式的语法基本上是一样的. 只是把[]替换成()
    gen = (i for i in range(10))
    print(gen)
    结果: 
    <generator object <genexpr> at 0x106768f10>
    打印的结果就是一个⽣生成器. 我们可以使用for循环来循环这个生成器:
    for i in gen:
    print(i)
    生成器表达式也可以进行筛选:
    # 获取1-100内能被3整除的数
    gen = (i for i in range(1,100) if i % 3 == 0)
    for num in gen:
    print(num)
    生成器表达式和列表推导式的区别:
    1. 列表推导式比较耗内存. 一次性加载. 生成器表达式几乎不占用内存. 使用的时候才分
    配和使用内存
    2. 得到的值不一样. 列表推导式得到的是一个列表. 生成器表达式获取的是个生成器

    深坑==> 生成器. 要值得时候才拿值.

    字典推导式:
    dic = {"a":1,"b":2}
    new_dic = {dic[key]:key for key in dic}
    print(new_dic)   #{1: 'a', 2: 'b'}
    lst1 = ['11', '22', '33']
    lst2 = ['aa', 'bb', 'cc']
    dic = {lst1[i]:lst2[i] for i in range(len(lst1))}
    print(dic)   #{'11': 'aa', '22': 'bb', '33': 'cc'}
    集合推导式:
    集合推导式可以帮我们直接生成一个集合. 集合的特点: 无序, 不重复. 所以集合推导式自带去重功能
    lst = [1, -1, 8, -8, 12]
    s = {abs(i) for i in lst}    #绝对值abs
    print(s)   #  {8, 1, 12}
    总结: 推导式有, 列表推导式, 字典推导式, 集合推导式, 没有元组推导式
     
     
     
     
     
     
  • 相关阅读:
    integer和double的比较.
    查看mysql版本的四种方法
    codefoces 1397D Stoned Game
    最小生成树集合合并
    codefoces 1400B RPG Protagonist
    codefoces 1400B RPG Protagonist
    牛客挑战赛42 小睿睿的伤害
    病毒扩散 排列组合
    Dus on tree 月出皎兮,佼人僚兮。
    msc的宠物 二分+树形DP
  • 原文地址:https://www.cnblogs.com/Aline2/p/11262557.html
Copyright © 2011-2022 走看看