首页 > python学习随笔(七)_函数

python学习随笔(七)_函数

函数    #作用:封装和复用

    数学定义:y=f(x) ,y是x的函数,x是自变量。y=f(x0, x1, ..., xn)

    Python函数

        由若干语句组成的语句块、函数名称、参数列表构成,它是组织代码的最小单元

        完成一定的功能



    函数的作用

        *结构化编程对代码的最基本的封装*,一般按照功能组织一段代码

        封装的目的为了复用*,减少冗余代码

        代码更加简洁美观、可读易懂

    函数的分类

        内建函数,如max()、reversed()等

        库函数,如math.ceil()等



函数定义、调用

    def语句定义函数

    def 函数名(参数列表):

        函数体(代码块)

        [return 返回值]

        函数名就是标识符*,命名要求一样

        语句块必须缩进,约定4个空格

        Python的函数没有return语句,隐式会返回一个None值

        *定义中的参数列表成为*形式参数*,只是一种符号表达,简称形参

    调用

        函数定义,只是声明了一个函数,它不会被执行,需要调用

        调用的方式,就是函数名加上小括号,括号内写上参数

        *调用时写的参数是*实际参数*,是实实在在传入的值,简称实参



定义时是形参,调用时是实参,调用加小括号



python是动态的,强类型语言

因为是动态的,参数没有定义类型,会带来很大问题(自由工业化开发会带来问题)

无法限制参数类型,除非进行判断

能不能控制这个?是解决团队的问题



函数参数

    参数调用时传入的参数要和定义的个数相匹配(可变参数例外)

    位置参数

        def f(x, y, z) 调用使用 f(1, 3, 5)#顺序对应,个数也要相同#传参,传入实参

        按照参数定义顺序传入实参

    关键字参数    #谁等于谁就是关键字传参(keyword)

        def f(x, y, z) 调用使用 f(x=1, y=3, z=5)    #顺序可以不一样,因为可以按名字找

        使用形参的名字来出入实参的方式,如果使用了形参名字,那么传参顺序就可和定义顺序不同

    传参

        f(z=None, y=10, x=[1])

        f((1,), z=6, y=4.1)

        f(y=5, z=6, 2) #位置参数必须在前,keyword在后是可以的

        要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的





函数参数默认值    #记得时候可以记带等号不可以放前面

  参数默认值(缺省值)

  定义时,在形参后跟上一个值

def add(x=4, y=5):

return x+y

测试调用 add(6, 10) 、add(6, y=7) 、add(x=5) 、add()、add(y=7)、 add(x=5, 6) #这个不可以、add(y=8,

4)、add(x=5, y=6)、add(y=5, x=6)

测试定义后面这样的函数 def add(x=4,y)#非缺省跟在非缺省后不可以(记得时候可以记带等号不可以放前面)

  作用

  参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值

  参数非常多的时候,并不需要用户每次都输入所有的参数,简化函数调用

  举例

  定义一个函数login,参数名称为host、port、username、password

函数参数默认值

 



  在形参前使用*表示该形参是可变参数,可以接收多个实参

****收集多个实参为一个tuple***





可变类型和解构类型,但不全相同(keyword-only)



def fn(*args,x,y,**kwargs)

(x,y)属于keyword-only:在后面 必须定义关键字传参

可以用缺省值,必须使用关键字传参#经常给keyword-only定义缺省值

def add(*,x,y):    #逗号标志后面的是keyword-only





***总结定义形参和传参的几种类型(定义时是形参,调用时是实参)

定义形参:,位置参数,可变位置参数(封装成元组tuple),可变关键字传参(封装成dict字典)





定义传参:位置传参,关键字传参,混着用的时候:位置传参在前,关键字传参在后



普通位置传参:位置传参和关键字传参都支持但是位置传参在前

可变参数:

    可变位置传参:不允许关键字传参,只可以写在一起让可变参数对应#add(1,2,3,4)



    可变关键字传参只收集关键字传参,不可以位置传参





位置参数往放前(可变的也要放前),关键字参数放后(记带星的放后星星放最后)



传参时对应形参必须只有一个,全是关键字传参可以不考虑顺序





函数参数

    参数规则

***参数列表参数一般顺序是,普通参数、缺省参数、可变位置参数、keyword-only参数(可带缺

省值)、可变关键字参数

模版:def fn(x, y, z=3, *arg, m=4, n, **kwargs):

print(x,y,z,m,n)

print(args)

print(kwargs)





参数解构

***只能在参数传参中运用

    传参的时候才解构,解构出元素作为实参



  非字典类型使用*解构成位置参数

****字典类型使用**解构成关键字参数

字典解构:一个*解key,**解字典

add(*{'a': 5, 'b': 6})#解构后为x = 'a',y = 'b'

#add(**{'a': 5, 'b': 6})#解构后为'a' = 5,'b' = 6



函数默认return none,如果想要函数有返回值修改return

------------------------------------------------------------------------------------------------------------------------------------

函数返回值

return 语句

一个函数只有一条return语句



