19. 函数基础知识详解

news2024/11/14 21:19:30

1. 什么是函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。之前文章中我们已经使用过python提供的内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

2. 自定义函数

(1) 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
(2) 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
(3) 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
(4) 函数内容以冒号 : 起始,并且缩进。
(5) return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
(6) 语法格式:

def 函数名(参数列表):
    函数体
# demo
def Max(num1, num2):
    if num1 > num2:
        return num1
    else:
        return num2

print('the max value is:> ', Max(1, 4))

在这里插入图片描述

3. 参数传递

说明,如果读者接触过c/c++,那么这部分不用看,它就是相当于c/c++函数中的值传递和引用传递。
(1) 可更改(mutable)与不可更改(immutable)对象
在 python 中,str、 tuple 和 number 是不可更改的对象,而 list、dict、set则是可以修改的对象
[a]. 不可变类型
变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。说白了,就是两次a所占的内存空间是不同的

# 通过id()来获取变量a所占的内存空间, 发现两次a所占的内存空间并不是相同的, 
# 说明第2次的赋值并不是简单的对第1次的a进行了值的修改, 
# 而是重新开辟了内存空间来存储.
a = 5
print(id(a))
a = 10
print(id(a))

在这里插入图片描述

[b]. 可变类型
变量赋值 la=[1,2,3,4] 后再赋值 la[2]=222 则是将 la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
说白了,就是对同一个la进行了操作

# 这里进行la[2]的操作实际上就就是对一开始的la进行了操作,
# 操作的是同一块内存空间.
la = [1,2,3,4]
print(id(la))
la[2] = 222
print(id(la))
print(la)

在这里插入图片描述
[c]. 参数传递总结
a) 不可变类型
类似 c/c++ 中的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
实参:在函数调用时, 函数名后面括号中的参数称之为"实际参数", 简称”实参“。
形参:定义函数时函数名后面括号中的变量称为"形式参数",简称"形参"。

# 以下函数中, num称之为形参, number称之为实参.
def test(num):
	pass
number=111
test(number)
# 可以看见在调用函数前后,形参和实参指向的是同一个对象(id()相同),
# 在函数内部修改形参后,形参指向的是不同的 id.
def change(number):
    print(id(number))  # 指向的是同一个对象
    number = 10
    print(id(number))  # 一个新对象, 新的内存空间

number = 1
print(id(number))
change(number)

在这里插入图片描述

b) 可变类型
类似 c++ 中的引用传递,如 列表,字典,集合。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响。

# 我们在函数内部对传入的dict进行改变, 发现外部的dict也同步改变了, 
# 说明实参和形参都是同一个对象, 都指向同一块内存空间.
def changeDict(d):
    print(id(d))
    d['num'] = 102
    print(d)

dict = {"num": 101, "name": "Zhang"}
print(id(dict))
changeDict(dict)
print(dict)

在这里插入图片描述

4. 函数参数

(1) 必需参数
必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

# 调用test()函数, 必须传入一个参数, 否则报错
def test(str):
    pass

test()	# 调用函数时没有传入参数, 则报错

在这里插入图片描述

(2) 关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 python 解释器能够用参数名匹配参数值

# 假如我们规定函数的第1个参数是字符串类型, 第2个参数是整数类型, 
# 第三个参数是列表类型, 那么一般地, 我们在函数调用时应该按照事先
# 规定的顺序传入对象, 但是由于我们在函数调用时指定了关键字参数, 
# 所以顺序可以随意写, 因为python解释器能够用参数名匹配参数值.
def test(str, num, ls):
    print(str, num, id)

test(num=191, ls=[1,2], str="HelloWorld")

在这里插入图片描述

(3) 默认参数
调用函数时,如果没有传递参数,则会使用默认参数。

# 为参数age指定了默认值, 调用函数时, 如果没有传入第三个参数,
# 将使用默认值. 
def printStudent(num, name, age=18):
    print('student info is:>', num, name, age)

printStudent(101, 'Zhang')	# 没有指定第3个参数, 将使用默认值
printStudent(102, 'Wang', 19)	# 指定了第3个参数

在这里插入图片描述

(4) 不定长参数
在定义函数时,可能事先不确定传入函数的参数个数,此时可以用不定长参数来接收。
(a) 格式1
加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。

# 格式
def fun([formal_args,] *var_args_tuple ):
   pass
