python练习生|函数三部曲——初来乍到(初识函数参数)

本文主要是介绍python练习生|函数三部曲——初来乍到(初识函数参数),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

python练习生|函数三部曲——初来乍到(初识函数&参数)

  • 一.认识对象
    • 1.对象分类
    • 2.基本应用
      • 1).可变对象
  • 二.函数
    • 1.初识函数
    • 2.函数的语法
    • 3.函数的参数
      • 1).参数的分类
    • 4.函数的传递方式
      • 1).默认值传递
      • 2). 位置传递
      • 3). 关键字传递
    • 5.函数中的对象
    • 6.不定长参数
      • 1).要点
      • 2).( *号参数)和(** 参数)举例
    • 7.参数的解包

在我们拜访函数之前,我们先要有一个认知,你认识的对象是否可变
在这里插入图片描述
不要多想,不是那个对象,而是下面我要说的对象

  • 在python领域有这样一句话:“一切皆为对象”。当然,这句话你自己知道就好了。要是面试的时候面试官问你,什么是对象?
  • 你回答:一切皆是对象,恭喜你,喜提再来一次。
    这里是引用
    还记得之前的博文有说到序列吗?一.序列
    序列其实就是一种对象
    那么,按照序列的分类,发散思维,对象也可分为可变对象和不可变对象

一.认识对象

1.对象分类

  • python中保存的数据都是围绕对象这个概念展开的
  • 对象分类:可变对象和不可变对象
  • 可变对象:例如 list,dict
  • 不可变对象:例如 int,str,tuple

2.基本应用

  • 每个对象中都保存了三个数据:内存地址(id)、对象类型(type)、值(value)

  • 有鉴于可变对象的实用性,在这里我们仅浅谈可变对象

1).可变对象

  • 我们所说的可变对象,其实就是说,对象内变量的值是可以改变的
  • 只要是在原来值的基础上进行修改,其内存地址就不会发生改变
  • 如果我们通过重新赋值改了变量,虽说也是改变了对象的值,但是其对应的内存地址也改变了
    举个栗子:
lst = [1,2,3,4]    
print(lst,type(lst),id(lst))
lst[1] = 100
print(lst,type(lst),id(lst))lst = [2,3,4,5]   #重新赋值
print(lst,type(lst),id(lst))

kebianduixaing

  • 我们可以这样理解:
lst[1] = 100
  • 这步操作是修改对象里面的值,通过对象内部修改变量来进行
  • 因此,这个操作不会改变变量指向的对象
lst = [2,3,4,5]
  • 这步操作相当于对变量进行重新赋值,相当于生成新的对象
  • 因此,这个操作会改变变量指向的对象

直白的讲:)就相当于你去看牙了,你有颗牙坏了,你去修修补补,这个牙还是你的牙(你的对象并没有变)。但是,如果你把这颗牙拔了,重新换一颗牙,那么,这个牙对于你来说,相当于是新的对象(你的对象变了)。


分割线:对象就讲到这,提前讲有助于我们后面对函数的理解


二.函数

1.初识函数

  • 函数:函数是一个功能代码块,在执行其功能时还有一个入口和出口,入口就是函数中的各种形参,出口就是实现功能的返回值
  • 函数⽤来保存⼀些可执⾏的代码,并且可以在需要时,对这些语句进⾏多次调⽤
  • 函数也是⼀个对象

2.函数的语法

 def 函数名([形参1,形参2,形参3....]):代码块

注意:

  • 函数名必须符合标识符的规范(可以包含字⺟、数字、下划线但是不能以数字开头)
  • 关于函数和标识符的相关介绍请移步:函数&标识符
  • 函数中保存的代码不会立即执行,需要调用后才会执行
def fn(a,b,c):print("a =",a)print("b =",b)print("c =",c)fn
print(fn,type(fn))
fn(1,2,3)

调用

  • 如图所示:fn是函数,而fn()则是调用函数

3.函数的参数

1).参数的分类

  • 分类:形参和实参
  • 形参(形式参数): 定义形参就相当于在函数内部声明了变量,但是并不是赋值
  • 实参(实际参数):指定了形参,在调⽤函数时必须传递实参,实参将会赋值给对应的形参,一般来说有⼏个形参就要有⼏个实参

就拿这部分代码来说

def fn(a,b,c):    #声明了三个形参,a,b,cprint("a =",a)print("b =",b)print("c =",c)fn(1,2,3)         #通过函数的调用将实参(1,2,3)传递给形参(a,b,c)

