封装成vla函数_第四章:Python之函数

第一节:函数入门与定义函数

  • 理解函数
    • 所谓函数,就是为一段实现特定功能的代码“取”个名字,以后即可通过该名字来执行(调用)这段代码
    • 从逻辑上看,函数相当于一个黑匣子
  • 定义函数的语法
    • 定义函数的三条铁律
      • 函数需要几个关键的、需要动态变换的数据,这些数据就应该定义成函数的参数
      • 函数需要传出去几个重要的数据(就是调用该函数的人希望得到的数据),这些数据应该定义成返回值
      • 函数内部的实现过程
    • 函数的语法:
fff395751924a0140eb46af70a578893.png

函数的语法

# 定义函数,无参数def first():    # 之前学习的定义变量、赋值、运算、分支、循环等全部都可以写在函数里面    print('first 函数')    for i in range(5):        print(i)first()# 只要执行函数,函数体的代码就可以被重复的调用(复用)first()first()# 函数定义,有一个参数 namedef hello(name):    print('hello 函数')    print('您好,' + name)hello('python')hello('java')# 函数定义,有2个参数 name, agedef info(name, age):    print('info函数')    print('name参数', name)    print('age参数', age)info(python, 90)info(java, 70)# 定义函数,有返回值def max(a, b):    r = a if a > b else b    # 返回值    return r# 返回值的意思,当程序调用函数之后,会得到N个值x = max(10, 20)print(x)x = max(30, 20)print(x)# print也是个函数,函数的嵌套print(max(20, 50))
  • 为函数提供文档
    • 只要把一段字符串放在函数声明之后、函数体之前,这段字符串就是函数的说明文档
    • Python内置的help()函数查看其它函数的帮助文档
    • 通过函数的_doc_属性来查看函数的说明文档
# 自定义说明文档def test(a):    '''    test 函数的说明,这是一个简单的函数    a-代表什么意义    return- 代表什么意义    '''    # 空语句    passprint(test.__doc__)help(test)

第二节:多返回值函数与递归函数

  • 多返回函数
    • 多返回值,本质就是返回元组
    • 程序即可返回元组,也可直接返回多个值(系统会自动将其封装成元组)
    • 获取多返回值函数的返回值时
      • 既可以用单个变量(元组)来获取
      • 也可以用多个变量获取(元组解包)
import random# 希望该函数返回三个随机的大写字符def test():    # 生成三个随机的大写字符    c1 = chr(random.randint(65,90))    c2 = chr(random.randint(65,90))    c3 = chr(random.randint(65,90))        # 以元组的形式返回    return(c1, c2, c3)    # 程序自动封装成元组    return c1, c2, c3# r就是一个元组r = test()print(r)print(test())# 多返回值函数,即可用多个变量来接收返回值,也可用单独变量来接收返回值c1, c2, c3 = test()print(c1)print(c2)print(c3)
  • 递归函数
    • 函数体内调用它自身,被称为函数的递归
    • 函数递归包含了一种隐式的循环,它会重复执行某段代码,但是这种重复执行无需循环控制
    • 递归函数的注意点
      • 向已知的方向递归
      • 让递归有结束的时候,不要无限递归
# 无限递归的例子def foo():    print('111')    print('222')    foo()foo()# 计算N的阶乘def frac(n):    if n < 1:        print("n不能小于1")        return    elif n == 1:        return 1    else:        # n的阶乘总是等于上一个阶乘*n        # 函数调用自身        return frac(n-1) * n        # 该函数的结束点是n==1,因此要向n==1方向递归        print(frac(5))print(frac(6))

第三节:关键字参数与参数默认值

  • 关键字参数
    • Python函数的参数名不是无意义的,Python允许调用函数时通过名字来传入参数值
    • 调用函数时支持两种方式为参数指定值
      • 位置参数:必须按照顺序为每个参数指定参数值
      • 关键字参数(命名参数):按参数名为参数指定参数值