# demo
def params(arg1, *vartuple):
    print(arg1, end=", ")
    print(vartuple)		# 元组
    for item in vartuple:
    	print(item, end="、")
    
params(22)
params(10, 20, 30, 40)

在这里插入图片描述

(b) 格式2
加了两个星号 ** 的参数会以字典的形式导入

# 格式
def fun([formal_args,] **var_args_dict ):
	pass
# demo
# 因为剩余参数是以字典的形式导入的, 所以调用函数时必须将剩余参数
# 以key=value的形式进行调用, 否则报错
def Params(arg1, **var_args_dict):
    print(arg1)
    print(var_args_dict)

Params(1, num=101, name='Zhang', age=18)

在这里插入图片描述
(c) 其他
声明函数时,参数中星号 * 可以单独出现
如果单独出现星号 *则星号 * 后的参数必须用关键字传入

def sum(a, b, *, c):
	return a + b + c

# sum(1,2,3)	# error
sum(1,2,c=3)	# 正确

5. return语句

return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。
如果函数没有任何返回值,则相当于返回 None

6. 函数的嵌套

不同于c/c++,python中的函数是可以嵌套的

# 来看一个demo
def foo(factor):
    def bar(number):
        return number * factor
    return bar  # 返回一个函数
    
x = foo(2)
print("the result is:> ", x(5))
print("the result is:> ", (foo(2))(5))

在这里插入图片描述

在这里,一个函数(bar())位于另一个函数(foo())中,且外面的函数返回里面的函数。也就是返一个函数,而不是调用它。
重要的是,返回的函数能够访问其定义所在的作用域
实际上,我们称bar()这样存储其所在作用域的函数称之为 闭包

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

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

相关文章

【JUC并发编程】线程池及相关面试题 详解

【JUC并发编程】线程池及相关面试题 详解 参考资料: 第十二章 线程池原理 深入浅出Java多线程原理 两道面试题,深入线程池,连环17问 深入理解Java并发编程之线程池、工作原理、复用原理及源码分析 硬核干货:4W字从源码上分析JUC…

Java二叉树OJ题

目录1. 检查两颗树是否相同2. 另一颗树的子树3. 翻转二叉树4. 判断一颗二叉树是否是平衡二叉树4.1 时间复杂度为O(n*n)【从上而下递归】4.2 时间复杂度为O(n)【从下而上递归】5. 对称二叉树6. 二叉树的构建及遍历7. 二叉树创建字符串8. 两个指定节点的最近公共祖先8.1 指定结点…

java入门作业-DAO,读取sql数据库

DAO意思是数据库、访问、对象。有了前后端思想。 需要下载mysql,并下载链接自己设置好密码。可以在navicat等软件链接打开。 材料是jc0122.sql,里面的admin_info是要操作的表。不像上一节需要把数据库文件放到java目录里。数据库只要在本地即可。 一、…

浅析Spring的五大类注解和方法注解

简单的将bean对象存储到Spring容器中,可以使用五大类注解实现,也可以通过Bean方法注解实现。本文重点围绕这几个问题展开:1.为什么需要五大类注解?2.五大类注解之间有没有关系?3.Spring使用五大类注解生成beanName问题…

Linux常见命令 17 - 帮助命令 man,whatis,--help,info,help

目录 1. 查看命令/配置文件帮助信息 man 2. 查看简短的命令帮助信息 whatis 3. 查看简短的命令选项信息 --help 4. 另一查看命令文件帮助信息 info 5. Shell内置帮助命令 help 1. 查看命令/配置文件帮助信息 man [1] 语法:man [命令] 示例:如果想要查…

分享129个ASP源码,总有一款适合您

ASP源码 分享129个ASP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 129个ASP源码下载链接:https://pan.baidu.com/s/1dUPOSf1BudsK-bB4FnGXfQ?pwdg3ae 提取码&#x…

黑马2021-8Vue自学笔记hm

黑马2021-8Vue教程学习笔记 文章目录黑马2021-8Vue教程学习笔记代码和笔记不断更新gitee代码仓库地址备用前端gei忽略提交文件webpack的使用初始化包管理配置文件 package.json下载webpack解决问题dependencies 和 devDependencies区别:在项目中配置webpackWebpack 中的默认约定…

python基础——列表推导式

python基础——列表推导式 文章目录python基础——列表推导式一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤一、实验目的 掌握Python数据结构:列表推导式的用法。 二、实验原理 列表推导式(list comprehension)列表推导式…