多分支结构可以有多条return,但只能执行一条return

#多分支结构可以设置个变量,最后return变量,可以省着每次分支都写return

if..ret=..else..ret=..最后return ret



函数可以返回值可以不同类型

一个函数只要碰到return就立即返回终止



函数默认return none,往往函数需要写return



return返回必须是一个值,不是一个会被它封装成一个元组

返回多个值包在容器中  得到它们使用解构一一对应

---------------------------------------------------------------------------------------------------------------------------

作用域****

嵌套函数

    函数内部的函数不可以在外部单独执行#因为在外部没有定义,报NameError



    在外部的函数可以调用嵌套在内的函数



****###函数是有可见范围的,这就是作用域



函数内部的标识符(变量),外部是不可见的





函数定义直接过,执行时看前面定义有没有用到变量



函数内部

x = 5

def show():

    x += 1#报错

    print(x)

show()



x = x +1    #在函数内部要先定义,要不然会说内部没有定义

    #右边x+1,赋值即重新定义,赋值要先算右边,

    #右边是内部本地变量(本地作用域),x要重新定义



嵌套函数:赋值即重新定义,但是是定义自己的变量



全局作用域    #在整个运行环境中都可见



局部作用域(local)    #在函数和类等内部中可见



---------------------------------------------------------------------------------------------------------------------------

全局作用域(了解,写函数基本不用,改动影响太大)

global x    #使用全局作用域变量

    #尽可能放在前面第一行



global 用在局部作用域中定义一个全局作用域中操作变量

但是global只影响当前作用域



函数应该用定义形参,传参这种形式用,尽量不要用global



---------------------------------------------------------------------------------------------------------------------------



闭包***#一般在有嵌套函数时候用



自由变量:未在本地作用域中定义的变量。例如定义在内存函数外的外层函数的作用域中的变量



本来变量在外层函数  内层函数用到了这个局部变量,闭包就已经产生





nonlocal    关键字

    #声明变量不在本地作用域中,但是在外层作用域中找,但是不会再全局作用域中找

    #形成闭包

    #一层层向外找但不在全局中找

    #不可在全局下一层中用(因为全局中的下一层可以直接用全局变量了)

形参可以当局部变量来看



---------------------------------------------------------------------------------------------------------------------------



默认值的作用域



函数也是对象,如果对象中包含引用类型时,会更改默认值,简单类型不会更改默认值



函数名.__defaults__        #查看默认值属性,使用元组保存所有位置参数默认值#使用元组位置就不会变

函数名.__kwdefaults__    #查看使用字典保存所有keyword-only参数的默认值,dict是关键字传参





缺省值函数默认的特殊属性,生命周期跟函数同样周期共消亡



缺省值只有自己的作用域的,要看缺省值指的是什么,如果指的是缺省值送给形参,形参的作用域就在函数内部,它是局部作用域中的局部变量



#default这个东西它又属于函数对象本身的特殊属性,它是放在函数对象上的

#函数对象是和函数定义相关的,函数在定义时它的标识符(形参)关联到它内存中创建的那一个函数对象上去了





默认值作用域为形参用,形参可以当函数的局部变量来看

如果形参可变的类型(如列表),(无缺省值)没有固定的缺省值,有缺省值也会变的

#有时候这个特性是好的,有的时候这种特性是不好的,有副作用



def foo(xyz=[], u='abc', z=123):

    xyz.append(1)

    return xyz

print(foo(), id(foo))

print(foo.__defaults__)

print(foo(), id(foo))

print(foo.__defaults__)#引用类型默认值改变





def foo(xyz=[], u='abc', z=123):

   #xyz = foo.__defaults__

    xyz = xyz[:] # 影子拷贝,简单类型空列表内存中新生成一份,内存地址不同

    xyz.append(1)

    print(xyz)

foo()

print(foo.__defaults__)

foo()

print(foo.__defaults__)

foo([10])

print(foo.__defaults__)

foo([10,5])

print(foo.__defaults__)#不改变默认值





def foo(xyz=None, u='abc', z=123):#使用不可变类型默认值

    if xyz is None:#使用默认值时创建列表

        xyz = []

        xyz.append(1)# 如果传入一个列表,就修改这个列表

    print(xyz)

foo()

print(foo.__defaults__)

foo()

print(foo.__defaults__)

foo([10])

print(foo.__defaults__)

foo([10,5])

print(foo.__defaults__)



第一种方法

    使用影子拷贝创建一个新的对象,永远不能改变传入的参数

第二种方法

    通过值的判断就可以灵活的选择创建或者修改传入对象

    这种方式灵活,应用广泛

    很多函数的定义,都可以看到使用None这个不可变的值作为默认参数,可以说这是一种惯用法





---------------------------------------------------------------------------------------------------------------------------



变量名解析原则LEGB        #一个名词的查找顺序就是LEGB,一层一层向外解析

LEGB规定了查找一个名称的顺序为:local-->enclosing function locals-->global-->builtin



Local,本地作用域、局部作用域的local命名空间。函数调用时创

建,调用结束消亡



