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函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

python常用的正则表达式及作用

《python常用的正则表达式及作用》正则表达式是处理字符串的强大工具,Python通过re模块提供正则表达式支持,本文给大家介绍python常用的正则表达式及作用详解,感兴趣的朋友跟随小编一起看看吧... 目录python常用正则表达式及作用基本匹配模式常用正则表达式示例常用量词边界匹配分组和捕获常用re

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

python删除xml中的w:ascii属性的步骤

《python删除xml中的w:ascii属性的步骤》使用xml.etree.ElementTree删除WordXML中w:ascii属性,需注册命名空间并定位rFonts元素,通过del操作删除属... 可以使用python的XML.etree.ElementTree模块通过以下步骤删除XML中的w:as