【Python百日进阶-Web开发-Linux】Day235 - Win11的WSL2中安装Docker

文章目录一、Docker是什么二、Win11安装Docker2.1 官网下载2.2 系统要求🔗2.2.1 WSL 2 后端2.2.2 Hyper-V 后端和 Windows 容器2.2.3 关于 Windows 容器2.3 在 Windows 上安装 Docker Desktop2.3.1 交互式安装2.3.2 从命令行安装2.4 启动 Docker 桌面三、WSL2的Ubun…

ConcurrentHashMap的死循环问题

文章目录前言1. 情景复现2. 源码解析3. 代码调试4. 原因5. 解决前言 对于ConcurrentHashMap来说,能保证多线程下的安全问题,但是在JDK1.8中还是会出现一个bug,就是computeIfAbsent,下面就来详细说说死循环的原因 1. 情景复现 首…

进阶C语言 第二章-------《进阶指针》 (指针数组、数组指针、函数指针、回调指针)知识点+基本练习题+深入细节+通俗易懂+完整思维导图+建议收藏

绪论 书接上回,通过对数据类型进阶的认识,你肯定对各种数据类型在内存中如何存储有了了解。虽然说,这方面可能对你的编程能力没什么进步。但是,他是一本内功秘籍,当我们遇到了这方面的问题时我们可以知道可能是哪一方面…

使用 Grafana 请求API接口

目的: 使用Grafana 配合JSON API 插件 请求API接口,完成可视化,实现一些简单的请求功能 假设我们想将如下的API接口返回的json数据可视化 这里借用一下 小熊同学的 金融数据接口 用请求如下接口举例 https://api.doctorxiong.club/v1/fund/detail?code000001&startDat…

色环电容读数方法要点总结

🏡《电子元器件学习目录》 目录 1,概述2,读数方法3,颜色对照表3.1,颜色与电容值数字对照关系表3.2,颜色与10的指数数字对照关系表3.3,颜色与误差对照关系表4,总结1,概述 本文简单介绍色环电容的读数方法。 2,读数方法 如下图所示色环电容共有四个色环。最粗的被命名…

36.Isaac教程--复合消息

复合消息 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录复合消息测量类型使用复合消息的示例手臂关节速度基本轨迹命令手臂关节和末端执行器命令CompositeMetric 和 CompositeAtlas组件使用 CompositeMetric 计算距离在 Python 脚本中创…

使用bookdown构建新年日记本

简介 一年多前在 B 站发布了一个视频,预览了一下基于 bookdown 构建的日记本。本打算之后更个文字版本教程。结果一直忘了,最近通过一位读者的了解,打算把这个坑补上。 本文内容将展示如何使用 bookdown 模板并修改成自己的日记本。此外&…

某阿里员工提问:年终绩效自己给自己打3.25,会有什么后果?网友回答:必死无疑,不要犯傻!...

年底评绩效,大多数人都会给自己打高绩效,但有些人却反其道而行之。最近,一位阿里员工提出了这样的问题:自评绩效时给自己打3.25,会有什么后果?希望领导能不按常理出牌,给自己3.75。有人问&#…

HashMap1.7中的线程安全问题

文章目录前言正文前言 下面聊聊JDK1.7HashMap的死循环问题,在这之前首先要知道JDK1.7的HashMap底层是数组 链表的形式的 正文 下面给出JDK1.7的扩容代码 //扩容代码 void resize(int newCapacity) {//旧的数组Entry[] oldTable table;//旧的数组长度int oldCap…

SpringBoot+Vue--引入Element-UI创建首页-笔记2

关于Vue项目目录结构介绍 https://tiantian.blog.csdn.net/article/details/128666429?spm1001.2014.3001.5502 先安装引入Element-UI Element - The worlds most popular Vue UI framework i是install的缩写 安装完成后,可以看到package.json里已经引入 在main.js里引入…

linux系统的结构

Linux系统一般有4个主要部分:内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。内核内核是操作系统的核心,具有很多最基本功能,它负责管理系…

Java基础之《netty(31)—用netty实现RPC》

一、需求说明 1、dubbo底层使用了netty作为网络通讯框架,要求使用netty实现一个简单的RPC框架。 2、模仿dubbo,消费者和提供者约定接口和协议,消费者远程调用提供者的服务,提供者返回一个字符串,消费者打印提供者返回…