4.函数的传递方式

  • 默认值传递:定义形参时,可以为形参指定默认值。指定了默认值以后,在调用函数过程中,如果传递了参数(实参)则默认值不会⽣效。如果没有传递,则默认值就会⽣效。
  • 位置传递:位置参数就是将对应位置的实参赋值给对应位置的形参
  • 关键字传递:关键字参数可以不按照形参定义的顺序去传递,⽽根据参数名进⾏传递

1).默认值传递

def fn(a=10):     # a = 10 是默认值参数print('a = ',a)
fn()              # 没有实参的传递,则打印默认值参数
fn(3)             #  3 是实参,则,把三赋值给函数中的 形参a 默认值不打印

默认值传递
-我们把在函数fn ( a=10)中,10称之为参数的默认值,如果在调用函数fn的过程中,你没有传参进去,那么函数中形参a将被默认值赋值,并执行函数调用,输出相应结果
-如果你传参进去,则实参将付给形参,而默认值参数则失效

2). 位置传递

def  fn1(a,b,c):print('fn1函数中,a =',a)print('fn1函数中,b =',b)print('fn1函数中,c =',c)
fn1(3,4,5)

位置传递

  • 每个实参和形参都有以一一对应的关系
    如果你多传或者少传了参数,则会进行报错
    举个栗子:
def  fn1(a,b,c):print('fn1函数中,a =',a)print('fn1函数中,b =',b)print('fn1函数中,c =',c)
fn1(3,4)              # TypeError: fn1() missing 1 required positional argument: 'c'def  fn2(a,b,c):print('fn1函数中,a =',a)print('fn1函数中,b =',b)print('fn1函数中,c =',c)
fn2(3,4,5,6)          # TypeError: fn2() takes 3 positional arguments but 4 were given

bug错误

  • 从图中我们可以看出,fn1函数在进行实参赋值时,少了一个实参,系统进行报错;fn2函数在进行实参赋值时,多传了一个实参,少传了一个形参,系统依旧会报错。

3). 关键字传递

def  fn1(a,b,c):print('fn1函数中,a =',a)print('fn1函数中,b =',b)print('fn1函数中,c =',c)
fn1(3,b=1,c=4)               
  • 在参数调用中,我们把形参b,c分别赋予了详细的实际参数————称之为关键字参数的传递
    关键字传递
  • 从这写代码中,不难发现,b和c都有关键字传递,a进行位置传递
    那么,问题出现了: 我们在进行关键字传递时,可以对不同参数任意顺序排序吗? 咱们来有一码一
def  fn1(a,b,c):print('fn1函数中,a =',a)print('fn1函数中,b =',b)print('fn1函数中,c =',c)
fn1(4,b=1,5)

报错
yuansu
改进之后:
改进之后
-总结:混合使⽤位置参数和关键字参数的时候必须将位置参数写到关键字参数前⾯

5.函数中的对象

  • 代码块一:
def fn(a):a = 50print('a =',a,type(a))
b = 20
print(b)
fn(b)

对象

  • 代码块二:
def fn(a):a = 50print('a =',a,type(a),id(a))
b = 20
fn(b)
print(b,id(b))

对象更新

  • 上述代码你一定看得多了,第一个代码块是进行的是一个位置传递,第二个代码块进行的是函数内部的参数重新赋值。
  • 但是,这是不可变对象之间的传递,如果我们进行 可变对象 的传递,并在函数中对参数进行再次赋值,会是什么结果呢?
  • 代码块三
def fn(a):a[0] = 10print('a =',a,type(a),id(a))
b = [1,2,3,4]
print(b,id(b))
fn(b)
print(b,id(b))

可变对象

  • 从图中,我们可以得到的结果是,这两个变量虽然数值变了,但是所对应的(内存地址(id)),并没有变,我们之前就已经生动形象的举过修牙的例子了,要是还不能够很好理解,可以再思考思考,把思绪捋一捋。
  • 再换一种说法:以上述代码块三举例。
    我们把 列表b 的值赋值给 参数a ,也就是说,对象b和对象a对应共同的值(value),并且二者的内存地址(id)是相同的。
    只要是在原来值的基础上进行修改,其内存地址就不会发生改变
  • 我们把对象a中的变量进行修改了,虽然值改变了,但是对应的内存地址还是原来的
  • 那么我们得到的反馈是,地址没变,值变了
  • 与值相关的对象a,和列表b,定会发生变量的改变

6.不定长参数