def info(name, age, height):    print("name:", name)    print("age:", age)    print("height:", height)    # 位置参数,按照顺序传递参数info('fkjava', 24, 183)# 关键字参数(命名参数)# 关键字参数的优势是 1:不需要按照顺序 2:可读性更高info(age=34, name='java', height=179)# 混合使用info('python', height=178, age=45)# 混合使用错误:关键字参数必须位于位置参数的后面info(name='python', 178, 45)
  • 参数的默认值
    • 程序需要在定义函数的时候为一个或者多个形参指定默认值,这样调用函数时就可以省略该形参传入参数值,而是直接使用该形参的默认值
    • 为形参指定默认值的语法格式如下:形参名 = 默认值
# 定义带默认值的参数(一个参数有默认值)def info(age, name='python'):    print('age参数为:', age)    print('name参数为:', name)      # 为参数指定默认值之后,调用时候可省略指定的参数值,该参数使用默认值    info(23)info(45, 'abc')info(11, 'Java')# 混合方式info(19, name='bcd')# 定义带默认值的参数(两个参数有默认值)def info(age=19, name='python'):    print('age参数为:', age)    print('name参数为:', name)    info()info(20)# 如果你希望省略前面的参数指定参数值,后面的参数应该用关键字参数来传入参数info(name='go')

第四节:参数搜集和逆向参数收集

  • 参数收集
    • 普通参数收集
      • 在形参前面加上一个星号(*),这样就意味着该参数可接收多个参数值,多个参数值被当成元组传入
      • 参数收集的本质就是一个元组:Python会将传给带*参数的多个值收集成一个元组
      • Python允许个数可变的参数可以处于形参列表的任意位置,但是最多只能带一个支持“普通”参数收集的参数
      • 如果支持“普通”参数收集的形参位于前面,后面参数则需要使用关键字参数传值
# books参数支持收集,它可接受多个参数值def test(num, *books):    print("num:", num)    print("books:", books)# 将多个值自动封装成一个元组test(5, "go", "python", "java")def info(*names, msg):    for name in names:        print("%s, %s" % (name, msg))# 如果你要为参数收集后的参数传入参数值,需要用关键字参数 info("孙悟空", "猪八戒", "牛魔王", msg="欢迎大家") # 否则所有参数都会被参数收集成元组 info("孙悟空", "猪八戒", "牛魔王", "欢迎大家")
    • 关键字参数收集
      • 在参数前面添加两个星号“**”,该参数支持关键字参数收集,收集的参数被当做dict处理
      • 一个函数可同时支持普通参数收集和关键字参数收集
# books参数支持普通参数收集,它可接受多个参数值,socres支持关键字参数收集def test(num, *books, **socres):    print("num:", num)    print("books:", books)    print("socres:", socres)test(20, 'fkjava', 'python', 'swift', 语文=89, 数学=93)def info(*names, msg, **socres):    for name in names:        print("%s, %s" % (name, msg))    print(socres)# 程序知道msg参数将是传给msg的,因此socres参数不会收集它# dict的参数收集,它只收集不能明确传入的关键字参数info("孙悟空", "猪八戒", "牛魔王", msg="欢迎大家", 语文=89, 数学=93) 
  • 逆向参数收集
    • 在列表、元组前添加*,在字典之前添加**
def test(a, b):    print(a)    print(b)# 元组的逆向参数收集,以普通参数的形式为参数传入参数值vals = (20, 40)# 调用函数时,元组不能自动解包# 默认情况下,元组是一个整体test(vals)# 这个语句是错误的# *对元组自动解包(逆向参数收集)test(*vals)# 列表的逆向参数收集,以普通参数的形式为参数传入参数值msgs = ['aa', 'bb']test(*msgs)# 字典的逆向参数收集,以关键字参数的形式为参数传入参数值# 简单来说,**是将字典解析成关键字参数vals = {'a': 89, 'b': 93}test(**vals)

第五节:变量作用域

  • 理解变量作用域
    • 根据定义变量的位置,变量的作用域分为两种:
      • 局部变量:在函数中定义的变量包括参数,都被成为局部变量
      • 全局变量:在函数外面、全局范围内定义的变量,被称为全局变量
