Python学习笔记——函数

news2024/11/24 19:08:32
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。能提高应用的模块性,和代码的重复利用率。

定义函数

定义函数使用关键字def,后接函数名,再后接放在圆括号()中的可选参数列表,最后是冒号。

函数的组成:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()

  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。

  • 函数内容以冒号 : 起始,并且缩进。

  • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。

函数的参数

形参,是从函数的角度来说的。实参,是从调用的角度来说的。在调用时传入的参数就是实参。

传递实参

向函数传递实参的方式很多,可使用位置实参,这要求实参的顺序与形参的顺序相同;也可使用关键字实参,其中每个实参都由变量名和值组成;还可使用列表和字典。

位置实参

你调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。

位置实参的顺序很重要:使用位置实参来调用函数时,如果实参的顺序不正确,结果可能出乎意料。

关键字实参

关键字实参是传递给函数的名称 — 值对。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

def describe_pet(animal_type, pet_name):
    """显示宠物的信息"""
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(animal_type='hamster', pet_name='harry')

注意 使用关键字实参时,务必准确地指定函数定义中的形参名。

默认参数

编写函数时,可给每个形参指定默认值。调用函数时,如果没有传递参数,则会使用默认参数。

def describe_pet(pet_name, animal_type='dog'):
    """显示宠物的信息"""
    print("\nI have a " + animal_type + ".")
    print("My " + animal_type + "'s name is " + pet_name.title() + ".")

describe_pet(pet_name='willie')    #调用函数时使用默认值

注意 使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参。这让Python依然能够正确地解读位置实参。

不定长参数

  1. 通过元组或列表的解包参数的方式,定义参数与调用方式:fun(*参数)

这种定义方式只有一个形参,当被调用时,形参会被定义为一个元组。传入的实参都是这个元组类型的形参的元素。在函数体中,可以通过访问形参中的元素来获取传入的实参。

(1)函数的调用:传入任意多的实参

def recoder(*person):                        #定义一个函数,形参person的类型为元组
    print('姓名:', person[0],'年纪:', person[1] )    #函数的内容为一句代码,实现将指定内容输出

recoder("Gary", "32")                        #调用函数,传入两个参数。输出“姓名:Gary年纪:32”

注意:

  • 这种方式无法通过指定形参名称来传入实参,而且传入的实参顺序与形参内部元素的顺必须一一对应;

  • 因为接收参数的类型是元组,所以,用这种方式传值后不能对形参内容进行修改。

( 2)函数的调用:传入列表或元组

Mylist  =  ["Gary", "32"]
#调用时传入的*Mylist是一个列表的类型前面加个星号。
recoder (*Mylist)                        #调用函数, 传入list作为实参。输出:姓名:Gary年纪:32

  1. 通过字典的解包参数方式, 定义参数与调用方式:fun(**参数)

这种方式是将形参当成一个字典类型变量来接收实参。这样传入的实参和对应的名字就可以放到这个字典里。形参为字典中元素的key, 实参为字典中元素的value。

def recoder(**person):                        #定义一个函数,形参person的类型为元组
    print('姓名:', person['name'],'年纪:', person['age'] )    

recoder(age=32 , name ="Gary")             #指定形参名称调用函数。输出“姓名:Gary年纪:32”

Mydic  = {"name":"Gary","age":32}
recoder(**Mydic)                            #调用时, 还可以直接将字典传入。

函数的属性

文档字符串

在函数体中,常会在开始位置放置一个行字符串,用来说明函数的功能及调用方法。这个字符串叫作函数的文档字符串(docstring),可以使用代码print(函数名._doc_)将其输出。而_doc_则为函数的属性,并且这个属性可修改。

def  getrecoder():                        #定义一个函数
    '''该函数是返回用户名字和年龄'''
    name  =’ Gary  ’
    age  =  32
    return  name, age        

print(getrecoder._doc_)                   #输出文档字符串:该函数是返回用户名字和年龄
getrecoder._doc_="新文档字符串"            #修改函数的_doc_属性
print(getrecoder . _doc_)                 #打印文档字符串,输出:新文档字符串

类似这样的功能,在定义函数的同时,还可以为函数添加自定义属性。每个函数都有个默认的字典_dict_,用于放置函数的属性。

def recoder(strname,*,age):                    #定义一个函数
    print('姓名:',strname,'年纪:',age)        #函数的内容

print(recoder._dict_)                          #函数没有任何属性,_dict_为空,输出:{}
recoder.attr="person"                          #为函数添加属性attr
print(recoder._dict_)                          #输出:{'attr':'person'}
print(recoder.attr)                            #直接取出属性值,输出:person

