数学函数
函数是什么
传统函数的定义:给定一个集合A,假设其中的元素为x,现对A中的元素x实加对应法则f,记作f(x),得到另一个数集B。假设B中的元素为y,则x和y直接的等量关系可以用y=f(x)表示,我们把这个关系式就叫函数关系式。
近代函数的定义:设A,B是非空的数集如果按照某种确定的对应关系f,使对于集合A中任意一个数x,在集合B中有唯一确定的数y和它对应,那么就称映射f:A-B为集合A到B的一个函数y=f(x)
数学模型
由此图可知,y就是x的函数,x就是自变量参数,给定一个x就能算出一个y,因此设定一个函数关系后,就可以形成一个图像,只要给定x就能求出y,在做数学计算题时就可以无需每次寻找关系,直接按照函数关系对于求值即可。
函数公共属性
- 某一函数,其本质就是某一对应法则,就是一个对象,集合A是自变量集合,经过对应法则后,对应B集合中唯一值;
- 集合A,B是两个非空的数集
- A中元素不能剩,B中的元素可以剩
- f是一对一或者多对一的关系
- f:A————>B,具有方向性
- 关键词”任意一个想”和”唯一确定的数f(x)”
函数表示方法
函数引入
1.已知函数f(x)=2x³+x,
求:f(2)的值和f(a)+f(-a)的值
解:f(2)=2*2³+2=18
f(a)+f(-a)=2*a³+a +2*(-a³)-a=0
如上每一个函数都是具体一个函数对象,其中x为形参,其中x∈集合A,只在集合中生效,在计算机中称之为本地变量。而f(2)是给函数传递实参,传递不同的参数得到不同的集合B。
2.某种笔记本的单价是2元,买x(x∈{1,2,3,4,5})个笔记本需要y元,试用三种表示法表示函数y=f(x)
解析法
解:y=2x x∈{1,2,3,4,5}
列表法
图形法
函数总结
- 根据如上两个函数可知,每个函数除了具有函数通有的特性外,每个函数都有自己的特性和自己的图像
- 将函数放在程序中,即需要不同功能的y值就得调用不同的函数对象,每个函数都是一个独立的对象
- 将函数放在程序中,函数的形参就像定义数学函数时定义x一样是形式上的参数,函数的形参也是函数的本地变量
- 将函数放在程序中,函数的默认值参数值就是函数defaults属性中的一个元组,默认值就是位置参数中的特殊化的一种形式用元组保存在函数属性中
- 将函数放在程序中,y=2x,y=3x其中x是同一个x吗?肯定不是同一个x,因此函数中x也有作用域的范围,x是本地变量,也就是说在本函数内有效,若出本函数后,此时本地变量在其他函数中无法生效,因此在函数嵌套子函数时,对于变量有本地变量的限制
函数的作用
和数学函数模型一致,功能类似,具体作用如下
- 结构化编程对代码的最基本的封装,一般按照功能组织一段代码
- 封装的目的为了复用,减少冗余代码
- 代码更加简洁美观,可读易懂
函数的定义和调用
函数定义
def 函数名(参数列表):
函数体(代码块)
[return 返回值]
- 函数名就是标识符,命名要求一样
- 语句块必须缩进,约定4个空格
- python的函数没有return语句,隐式会返回一个None值
- 定义中的参数列表形成一个形式参数,只是一种符号表达,简称形参
函数调用
- 函数定义,只是声明了一个函数,它不会被执行,需要调用
- 数学函数调用时,必须给传入一个实参,如y=f(2),f就是函数名,2就是实参,()表示要传入的参数,因此在程序中也一样,必须要加(),至于实参可有可无
- 调用时写的参数是实际参数,是实实在在传入的值,简称实参
函数形参定义
形参位置参数
- def f(x,y,z),此时就定义了位置参数,就是普通函数中的最为普通的常见的参数形式就是位置参数
形参默认值参数
- def f(x,y,z=10),此时就定义了形参的默认值z=10,而且函数将此默认值以tuple的形式保存在函数对象属性的__defaults__之中
- 形参的默认值本质也是位置参数的特殊使用形式,本质也是位置参数,仅在位置参数的基础之上赋予默认值而言
- 给带有默认值的参数传参时,也可以通过位置参数传参或者关键字参数传参
代码测试:
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def f(x,y,z=10):
sumnum = x+y+z
return sumnum
sumn = f(1,2) #默认值传参
print(sumn)
summ = f(1,2,3) #位置参数传参方式
print(summ)
sumnm = f(1,2,z=4) #关键字传参方式
print(sumnm)
运行结果:
[python@centos7 412]$./test.py
13
6
7
形参位置可变参数
位置可变参数诞生由来
可变参数问题1: 如果实参是100个,实现这100个数求和
代码测试:
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def f(nums):
sumnum = 0
for i in nums:
sumnum += i
return sumnum
sumn = [x for x in range(1,101)]
print(f(sumn))
summ = f(1,2,3)
print(summ)
运行结果:
5050
Traceback (most recent call last):
File "./test.py", line 12, in <module>
summ = f(1,2,3)
TypeError: f() takes 1 positional argument but 3 were given
说明默认一个位置形参只能接收一个实参,所以list接收了,f(1,2,3)无法接收,报错为给定参数过多,函数体都无法进入
位置可变参数带来的问题
可变参数问题2
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def f(*nums):
sumnum = 0
for i in nums:
sumnum += i
return sumnum
summ = f(1,2,3) #多个参数进入封装成tuple可以执行
print(summ)
sumn = [x for x in range(1,101)] #一个参数list无法再次封装tuple,报错
print(f(sumn))
运行结果:
6
Traceback (most recent call last):
File "./test.py", line 12, in <module>
print(f(sumn))
File "./test.py", line 7, in f
sumnum += i
TypeError: unsupported operand type(s) for +=: 'int' and 'list'
位置可变参数正确用法
可变参数问题3
#!/home/python/.pyenv/versions/3.5.3/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def f(*nums):
sumnum = 0
print(type(nums))
for i in nums:
sumnum += i
return sumnum
summ = f(1,2,3)
print(summ)
sumn = [x for x in range(1,101)]
print(f(*sumn)) #将list解构为一个个数字,然后再封装为tuple
运行结果:
<class 'tuple'>
6
<class 'tuple'>
5050
位置可变参数总结
- 一个形参可以匹配任意个参数
- 在形参前使用*表示该形参是可变参数,可以接收多个实参
- 收集多个实参为一个tuple
位置可变关键字参数
普通位置可变关键字参数
- 形参前使用**符合,表示可以接收多个关键字参数
- 收集的实参名称和值组成一个字典
代码示范
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def showconfig(**kwargs):
for k,v in kwargs.items():
print('{}={}'.format(k,v))
print(showconfig(host='127.0.0.1',port='8080',username='weibo',password='123456'))
运行结果:
[python@centos7 412]$./testkwargs.py
username=weibo
host=127.0.0.1
password=123456
port=8080
None
特殊位置关键词参数
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def showconfig(*,x):
print(x)
print(showconfig(x=1))
位置参数keyword-only参数
keyword参数由来
在python3加入
- 如果在一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通参数了,而是keyword-only参数
- 从语法上卡args可以看做已经截获了所有的位置参数,x不使用关键字参数就不可能拿到实参
- keyword-only参数必须给赋值,若不赋值则报错
错误示范代码
[python@centos7 412]$cat keyword.py
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def fn(*args,x):
print(x)
print(args)
print(fn(3,5,7))
print(fn(3,5,x=1))
运行结果:
Traceback (most recent call last):
File "./keyword.py", line 7, in <module>
print(fn(3,5,7))
TypeError: fn() missing 1 required keyword-only argument: 'x'
正确示范代码
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def fn(*args,x):
print(x)
print(args)
#print(fn(3,5,7))
print(fn(3,5,x=1))#x采用关键字传参方式进行传参
运行结果:
[python@centos7 412]$./keyword.py
1
(3, 5)
None
keyword-only参数另外形式
- *号之后的普通形参都变成了必须给出的keyword-only参数
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def fn(*args,x,y):
print(x,y)
print(args)
print(fn(3,5,x=1,y=2))
运行结果:
1 2
(3, 5)
None
keyword-only默认值
- 不管什么类型的位置参数,只要有默认值都会保存值__defaults__属性之中
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def fn(*args,x=1,y=2):
print(args)
print(x,y)
print(args)
print(fn(3,5))
运行结果:
[python@centos7 412]$./keyword.py
(3, 5)
1 2
(3, 5)
None
能否定义fn(**kwargs,x)?
- 根据传参方式**kwargs通过关键字传参,x也得通过关键字传参,x的关键词传参有可能被位置可变关键词参数吸收,因此通过意义判断不可以
代码示范
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def fn(**args,x):
print(x)
print(args)
print(fn(3,5,x=1))
运行结果:
[python@centos7 412]$./keyword.py
File "./keyword.py", line 4
def fn(**args,x):
^
SyntaxError: invalid syntax
不同类型位置参数定义
可变参数和默认值1
- 只要有非可变的形参,则必须给传参,因为非可变的参数相当于占位符x,当不给定x值去求y=2x,x的值都没给,怎么能求出y的值,典型案例如下:
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def fn(y,*args,x=1):
print('x={},y={}'.format(x,y))
print(args)
print(fn())
运行结果:
[python@centos7 412]$./keyword.py
Traceback (most recent call last):
File "./keyword.py", line 7, in <module>
print(fn())
TypeError: fn() missing 1 required positional argument: 'y'
可变参数和默认值2
- 如果默认值放在首位,默认有x的值,即可求值
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def fn(x=5,**args):
print('x={}'.format(x))
print(args)
print(fn())
运行结果:
[python@centos7 412]$./keyword.py
x=5
{}
None
标准模范参数定义规则
- 参数列表参数一般顺序是,普通位置形参,默认参数,可变位置参数,keyword-only参数,可变关键字参数
- 代码应该易懂,而不是为难别人,尤其是在项目中不要给自己和他人挖坑,复杂问题简单化
- 书写是请按照标准规范定义函数参数
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def fn(x,y,z=3,*args,m=4,n,**kwargs):
print(x,y,z,m,n)
print(args)
print(kwargs)
传实参方式
位置参数传参
- def f(x,y,z)调用使用f(1,3,5)
- 按照参数定义顺序传入实参
关键字参数传参
- def f(x,y,z)调用使用f(x=1,y=3,z=5)
- 使用形参的名字来出入实参的方式,如果使用了形参名字,那么传参顺序就可和定义顺序不同。
解构方式传参
- 给函数提供实参的时候,可以在集合类型前使用或者*,把集合类型的结构解开,提取出所有元素作为函数的实参
- 非字典类型使用*解构成位置参数
- 字典类型使用**解构成关键字参数
- 提取出来的元素数目要和参数的要求匹配,也要和参数的类型匹配
#!/bin/python3
#-*- coding: UTF-8 -*-
#created time 2018-04-13
def add(x,y):
return x+y
print(add(*(4,5)))
print(add(*[4,5]))
print(add(*{4,5}))
print(add(**{'x':4,'y':5}))
运行结果:
[python@centos7 412]$./keyword.py
9
9
9
9
传参总结
传参的方式通常有两种方式,
- 通过位置参数传参
- 通过关键字参数传参
- 通常位置参数在前,关键字参数在后,若采用关键字参数时,顺序可以迭代,但是位置参数传入时,顺序不能乱