# 全局变量a = 35def info():    # 局部变量    b = 'fkjava'    # 正确,局部变量只能在当前函数内访问    print(b)    # 正确,全局变量可以在任何函数内访问    print(a)    def info1():    # 局部变量    c = 'java'    print(c)    # 正确,全局变量可以在任何函数内访问    print(a)    # 错误,局部变量只能在定义局部变量的函数中使用    #print(b)    info()info1()
  • 变量字典
    • 获取变量字典
      • globals():该函数返回全局范围内搜所有变量组成的“变量字典”
      • locals():该函数返回当前局部范围内搜所有变量组成的“变量字典”
      • vars(object):获取指定对象的范围内所有变量组成的“变量字典”,如果不传入object参数,vars()和locals()作用完全相同
# 全局变量a = 35name = 'java'def info():    # 局部变量    b = 'fkjava'    # 正确,局部变量只能在当前函数内访问    print(b)    # 正确,全局变量可以在任何函数内访问    print(a)        # 局部变量组成的数组    print(locals())    def info1():    # 局部变量    c = 'java'    print(c)    # 正确,全局变量可以在任何函数内访问    print(a)    # 错误,局部变量只能在定义局部变量的函数中使用    #print(b)        # 局部变量组成的数组    print(locals())# 全局变量组成的数组print(globals())  # locals获取当前范围内的所有局部变量# 因此你在全局范围调用locals函数的时候,它返回全部的全局变量# 简单来说,你在全局范围内,用globals和locals函数效果是一样的print(locals())   info()info1()
  • 处理局部变量遮蔽全局变量
    • 全局变量默认可以在所有函数内访问
    • 如果在函数中定义了与全局变量同名的变量,此时就会发生局部变量的遮蔽(hide)全局变量的情形
# 解决方法一name = 'java'def info():    # 依然访问全局变量name    print(globals()['name'])    # 在函数内对变量赋值,变成了定义新的name变量    name = 'python'    print(name)    info()# 全局变量name没有改变print(name)# 解决方法二name = 'java'def info():    # 声明作用:该函数中的name始终使用全局变量    global name    # 依然访问全局变量name    print(name)    # 前面已经声明了name始终是全局变量    # 因此此处不是重新定义局部变量    name = 'python'    print(name)    info()# 全局变量name会被改变print(name)

第六节:局部函数

  • 理解局部函数
    • 放在函数体内的函数称为局部函数
    • 在默认情况下,局部函数对外部是隐藏的,局部函数只能在其封闭(enclosing)函数内使用
  • 定义、使用局部函数
def foo():    print('foo函数')    # 嵌套函数:在其他函数内定义的函数    def bar():        for i in range(5):            print('bar函数')    # 只能在foo函数内调用bar函数    bar()# 在此处调用bar函数出错,局部函数只在它所在的封闭函数内有效# bar()foo()
  • 封闭函数返回局部函数
    • 封闭函数可以返回局部函数,以便程序在其他作用域中使用局部函数
    • 如果封闭函数没有将局部函数返回出来,那么局部函数将只能在封闭函数内部调用
def foo():    print('foo函数')    # 嵌套函数:在其他函数内定义的函数    def bar():        for i in range(5):            print('bar函数')    # bar表示返回函数本身(函数也相当于一个值,是function类型的值)    # bar()表示调用(执行)函数    return bar    # foo函数的返回值时bar函数,因此此处是用变量r来保存bar函数r = foo()print(r)# 此时R引用bar函数本身,r的类型是functionprint(type(r))print('-' * 60)# 由于r是函数,因此程序可以调用它r()# 下面代码看上去有点诡异# foo函数调用之后返回bar函数,bar函数也可调用foo()()
  • 局部函数的变量遮蔽
    • 局部函数内的变量也会遮蔽它所在的封闭函数的局部变量
    • 避免方法:可用nonlocal进行声明
def test():    name = 'fkjava'    def  info():        print('info 函数')                # 声明后面的name变量不是声明新的局部变量,而是引用所在封闭函数的局部变量        nonlocal name        print('name:', name)        # 默认情况下,下面代码是为info这个局部函数再次定义name局部变量        # 此时name局部变量就会遮蔽test函数的name变量        name = 'crazyit'        # 在没有用nonlocal声明之前,此时打印会出错,用nonlocal声明之后,程序正常        print('name:', name)    info()    print(name)test()
    • global与nonlocal总结
      • 作用大致相同,都是用来避免变量遮蔽
      • 区别:global用于声明访问全局变量。nonlocal用于声明访问局部函数所在封闭函数内的局部变量

