zoukankan      html  css  js  c++  java
  • python函数

    一、函数初识

    •  函数的定义和调用: 对功能进行定义和封装,方便调用

        基本格式: 

            def  函数名(形参):

              函数体(代码块)

            函数名(实参)

    •  函数名: 函数名的命名规则和变量是一样的

    定义一个简单的函数并调用它:

    1 def app():
    2     print("这只是在构建最基本的函数格式")
    3     print("函数的功能并不只是打印内容")
    4     print("函数的作用是封装功能,里面什么都能写")
    5 
    6 app()
    •  函数的返回值:

        return      执行完函数之后. 我们可以使用return来返回结果.当函数执行到return之后,结束此函数,不在继续执行     return 可以返回多个值,用元组表示

    1 def app():
    2     print("这只是在构建最基本的函数格式")
    3     print("函数的功能并不只是打印内容")
    4     print("函数的作用是封装功能,里面什么都能写")
    5     return '基本格式', '封装功能'
    6 print(app())
    •  关于返回值:

        如果return什么都不写 或者 干脆不写return .那么返回的就是None

        如果return后面写了一个值. 则调用者可以接收一个结果

        如果return后面写了多个结果, 则调用者可以接收一个tuple, 调用者可以直接解构成多个变量

    •  函数的参数:   函数在调用的时候指定具体的一个变量的值. 就是参数.

        形参:

          位置参数:  按照位置顺序给函数创建参数

    1 def yue(fangshi, age):   # 形参
    2     print("打开手机")
    3     print("打开%s" % fangshi)
    4     print("找一个漂亮的妹子")
    5     print("年龄最好是%s" % age)
    6     print("出来约一约")
    7 
    8 yue("探探", 38)
    9 yue("陌陌", 26)

          默认值参数:  指定参数的值,如果传参是不输入值,则使用默认值

    1 def regist(id, name, sex=""):
    2     print("录入学生信息:id是%s, 名字是%s, 性别是:%s" % (id, name, sex))
    3 
    4 regist(1, "大阳哥")
    5 regist(2, "徐卫星")
    6 regist(3, "毛尖妹妹", "")

          位置参数和默认值参数混合使用: 可以把上面两种参数混合着使用. 也就是说在调用函数的时候即可以给出位置参数, 也可 以指定参数的默认值.

        实参:

          位置参数:  按照位置给形参赋值

          关键字参数:   按照名称给形参赋值

          混合参数:   先用位置参数, 再用关键字参数

    1 def gn(name, age, address, id, sex, hobby):
    2     print("人的名字叫%s, 年龄:%s, 地址:%s, id是:%s, 性别:%s, 爱好是:%s" % (name, age, address, id, sex, hobby))
    3 gn("太白", 58, "保定", 1, "不详", "")    # 位置参数
    4 gn(id=1, name="太白", address="保定", hobby="", age=58, sex="不详")  # 关键字(形参)参数
    5 gn("太白", 58, "保定", id="3", sex="", hobby="不详")

     二、函数参数,命名空间和作用域

    • 函数传参 - 动态传参

        *args   动态传参   位置传参

    def chi(*food):
        print("我要吃", food)
    chi("包子", '馒头', '米饭', '小龙虾', '黄焖鸡', '酸菜鱼')

        示例:传入任意整数,求所有数的和

    def num(*digit):
        sum = 0
        for i in digit:
            sum = sum + i
        return sum
    print(num(1,2,3,4,5,6,7))

        **kwargs  动态传参   关键字传参

    def app(**games):
        print(games)
    app(free_game ='消消乐', dongzuo_game = "格斗之王", jingji_game = "王者荣耀", yizhi_game = '数独')

        当*args 和 **kwargs一起使用时,什么东西都能传入

    def func(*args,**kwargs):
        print(args)
        print(kwargs)
    func('哈士奇', '金毛', '萨摩', name='y',age=22,sex='nan')

       参数接收顺序: 位置参数  , *args  , 默认值参数  , **kwargs

    • 函数的命名空间和作用域

      • 命名空间

          内置命名空间:   存放python解释器为我们提供的名字, list, tuple, str, int这些都是内 置命名空间

          全局命名空间:   我们直接在py⽂件中, 函数外声明的变量都属于全局命名空间

          局部命名空间:   在函数中声明的变量会放在局部命名空间

          加载顺序:  内置命名空间  , 全局命名空间  , 局部命名空间

          取值顺序:  局部命名空间  , 全局命名空间  , 内置命名空间

      • 作用域

          全局作用域:   包含内置命名空间和全局命名空间. 在整个文件的任何位置都可以使用(遵循 从上到下逐行执行).

          局部作用域:   在函数内部可以使用.

          作用域命名空间:

            全局作用域:  内置命名空间  +  全局命名空间

            局部作用域:   局部命名空间

          globals()    查看全局作用域中的名字

          locals()        查看局部作用域中的名字

     a = 10
    def func():
        a = 40
        b = 20
        def abc():
           print("哈哈")
        print(a, b) # 这⾥使⽤的是局部作⽤域
        print(globals()) # 打印全局作⽤域中的内容
        print(locals()) # 打印局部作⽤域中的内容
    func()
    • global  和  nonlocal

      • global   把全局变量拿到局部来用
      • nonlocal    把离他最近的一层的变量拿过来.不会找全局

       global  使用示例

    1 a = 100
    2 def func():
    3     global a # 加了个global表示不再局部创建这个变量了. 而是直接使用全局的a
    4     a = 28
    5     print(a)
    6 func()
    7 print(a)

       nonlocal  使用示例

     1 a = 10
     2 def func1():
     3     a = 20
     4     def func2():
     5         nonlocal a
     6         a = 30
     7         print(a)
     8     func2()
     9     print(a)
    10 func1()

    三、函数名的应用(高阶函数),闭包,迭代器,生成器

    • 函数可以像变量一样使用

        1.函数名可以赋值给其他变量

        2.函数名可以当做函数的参数

        3.函数名可以作为函数的返回值

        4.函数名可以作为list元素

     赋值:

    1 def func():
    2     print("呵呵")
    3 print(func)
    4 a = func    # 把函数当成⼀个变量赋值给另⼀个变量
    5 a()      # 函数调⽤ func()

    做list元素:

     1 def func1():
     2     print("呵呵")
     3 def func2():
     4     print("呵呵")
     5 def func3():
     6     print("呵呵")
     7 def func4():
     8     print("呵呵")
     9 lst = [func1, func2, func3,func4]
    10 for i in lst:
    11     i()

     做返回值:

    1 def func_1():
    2     print("这里是函数1")
    3     def func_2():
    4         print("这里是函数2")
    5     print("这里是函数1")
    6     return func_2
    7 fn = func_1()    # 执行函数1. 函数1返回的是函数2, 这时fn指向的就是上面函数2
    8 fn()     # 执行上面返回的函数
    • 闭包

      闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包

    1 def func1():
    2     name = "alex"
    3     def func2():
    4         print(name)  # 闭包
    5     func2()
    6 func1()

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

    1 def func1():
    2     name = "alex"
    3     def func2():
    4         print(name)  # 闭包
    5     func2()
    6     print(func2.__closure__) # (<cell at 0x10c2e20a8: str object at0x10c3fc650>,)
    7 func1()

      闭包的特征:

        常驻内存

        安全

    • 迭代器

      可迭代对象:str ,list,dict,tuple,set,range           iterable(可迭代对象)       内部包含 __iter__() 函数

      迭代器:文件句柄   iterator(迭代器)    内部包含__iter__()  和  __next__() 函数

    迭代器示例:

    1 lst = ['','','','','','','']
    2 
    3 f = lst.__iter__()
    4 while 1:
    5     try:
    6         name = f.__next__()
    7         print(name)
    8     except StopIteration:
    9         break
    • 迭代器特征:
      • 节省内存
      • 惰性机制
      • 不能反复,只能向下执行

    生成器

    • 生成器实质就是迭代器
    • 获取生成器的方式:
      • 通过生成器函数
      • 通过推导式实现生成器
      • 通过数据转换实现生成器

    获取生成器函数 __next__():

     1 def func():
     2     print('假装我是一个功能')
     3     yield '然而并不是'
     4     print('假装我是小蝌蚪')
     5     yield '你看不见我'
     6     print('假装我是一阵风')
     7     yield '无影无形'
     8 
     9 s = func()
    10 print(s.__next__())
    11 print(s.__next__())
    12 print(s.__next__())

    节省内存的方法:

     1 def eggs():
     2     i = 1
     3     while i < 101:
     4         yield '鸡蛋%s' % i
     5         i += 1
     6 s = eggs()
     7 print(s.__next__())
     8 print(s.__next__())
     9 print(s.__next__())
    10 print(s.__next__())

    获取生成器函数 send():

     1 def eat():
     2     print("我吃什么啊")
     3     a = yield "馒头"
     4     print("a=",a)
     5     b = yield "⼤饼"
     6     print("b=",b)
     7     c = yield "⾲菜盒⼦"
     8     print("c=",c)
     9     yield "GAME OVER"
    10 gen = eat() # 获取⽣成器
    11 ret1 = gen.__next__()
    12 print(ret1)
    13 ret2 = gen.send("胡辣汤")
    14 print(ret2)
    15 ret3 = gen.send("狗粮")
    16 print(ret3)
    17 ret4 = gen.send("猫粮")
    18 print(ret4)

    列表推导式:

      [结果 for 变量 in 可迭代对象 if 条件]

    1 # 获取1-100内能被3整除的数
    2 lst = [i for i in range(1,101)  if i % 3 == 0]
    3 print(lst)
    1 # 寻找名字中带有两个e的人的名字
    2 names = [['Tom', 'Billy', 'Jefferson' , 'Andrew' , 'Wesley' , 'Steven' ,'Joe'],['Alice', 'Jill' , 'Ana', 'Wendy', 'Jennifer', 'Sherry' , 'Eva']]
    3 lst = [a for i in names for a in i  if a.count('e') == 2]
    4 print(lst)

    字典推导式:

      {结果 for 变量 in 可迭代对象 if 条件}  结果是键值对=》key:value

    1 # 字典推导式
    2 
    3 list1 = ['', '', '', '', '', '', '']
    4 list2 = ['','','','','6','', '']
    5 
    6 dic = {list1[i]:list2[i]  for i in range(len(list1))}
    7 print(dic)

    集合推导式:

      {结果 for 变量 in 可迭代对象 if 条件}  结果是 key

    1 lst = [1, -1, 8, -8, 12]
    2 # 绝对值去重
    3 s = {abs(i) for i in lst}
    4 print(s)

    生成器表达式和列表推导式的区别:

      1.列表推导式比较耗内存. 一次性加载. 生成器表达式几乎不占用内存. 使用的时候才分 配和使用内存

      2.得到的值不一样. 列表推导式得到的是一个列表. 生成器表达式获取的是一个生成器

  • 相关阅读:
    《DSP using MATLAB》Problem 6.4
    《DSP using MATLAB》Problem 6.3
    《DSP using MATLAB》Problem 6.1
    《DSP using MATLAB》Problem 5.38
    整除分块+取模
    尺取法(滑窗,双指针)
    uva247电话圈(floyd)
    uva1151并查集+最小生成树
    uva1395 苗条的生成树
    uva10562看图写树
  • 原文地址:https://www.cnblogs.com/child-king/p/9299931.html
Copyright © 2011-2022 走看看