直接在函数名后面加个点,就可以在后面直接添加属性;获取该属性时,也同样是在该函名后面加个点,再跟上函数的具体属性名。这种方式可以在使用函数时传递更多的信息。

函数的本质

函数的本质时对象,可以被调用的函数,都会继承可调用的方法call,使用函数callable可以检查函数是否被调用。

def recoder(strname,*,age):                    #定义一个函数
    print('姓名:',strname,'年纪:',age)        #函数的内容

print(callable(recoder))                   #函数是否被调用:输出:True

函数的分类

  1. 从用户角度

  • 内置函数:Python内部自带的函数

  • 自定义函数:用户自己编写的函数

  1. 从功能角度

  • 生成器函数

  • 一般函数

  1. 从形式角度

  • 普通函数:使用def定义

  • 匿名函数:使用lambda关键字来定义

  • 可迭代函数:一种循环迭代功能的内置函数

  • 递归函数

  • 偏函数:使用partial关键字定义

在函数调用中检查参数

在函数调用中,默认是不检查参数的类型的,通过使用isinstance函数可以对参数进行检查。

isinstance(obj , class_or_tuple)

  • 第一个参数obj:传入待检查的具体对象。

  • 第二个参数class_or_tuple:待检查的具体类型, 可以是个类或者元组。

确切的说, 该函数的功能是检查obj是否为class_or_tuple的一个实例。

在使用的过程中, 直接在函数体的开始部分使用isinstance判断一下参数即可。isinstance的第一参数传入带判断的形参;第二个参数就是合法的类型。

def recoder(strname,age):                    #定义一个函数recoder
    if not isinstance(age,(int,str)):       #对参数类型进行检查, 合法的类型为int和str
        raise TypeError('bad operand type')  #如采类型错误, 使用raise函数进行报错
    print('姓名:', strname, '年纪:', age)   
 
recoder("Gary", age=32.2)                      #调用时传入了age为float类型

函数调用中的参数传递及影响

函数调用时, 实参传递到形参的过程中有两种情况一一传值和传用。
  • 对于不可变对象, 函数调用时, 是传值。意味着函数体里可以使用实参的值, 但不能改变实参。

  • 对于可变对象, 函数调用时, 是传引用。意味着在函数体里还可以对实参进行修改。

匿名函数与可迭代函数

匿名函数一般适用于单行代码函数。
匿名函数的作用是, 把某一简单功能的代码封装起来, 让整体代码更规整一些。一般只调用一次不再需要, 所以名字也省略了, 于是变成了匿名函数。

匿名函数是以关键宇lambda开始的, 它的写法如下:

Lambda参数1, 参数2...:表达式

上面的写法中, 表达式的内容只能是一句话的函数, 而且不能存在return关键字。

可迭代函数就是一种有循环迭代功能的内置函数,包括reduce、map和filter等。

匿名函数与reduce函数的组合应用

reduce函数本质上也可以算作一个内嵌循环的函数。
reduce函数一般用于归并性任务。

reduce函数的能是按照参数sequence中的元素顺序, 来依次调用函数function, 并且每次调用都会向其传入两个参数:一个是sequence序列中的当前元素, 另一个是sequence序列中上一个元素在函数function中的返回值。

reduce( function, sequence, [initial])

  • function:要回调的函数。

  • sequence:一个“序列”类型的数据。

  • 第三个参数可选, 是一个初始值。

使用reduce函数与匿名函数的结合写法, 来实现求l~100的和:

from functools import reduce                     #导入reduce函数

print(reduce(lambda x, y:x+y, range(l,101)))    #第一个参数是个匿名函数, 实现两个数相加, 输出:5050

匿名函数与map数的组合应用

map函数的功能是:将参数sequence内部的元素作为参数, 并按照sequence序列的顺序, 依次调用回调函数function。
map函数一般用于映射性任务

map(function, sequence[, sequence, ……])

  • function:要回调的函数。

  • sequence:一个或多个“序列”类型的数据。

该函数返回值为一个map对象。在使用时, 得用list或tuple等函数进行转化。

1、使用map函数处理一个序列数据

当map后面直接跟一个序列数据时, 直接将该序列数据中的元素作为参数, 依次传入前面的函数。例如:

t = map(lambda x: x ** 2, [1,2,3,4,5])        #使用map函数, 对列表[1,2,3,4,5]的元素求平方值。返回值赋给t
print(list(t))                                #将t转成列表类型, 并打印。输出:[1,4,9,16,25]

2、使用map函数处理多个序列数据