第七节:案例实操-定义计算N的阶乘的函数

  • 实现方法
    • 方法一:使用循环计算阶乘
      • 控制循环计数器从1循环到N
      • 让循环计数器与前一个结果相乘,直到循环计数器等于N就得到了N的阶乘
def fract():    r = 1    if n < 1:        print('n不能小于1')        return     else:         for i in range(1, n + 1):             r *= i         return rprint(fract(5))
    • 方法二:运用递归计算阶乘
      • 经研究发现:N的阶乘等于N乘以N-1的阶乘,因此可借助于递归来实现
      • N为1时,N的阶乘是1,保证递归有结束点
def fract():    if n < 1:        print('n不能小于1')        return     # 对于递归函数来说,必须保证在某个条件下,函数不再调用自身,递归结束     elif n == 1:         return 1     else:         # 递归:就是函数里面调用自身         return fract(n - 1) * n         print(fract(5))
    • 方法三:调用reduce函数计算阶乘
      • Python在functools模块提供了reduce()函数,该函数使用指定函数对序列对象进行积累
      • 可通过help(reduce)查看该函数的用法:reduce(function, sequence[, initial])
b44878fb610ab944205056374d9f4aec.png
import functoolsdef fn(x, y):    return x * y    def fract():    if n < 1:        print('n不能小于1')        return    else:        '''        # fn(ele1, ele2)->r        # fn(r,ele3)->r        # fn(r,ele4)->r        '''        # 方法一:        return functools.reduce(fn, range(1, n + 1))                # 方法二:        # lambda x ,y: x * y 的本质就是一个函数        return functools.reduce(lambda x ,y : x * y, range(1, n + 1))print(fract(5))

第八节:案例实操-定义计算矩阵转置的函数

  • 使用循环进行转置
    • 首先创建一个长度与原矩阵第一个元素长度相等的新列表
    • 使用遍历原矩阵的每个元素,再使用嵌套循环遍历每个元素,将列表中的元素添加到新列表对应的列表元素中
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]'''# 转置就是行变列 列变行# 转置之前1  2  3  45  6  7  89 10 11 12# 转置之后1  5  92  6 103  7 114  8 12'''def printmatrix(m):    # 列表嵌套列表,因此ele也是列表    for ele in m:        # 打印一行        for e in ele:            print('%2d' % e, end=' ')     print(' ')     def transformmatrix(m) :    # m[0]有几个元素,说明原矩阵有多少列    # 列转成行    rt = [[] for i in m[0]]    for ele in m:        for i in range(len(ele)):            # rt[i]代表新矩阵的第i行            # ele[i]代表原矩阵当前行的第i列            rt[i].append(ele[i])     return rtprintmatrix(matrix)print('-' * 60)printmatrix(ransformmatrix(matrix))
  • 使用zip()函数转置
    • zip函数的作用正是合并多个序列:多个序列第一个元素合并成第一个元素,多个序列第二个元素合并成第二个元素......
    • 运用逆向函数收集即可
bd541187b1ad4637301487208678052f.png
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]def printmatrix(m):    # 列表嵌套列表,因此ele也是列表    for ele in m:        # 打印一行        for e in ele:            print('%2d' % e, end=' ')     print(' ')     def transformmatrix(m) :    # 逆向参数收集,将矩阵中多个列表转换成多个参数,传给zip    return list(zip(*m))printmatrix(matrix)print('-' * 60)printmatrix(ransformmatrix(matrix))
  • 使用numpy模块转置
    • numpy模块提供transpose函数执行转置,该函数的返回值是numpy的内置类型:array
    • 调用array的tolist()方法可将array转换成list列表
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]def printmatrix(m):    # 列表嵌套列表,因此ele也是列表    for ele in m:        # 打印一行        for e in ele:            print('%2d' % e, end=' ')     print(' ')     def transformmatrix(m) :    # 使用numpy模块的transpose函数进行转置    import numpy    return numpy.transpose(m).tolist()printmatrix(matrix)print('-' * 60)printmatrix(ransformmatrix(matrix))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