1).要点

  • 定义函数时,有时会在形参前⾯加⼀个 * ,那么这个带有 (* 号)的形参可以获取到所有的实参,它会将所有的实参保存到⼀个元组中
  • 带(* 号)的形参只能有⼀个,可以和其他参数混合使⽤
  • (带 * 号的 形参)只能接受位置参数,不能接受关键字参数
  • (带 ** 号的 形参)可以接收其他的关键字参数,它会将这些参数统⼀保存到字典当中。字典的key就是参数的名字,字典的value就是参数的值
  • ** 形参)只有⼀个,并且必须写在所有类型参数的后⾯

2).( 号参数)和(* 参数)举例

  • 下面我们进行举例:
    *号参数:
def  fn1(a,b,*c):         print('fn1函数中,a =',a,type(a))print('fn1函数中,b =',b,type(b))print('fn1函数中,c =',c,type(c))
fn1(3,4,5,6,7)

参数

  • *c 的作用是在进行位置传参后,对于多的实参,会把他们打包成一个元组传给形参(*c)
  • 基于此,如果你善于思考,但是,你却忘了之前的要点,你可能又会诞生之前的问题
    问号1:星号参数可以有多个吗?
    问号2:星号参数可以在形参中的任意位置吗?
    问号3:星号参数可以接受任意参数吗?
  • 问号一解答:
#问号1
def  fn2(a,*b,*c):         #SyntaxError: invalid syntax(只能有一个(*参数))print('fn1函数中,a =',a,type(a))print('fn1函数中,b =',b,type(b))print('fn1函数中,c =',c,type(c))
fn2(3,4,5,6,7)

问号一

  • 问号二解答:
#问号2
def  fn3(a,*b,c):print('fn1函数中,a =',a,type(a))print('fn1函数中,b =',b,type(b))print('fn1函数中,c =',c,type(c))
fn3(3,4,5,6,7)     # TypeError: fn3() missing 1 required keyword-only argument: 'c'

问号二

  • 问号二延伸:怎么才能让我们的星号参数在形参的任意位置呢?
#问号2延伸
def  fn3(a,*b,c,d):print('fn1函数中,a =',a,type(a))print('fn1函数中,b =',b,type(b))print('fn1函数中,c =',c,type(c))print('fn1函数中,d =',d, type(d))
fn3(3,4,5,6,c=7,d=8)

问题而延伸

  • 通过代码,敏锐的你一定发现了,星号参数可以在形参中的任意位置,那么相应的,你需要在调用参数时,将星号参数后面的参数以 关键字参数的形式 进行调用。

  • 问号三解答:

#问号三
def fn4(a,c,*b):print('a =',a,type(a))print('b =',b,type(b))print('c =',c,type(c))
fn4(3,4,5,1,2)
fn4(c=3,a=4,g=5,d=1,e=2)   # TypeError: fn4() got an unexpected keyword argument 'g'

问号三

**号参数:

  • 我们进行举一反三?问题差不多,按照*号参数的问题逻辑,我们在来探讨一下 **号参数

乖乖坐着

  • 问号1:双星参数可以有多个吗?
    问号1解答:
def fn4(a,**b,**c):     #SyntaxError: invalid syntaxprint('a =', a, type(a))print('b =',b,type(b))print('c =',c,type(c))
fn4(1,2,3,4,5,76)

双星问号一
从图中,我们能够认识到 双星参数只能有一个

  • 问号2:双星参数可以在形参中的任意位置吗?
    问号2解答:
#问号二
def fn4(a,**b,c):          # SyntaxError: invalid syntaxprint('a =',a,type(a))print('b =',b,type(b))print('c =',c,type(c))
fn4(1,2,3,4,5)

问号二
双星参数只能在形参最后一个

  • 问号3:双星参数可以接受关键字参数吗?
    问号3解答:
#问号三
def fn4(a,c,**b):          print('a =',a,type(a))print('b =',b,type(b))print('c =',c,type(c))
fn4(3,4,g=5,d=1,e=2)

问号三栓性
双星参数可以接受关键字参数,且会将参数打包到字典

7.参数的解包

  • 传递实参时,也可以在序列类型的参数前添加星号,这样它会⾃动的将序列中元素依次作为参数传递
  • 要求序列中的元素的个数必须和形参的个数⼀致
def fn4(a,b,c,d):print('a =',a,type(a))print('b =',b,type(b))print('c =',c,type(c))print('c =',d,type(d))
fn4(*[1,3,4,5])

图片

这篇关于python练习生|函数三部曲——初来乍到(初识函数参数)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/328002

相关文章

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

Python包管理工具pip的升级指南

《Python包管理工具pip的升级指南》本文全面探讨Python包管理工具pip的升级策略,从基础升级方法到高级技巧,涵盖不同操作系统环境下的最佳实践,我们将深入分析pip的工作原理,介绍多种升级方... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v