当map后面直接跟多个序列数据时, 处理函数的参数个数要与序列数据的个数相同。

运行时, map内部依次提取每个序列数据中的元素, 一放到所提供的处理函数中, 直到循环遍历完最短的那个序列。例如:

t = map(lambda x,y: x + y, [1,2,3,4,5],[1,2,4,5])        #遍历最小的列表[1,2,4,5],实现两个列表的元素相加
print(list(t))                                #将t转成列表类型, 并打印。输出:[2,4,7,9]

匿名函数与filter函数的组合应用

filter函数的功能是对指定序列进行过滤。
fliter函数一般用于过滤性任务。

filter函数的定义

filter函数有两个输入参数:一个是filter的处理函数, 另一个是待处理的序列对象。在运行时, filter函数会把序列对象中的元素依次放到filter的处理函数中。如果返回True, 就留下, 反之就舍去。

其定义如:filter(function or None, sequence)

  • function:为filter的处理函数, 在filt町的内部以回调的方式被调用。返回布尔型。意味着某元素否要留下。

  • sequence:一个或多个“序列”类型的数据。

filter函数的使用

filter函数的返回值是一个filter类型, 需要将其转成列表或元组等序列才可以使用。例如:

t=filter(lambda x:X%2==0,[1,2,3,4,5,6,7,8,9,10])    #筛选出一个列表中为偶数的元素
print(list(t))                    #转成列表, 并打印。输出[2,4,6,8,10]

如果filter的处理函数为None, 则返回结果和sequence参数相同。例如:

t=filter(None,(1,2,3,4,5,6,7,8,9,10])    #过滤一个列表中为偶数的元素
print(list(t))                              #转成列表, 并打印。输出【1,2,3,4,5,6,7,8,9,10]

当fliter的处理函数为None时, 返回的元素与原序列一样。从功能上来说, 没有什么意义;从代码框架的角度来说, 会更有扩展性。当处理函数的输入是变量时, 则可以把filter函数的调用部分代码固定下来。为处理函数变量值不同的过滤函数, 以实现不同的处理功能。

可迭代函数的返回值

每个可选代函数返回的值都属于一个生成器对象。

生成器对象会有一个_next_方法。调用该方法可以取到内部的各个值。最终_next_通过Stoplteration异常来停止迭代。

#过滤列表中能被4整除的元素 返回4、8
t=filter  (lambda  x:x %4==0 ,  [l,  2,  3,  4, 5, 6, 7, 8,  9,  10])
print(t._next_())                #使用_next_()方法获取元素,输出:4
print(t._next_())                #使用_next_()方法获取元素,输出:8
print(t._next_())                #已经没有元素,返回Stoplteration

生成器对象与迭代器对象的主要区别在于:生成器对象只能选代一次而选代器对象可以法代多次。所以, 对可选代函数的结果只能取一次, 无法再次提取。这一点一定要注意。

偏函数

偏函数是对原始函数的二次封装, 它是属于寄生在原始函数上的函数。偏函数可以理解为重新定义一个函数, 向原始函数添加默认参数。有点像面向对象中的父类与子类的关系。

偏函数的定义:partial(func , *args, **keywords)

  • func:要封装的原函数;

  • 第二个参数为一个元组或列表的解包参数:代表传入原函数的默认值(可以不指定参数名)

  • 第三个参数为一个字典的解包参数:代表传入原函数的默认值(指定参数名)。

偏函数的作用是, 为其原函数指定一些默认的参数。调用该偏函数, 就相当于调用了原函数, 同时将默认的参数传入。在使用partial前, 必须引入functools模块

偏函数的使用:

from  functools  import  partial

def  recoder(strname , age):
    print('姓名:', strname, '年纪:', age) 

Garyfun  =  partial(recoder ,  strname ="Gary")        #定义一个偏函数
Garyfun(age  =  32)                                    #调用偏函数,输出“姓名:Gary年纪:32“

偏函数的本质是, 将函数式编程、默认参数和冗余参数结合在一起。通过偏函数传入的参数调用关系, 与正常函数的参数调用关系是一致的。