allegro大十字光标设置方法

使用大十字光标&#xff0c;在摆放元器件时&#xff0c;容易对齐。在allegro中&#xff0c;可以通过设置实现大十字光标&#xff0c;其具体方法如下&#xff1a; &#xff11;、选择Setup->User Perferences,即可出现如下图所示界面&#xff1a; &#xff12;、选择Display-…

基于.NET平台常用的框架整理(收藏)

目录 分布式缓存框架 日志记录异常处理 关于NoSQL数据库 自动任务调度框架 依赖注入IOC容器框架 常用的几个ORM框架 格式和数据类型转换 反射和动态语言 跨平台和运行时解决方案 WEB开发和设计 移动互联网和云计算 网络通信和网络协议 图形和图像处理框架 桌面应用程序框架 测试…

界址点号_界址点及四至优化

先对文中提到的面做一个解释&#xff0c;他可以指地块&#xff0c;宗地。一、界址点先说一下对界址点优化的情况&#xff0c;之前的方法主要是只要考虑了对坐标排序的问题&#xff0c;对于比较规整的面出的效果还是挺好&#xff0c;但往往现实中的面都比较复杂&#xff0c;像下…

java程序 输入10个数字并求和

课程作业&#xff1a; 模仿JavaAppArguments.java示例&#xff0c;编写编写一个程序&#xff0c;此程序从命令行接受多个数字&#xff0c;求和之后输出结果。 设计思想&#xff1a; 先从命令行读出数字&#xff0c;然后计算各个数字之和。求出结果。 流程图&#xff1a; 程序源…

是先打工还是直接创业?答案让我惊呆了!

第一问&#xff1a;成功路上&#xff0c;您是自己乱走&#xff0c;还是有老师指导更好&#xff1f;人生路上&#xff0c;因为有父母&#xff0c;才有生命&#xff1b;成功路上&#xff0c;因为有老师&#xff0c;才有方向。父母优秀&#xff0c;才可以培养出优秀的孩子。优秀的…

MVC知识点整理汇总

MVC与ASP.NET MVC基础概念MVC是Model-View-Controller的缩写.MVC将应用程序划分为3大组件:模型\视图\控制器.MVC不是ASP.NET所特有,它只是一种开发理念.java中的struts2也是一种MVC模型.ASP.NET MVC从2008年发布1.0版以来,截至2014年ASP.NET MVC最新版本已经是5.0.ASP.NET MVC从…

第三次作业——结对编程

成员&#xff1a;031302439 031302415 本次实践中我们是用phpmysql来实现所需功能的&#xff0c;其中使用到的软件有PowerDesigner和WampServer 一. PowerDesigner使用过程 1. 运行程序&#xff0c;进入主界面&#xff0c;新建一个Model&#xff0c;设置DBMS属性。我们…

NET比较常用的性能优化技巧

现在很多客户也慢慢开始注重网站的性能了&#xff0c;同时有很多运营网站的公司也不像以前那样特别在意网站是否非常漂亮&#xff0c;而把更多的精力放在了网站性能优化上面&#xff0c;提供更快更稳定的浏览速度&#xff0c;在这个基础上面进行网站功能上的扩充和完善&#xf…

js修改mysql数据库数据_Node.js操作mysql数据库增删改查

关于node.js操作mysql数据库的相关介绍请阅读全文吧。下文介绍的非常详细&#xff0c;具体内容如下所示&#xff1a;安装mysql模块npm install mysql数据库准备mysql server所在的机器IP地址是192.168.0.108&#xff0c;登录账户就用root123456在mysql中创建test数据库在test数…

Win10 注册IIs4.0的解决方案

随着Win10的出现&#xff0c;越来越多的人装上了Win10&#xff0c;尤其是程序员&#xff0c;由于Win10是一个新的操作系统&#xff0c;但现有软件的兼容性等各方面都是未知&#xff0c;难免会存在很多坑&#xff0c;就拿IIS来说&#xff0c;我刚装完win10系统&#xff0c;然后装…