Enclosing,Python2.2时引入了嵌套函数,实现了闭包,这个就

是嵌套函数的外部函数的命名空间



Global,全局作用域,即一个模块的命名空间。模块被import时

创建,解释器退出时消亡



Build-in,内置模块的命名空间,生命周期从python解释器启动

时创建到解释器退出时消亡。例如 print(open),print和open都是内置的变量



---------------------------------------------------------------------------------------------------------------------------



函数的销毁

#函数的定义一般只做一次,除非你想把它覆盖掉再定义一次

#定义函数的目的就是复用,要明确为什么要销毁,不要轻易销毁



全局函数的销毁

     重新定义同名函数

    del 语句删除函数对象

    程序结束时



局部函数销毁

    重新在上级作用域定义同名函数

    del 语句删除函数名称,函数对象的引用计数减1

    上级作用域销毁时

 

--------------------------------------------------------------------------------------------------------------------------

递归函数



#栈和线程相关,栈是每个线程自己的空间

函数执行要压栈,一个落一个,函数局部变量也要压栈,用完后弹出

#局部变量,函数调用时创建,调用结束消亡



递归 Recursion

函数直接或者间接调用自身就是递归



递归一定要有退出条件 return 出一个结果

每次计算后也要return





import sys

print(sys.getrecursionlimit)    #查看递归层数



---------------------------------------------------------------------------------------------------------------------------

匿名函数



格式

    lambda 参数列表 : 表达式



map是生成一个惰性求值的



(lambda x : 0)(3)

冒号后面不可以用等号

---------------------------------------------------------------------------------------------------------------------------

生成器***

生成器generator



next()    #



生成器函数必须包含yield语句,生成器函数的函数体不会立即执行



协程    #非抢占式,轮询



yield from    #新语法从可迭代对象中一个个拿元素

for x in range(10)  =>   yield from range(10)

    yield x





转载于:https://www.cnblogs.com/springquanquan/p/9573783.html

更多相关:

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...

  • 情况一:后台给的日期是Sat Jul 31 2021 21:50:01 GMT+0800 (中国标准时间),如果直接呈现给用户,他们一定会吐槽你不说人话~~~ 情况二:后台给的百分数是小数没有转化成00%格式 采用vue的过滤机制就可以解决这种情况,有两种方式: 第一种:全局写法,在main.js里面加入 // 【...

  • 问题描述 使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。 例如:输入test.exe  -a 1 2       执行1+2输出3 问题分析 上面的逻辑思维很简单,但是问题在于如何在VS中向...

  • ------------------------siwuxie095                         MyBatis 中 #{} 和 ${} 的区别       1、在 MyBatis 的映射配置文件中,动态传递参数有两种方式:    (1)#{} 占位符    (2)${} 拼接符          2、#{} 和...

  •     #2.6 map()# 第一个参数传入一个函数,,第二个参数为一个可迭代对象li_1 = (1,3,5,7)def funcA(x): return x*xm1 = map(funcA,li_1)print(type(m1))print(m1())# 2.6 reduce()# 第一个参数传入一个函数,第二个参数 可以迭...

  • 列表,元组,字典的转换。 list列表是一组可变的元素集合 列表是'[]'括号组成的,[]括号包含所有元素,列表的创建可以传递字符串,也可以传递多个字符串来创建列表。如"asd", / "a","b" ... tuple元组的创建和列表一致,区别在于 元组是以'()'创建的,并且元组数据不可变。 dict字典不同于列表和元组,他...

  • 这里将分享我使用PCL库的遇到的一些坑,以及总结的技巧,当然也需要各位能够多多分享,将公众号的文章或者知识星球的文章转发到朋友圈。 pcl_common中主要是包含了PCL库常用的公共数据结构和方法,比如PointCloud的类和许多用于表示点,曲面,法向量,特征描述等点的类型,用于计算距离,均值以及协方差,角度转换以及几何变化的函...

  • C++中extern是指全局的意思。它一般有两个方面的用途: 1、声明变量 首先说一下声明和定义的区别: ①变量的定义:用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。 ②变量的声明:用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern...

  • 在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A {     int i;     B b; } class B {     int i;     A* a; } 请注意上面的定义内容,一般情况下是不能出现类A,类B相互引用都定义对象,即...

  •   前天在玩OLED时想完成一直想弄得一个东西,就是简单的单片机游戏。因为STM32和nRF51822的内存足够,所以就用缓存数组的方法来显示图像(我也不知道术语是啥,反正就是在内存中建立一个128X64的二维数组,更新显示时将整个数组刷新到屏幕上),而且这两个OLED是串口的(还有一个128X32的OLED,一样串口的,连驱动时序和...

  • 三、继承中容易引起的错误有时候继承也会带来些错误,比如说下面这条css定义: body{color:blue} 在有些浏览器中这句定义会使除表格之外的文本变成蓝色。从技术上来说,这是不正确的,但是它确实存在。所以我们经常需要借助于某些技巧,比如将css定义成这样: body,table,th,td{color:blue} 这样表格...