偏函数通过将任意数量(顺序)的参数, 转化为另一个带有剩余参数的函数对象, 从而实现了截取函数功能(偏向〉的效果在实际应用中, 可以使用一个原函数, 然后将其封装多个偏函数, 在调用函数时全部调用偏函数。这样的代码可读性提升了很多。

生成器函数

生成器与迭代器区别:

  • 迭代器是所有的内容都在内存里, 使用next函数来依次往下遍历。

  • 生成器不会把内容放到内存里, 每次调用next函数时, 返回的都是本次计算出来的那个元素, 用完之后立刻销毁。

整个序列占用内存特别大时, 使用生成器对象会节约内存;当系统的运算资源不足时, 使用迭代器对象会节约运算资源。

生器函数(Generator)是一种特殊的函数, 是用来创建生成器对象的工具。生成器函数使用yield语句返回, 返回值是一个生成器对象。
def  Reverse(data} :                #定义一个函数实现字符串反转
    for  idx  in  range(len(data)-1 , - 1,  -1) :
        yield  data [ idx ]          #使用yield返回具体的一个元素

for  c  in  Reverse('Python'):
    print(c,  end = ' ')            #输出 n o h t y P

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

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

相关文章

P1036 [NOIP2002 普及组] 选数————C++

题目 [NOIP2002 普及组] 选数 题目描述 已知 nnn 个整数 x1,x2,⋯,xnx_1,x_2,\cdots,x_nx1​,x2​,⋯,xn​&#xff0c;以及 111 个整数 kkk&#xff08;k<nk<nk<n&#xff09;。从 nnn 个整数中任选 kkk 个整数相加&#xff0c;可分别得到一系列的和。例如当 n4n4…

支持ITIL的IT帮助台

什么是ITIL 信息技术基础架构库 &#xff08;ITIL&#xff09; 是一套集成的最佳实践&#xff0c;旨在帮助企业向客户提供 IT 服务。ITIL是由中央设计的广泛采用的框架 计算机和电信局&#xff08;CCTA&#xff09;&#xff0c;英国的政府机构;它目前由AXELOS Ltd拥有。 ITIL…

【微信小程序】实用教程03-自定义底部导航(含自定义tabBar导航高亮需点击两次的解决方案)

开始前&#xff0c;请先完成底部导航的开发&#xff0c;详见 【微信小程序】实用教程01-注册登录账号&#xff0c;获取 AppID、下载安装开发工具、创建项目、上传体验 显然&#xff0c;纯文字的底部导航有点low&#xff0c;还是需要有图标的才酷&#xff0c;下面我们一起来实…

python的numpy的用法总结

本文总结Numpy的用法&#xff0c;建议先学习python的container 基础。numpy可以理解列表或数组。一个numpy数组是一个由不同数值组成的网格。网格中的数据都是同一种数据类型&#xff0c;可以通过非负整型数的元组来访问。维度的数量被称为数组的阶&#xff0c;数组的大小是一个…

五个了解自己天赋优势的分析工具(五)PDP性格测试

PDP性格测试 PDP的全称是Professional Dyna-Metric Programs⾏为特质动态衡量系统&#xff0c;它是⼀个⽤来衡量个⼈的⾏为特质、活⼒、动能、压⼒、精⼒及能量变动情况的系统。 PDP根据⼈的天⽣特质&#xff0c;将⼈群分为五种类型&#xff0c;包括&#xff1a;⽀配型、外向型…

项目部署 koa项目 (后端)

当你用node koa写好项目后&#xff0c;把它部署到服务器上使用 首先&#xff0c;你要买台服务器&#xff0c;链接到你的服务器上&#xff08;我前面部署前端项目有写&#xff0c;你可以参考&#xff09; 安装node 因为我们是node项目&#xff0c;所以先安装node dnf instal…

学习记录662@项目管理之项目整体管理

什么是项目整体管理 整体管理就是要决定在什么时间把工作量分配到相应的资源上&#xff0c;有哪些潜在的问题并在其出现问题之前积极处理&#xff0c;以及协调各项工作使项目整体上取得一个好的结果。项目整体管理包括选择资源分配方案、平衡相互竞争的目标和方案&#xff0c;…

LiveGBS流媒体平台GB/T28181功能-支持GB35114接入海康大华华为设备通过GB35114国标流媒体平台

LiveGBS流媒体平台GB/T28181功能-支持GB35114接入国标流媒体平台接入说明1、LiveNVR通过GB35114接入LiveGBS1.1、开启LiveGBS 35114功能1.2、 获取设备端证书给平台1.3、LiveGBS白名单中添加需要接入的国密设备1.4、导出LiveGBS平台端证书给设备&#xff08;双向认证需要&#…

嵌入式Linux-进程中常用的函数调用

1. execve()函数 系统调用 execve()可以将新程序加载到某一进程的内存空间&#xff0c;通过调用 execve()函数将一个外部的可执行文件加载到进程的内存空间运行&#xff0c;使用新的程序替换旧的程序&#xff0c;而进程的栈、数据、以及堆数据会被新程序的相应部件所替换&…

W13Scan 漏洞扫描器之XSS插件模块编写示例

一、背景 上周将W13Scan目录结构整理了一番&#xff0c;觉得要深入研究还得从代码层&#xff0c;于是尝试编写一下插件&#xff1b;框架本身已经集成了XSS扫描插件&#xff1b; 本篇文章的XSS插件的编写单纯是为了学习这个框架&#xff0c;所以只支持GET型&#xff0c;了解插…

一文解析企业网盘 带你寻找数据协作的“满分答案”

数据量急剧增长&#xff0c;线上办公逐渐成为常态。许多企业都会选择部署企业网盘来满足日益增长的数据管理与数据协作的需求。网盘市场乱花渐欲迷人眼&#xff0c;企业又该如何从中甄别最适合自己的企业网盘&#xff1f; 网盘&#xff0c;企业的数字基建 飞速发展的科技让企业…

[GIT] GIT拆分仓库--不丢git提交历史记录

背景 如果你的代码仓库里有多个目录&#xff0c;你想把其中一个目录拆分出去变成一个独立的代码仓库。重要的一点是拆分的过程中要保留git提交历史记录。 拆分步骤 1. 检查一下你的 repo 的根目录中。 进入根目录后&#xff0c;快速运行 ls 终端命令以确保列出所有子目录。…

ruoyi-vue版本框架(二)源码目录结构的讲解,与底层子项目的讲解

目录1 目录介绍2 ruoyi-common 子项目3 ruoyi-system 子项目4 配置文件5 ruoyi-framework6 数据库表7 druid 监控1 目录介绍 下载下来源码&#xff0c;后端一共有6个模块 其中 rouyi-admin这个子项目是整个若依框架的web项目&#xff0c;也就是我们要启动的后台就是这个子项目…

Django 第五章RESTFramework(DRF)框架初探以及认识serializers序列化器的增删改查

定义 Django REST framework (简称 DRF) 是一个强大灵活的wb api工具 功能完善&#xff0c;可快速开发api平台 官网地址 https://www.django-rest-framework.org/安装要求 pip3 install django3.2 pip3 install djangorestframework1.0 使用drf实现用户的增删改查 1.创建ap…

influxdb问题: unable to create database ‘mydb‘ 与 failed to send metrics to influx

[influx-metrics-publisher] ERROR i.m.i.InfluxMeterRegistry - [createDatabaseIfNecessary,117] - unable to create database mydb&#xff1b; [influx-metrics-publisher] ERROR i.m.i.InfluxMeterRegistry - [publish,161] - failed to send metrics to influx现象解决方…

Spring REST风格

REST&#xff08;Representational State Transfer&#xff09;&#xff0c;表现形式状态转换,它是一种软件架构风格。 当我们想要表示一个网络资源时&#xff0c;传统方式通常是用一个请求url表示一个操作。这样既不方便&#xff0c;也不安全&#xff0c;因为操作对于用户是透…

精要速览 | PacBio三代全长扩增子测序的多方向研究应用进展

随着测序技术的不断发展&#xff0c;组学研究愈加深入。在微生态研究领域&#xff0c;受限于二代测序读长的扩增子测序技术&#xff0c;迎来了“解放式”全面发展优化的三代测序时代——PacBio全长扩增子测序的优势逐渐显现&#xff1a;凭借其超长读长&#xff0c;高准确率&…

独立产品灵感周刊 DecoHack #044 - 新的一年如何管理你的时间

本周刊记录有趣好玩的独立产品设计开发相关内容&#xff0c;每周发布&#xff0c;往期内容同样精彩&#xff0c;感兴趣的伙伴可以点击订阅我的周刊。为保证每期都能收到&#xff0c;建议邮件订阅。欢迎通过 Twitter 私信推荐或投稿。本周看到了很多时间管理的工具类型产品&…

力扣中SQL刷题

小知识点 取余数&#xff1a;mod(数,2) 取第一个字母&#xff1a;left(name,1) 或者name like ‘M%’ 196. 删除重复的电子邮箱 题型&#xff1a;删除列A中重复的记录&#xff0c;指保留列B最小的那一行记录 答案&#xff1a;delete t1 from 表名 t1,表名 t2 where t1.列At2…

测试——自动化测试(Selenium工具)

目录 一、自动化测试的概念以及分类 二、Selenium—web自动化测试工具 1、自动化测试的一些前置工作 2、第一个自动化实例 3、总结​编辑 三、 Selenium常用方法 定位元素的方法 元素的操作 等待 强制等待&#xff08;待补充&#xff09; 隐式等待&#xff08;待补充&…