DotNet 资源框架整理

目录 框架 应用模板&#xff08;Application Templates&#xff09; 人工智能&#xff08;Artificial Intelligence&#xff09; 程序集处理&#xff08;Assembly Manipulation&#xff09; 资源&#xff08;Assets&#xff09; 认证和授权&#xff08;Authentication an…

oracle9

约束 维护数据的完整性 数据的完整性用于确保数据库数据遵从一定的商业和逻辑规则&#xff08;比如年纪不能为-1&#xff0c;性别不能为非男女&#xff09;&#xff0c;在oracle中&#xff0c;数据完整性可以使用约束、触发器、应用程序&#xff08;过程、函数&#xff09;三种…

公司来了个傻员工,改变了所有聪明的员工

公司来了个新员工&#xff0c;有点土&#xff0c;但很听话。其它员工都把所有得工作堆给他做&#xff0c;新员工不介意&#xff0c;默默地帮他们都完成。主管看到他勤快&#xff0c;叫他帮忙跟着做很多事情&#xff0c;可他一点都不介意&#xff0c;可他帮主管做事都是义务的。…

mysql 交叉连接的用法_sql中内连接与外连接与交叉连接用法

文章介绍了在mysql中的内连接与外连接与交叉连接用法与举例说明了&#xff0c;有需要了解的朋友可以参考一下下。(一)内连接SQL INNER JOIN 关键字在表中存在至少一个匹配时&#xff0c;INNER JOIN 关键字返回行。内连接查询操作列出与连接条件匹配的数据行&#xff0c;它使用比…

使用JAXP对XML文档进行DOM解析

一、XML解析方式分为两种&#xff1a;dom和sax dom&#xff1a;&#xff08;Document Object Model,即文档对象模型&#xff09;是W3C组织推荐的解析XML的一种方式。sax&#xff1a;&#xff08;Simple API for XML)不是官方标准&#xff0c;但它是XML社区事实上的标准&#xf…

tfpose与openpose区别_人体姿态识别--Openpose+Tensorflow

目的复现代码完成视频中的人体姿态识别复现过程视频来源&#xff1a;https://www.youtube.com/watch?vcMhWNGBW1Xg​www.youtube.com视频动图检测结果下载的画质本来就不高&#xff0c;再加上两次录屏&#xff0c;画质比较渣。首先确认工程所需要的依赖&#xff1a;python3ten…

让 步( 写的太好了!)

一个不懂得为亲人让步&#xff0c;为朋友让步&#xff0c;为爱人让步&#xff0c;为合作伙伴让步的人&#xff0c;是缺乏胸襟的人&#xff0c;最无能和不可交的人。试问一个连自己人都斤斤计较的人可交往吗&#xff01;长不大的人最重要的标志&#xff0c;就是跟自己人&#xf…

Android学习手记(2) Activity生命周期

1. 单个Activity的生命周期 当只有一个Activity的时候&#xff0c; 首先执行onCreate->onStart->onResume。 这时&#xff0c; 窗口便显示在屏幕上了。 然后我们按返回键退到桌面的时候&#xff0c;便执行onPause->onStop。这时候&#xff0c; 如果我们在最近使用程序…

墙角的父亲(一篇让千万人潸然泪下好文)

前言&#xff1a;拥有思想的瞬间&#xff0c;是幸福的&#xff1b;拥有感受的快意&#xff0c;是幸福的&#xff1b;拥有父爱也是幸福的。帮老乡大将搬家。在整理一堆旧书籍的时候&#xff0c;大将蹲在地上呜呜大哭起来。大将打开的是一个笔记本&#xff0c;上面记着日常开支&a…

react遍历对象的值_React 原理之实现 createElement 和 render 方法

前言在 React 中&#xff0c;我们都知道可以写 jsx 代码会被编译成真正的 DOM 插入到要显示的页面上。这具体是怎么实现的&#xff0c;今天我们就自己动手做一下。实现 createElement 方法这个方法平时开发我们并不会用到&#xff0c;因为它是经 babel 编译后的代码&#xff0c…