1.函数的概念:
函数是一个过程,功能、动作、实现某种功能或某些指令的集合,简单来说可以看作一个工厂,把数据放入工厂进行各种各样的加工。
2.函数的定义:
def 函数名称 ([参数列表]):
#缩进 函数体
#[return]
(如果没有返回值,其返回为空(None))
(pass------相当于占位符、空语句)
检查参数
1,如果参数数量不匹配
2,用到的参数类型不匹配
异常处理
这里只是简单提一下,有兴趣的话可以私下去了解
#绝对值
def myabs(x):
if not isinstance(float,str):
raise TypeError("dsafsda")
if x>0:
return x
else:
return -x
x=-9.0
print(myabs(x))
3.函数具体使用
3.1.返回多个值的情况
import math
def move(x,y,step,angle=0):
nx = x + step*math.cos(angle)
ny = y - step*math.sin(angle)
return nx,ny
r=move(7,7,7,math.pi/6)
print(r)
需要注意的是
如果返回多个值用一个变量接收其类型为元组
3.2.函数重定义
用一个变量接收函数对象
# #绝对值
def myabs(x):
if x>0:
return x
else:
return -x
x=9
a=myabs
print(a(x))
3.3.引用传递
def info(fn,msg):
fn()
print(msg)
def print_msg():
print("我们自己定义的函数")
print(print_msg)
print(print_msg())
其中fn表示函数的地址,弱数据语言中可以将函数传入
小结:
1、函数定义,如果有必要的话可以检查参数的类型
2、如果函数有返回值的话,使用return进行返回值操作
3、pass关键字------相当于一个占位符,空语句
4、返回多个值实际上是一个元组
3.4.函数调用
方法:
函数名称([参数])
a(x)
3.5.函数分类
分类依据 | 分出类型 |
---|---|
1.有无参数 | 有参函数和无参函数 |
2.有无返回值 | 有返回值函数和无返回值函数 |
3.根据定义者角色 | 系统自定义函数(内置函数)和第三方(公司、个人、组织)自定义的函数 |
4.函数参数具体使用
4.1.位置参数
即按顺序对参数进行输入
def power(x,n):
return x**n
print(power(4,2))
对于power两个参数,调用函数的时候需要依次按照顺序传入两个参数的值
4.2.默认值参数
用“=”号为参数赋予默认值
def power(x,n=2):
return x**n
print(power(4))
默认值参数就是给一个参数设定默认值,如果该参数没有传入相应的值,按照默认值计算,如果该参数有传入相应的值,则按照传入的值计算。
注意!【默认值参数写在无默认值参数的后面】
4.3.可变参数
python中,“*”表示可变参数
允许调用函数将参数自动封装成元组
def num(*numbers):
sum=0
for i in numbers:
sum+=i**2
return sum
print(num(1,2,3,4))
print(num(1,2,3))
另外我们也能用*对可迭代对象进行拆分,如下代码中的list1
def num(*numbers):
sum=0
print(type(numbers))
for i in numbers:
sum+=i**2
return sum
list1=[1,2,3,4]
print(num(1,2,3,4))
print(num(1,2,3))
print(*list1)
print(num
4.4.关键字参数
允许调用函数将参数自动封装成字典,用**表示
def person(name,age,**kw):
print("name",name,"age:",age,"other:",kw)
person("zhangsnaa","18",city="北京",sex="张三")
def person(name,age,**kw):
print("name",name,"age:",age,"other:",kw)
d={"city":"chongqing","sex":"男"}
person("zhangsnaa","18",city=d["city"],sex=d["sex"])
person("zhangsnaa","18",**d)
4.5.命名关键字参数
命名关键字参数也用“*”表示,但具体实现与可变参数略有不同。且需要注意,其赋值方式只能是“参数名=值”,参数名相当于它的key值
def person(name,age,*,city,gender):
print("name",name,"age:",age,"city:",city,"gender:",gender)
d={"city":"chongqing","sex":"男"}
person("zhangsnaa","18",city=d["city"],gender=d["sex"])
补充
1.如果函数参数中已经出现了可变参数,则可以省略命名关键字的参数前的“*”。
2.也可以给命名关键字参数设置默认值
def person(name,age,*a,city,gender):
print("name",name,"age:",age,"city:",city,"gender:",gender)
d={"city":"chongqing","sex":"男"}
person("zhangsnaa","18",city=d["city"],gender=d["sex"])
def person(name,age,*,city="chongqing",gender="wghh"):
print("name",name,"age:",age,"city:",city,"gender:",gender)
d={"city":"chongqing","sex":"男"}
person("zhangsnaa","18",city=d["city"])
4.6.参数组合
五种参数可同时存在一个函数中组合使用,但是有一定顺序:
下面是一些没事时打的练习用于参考:
>>> def f1(a,b,c=0,*args,**kw):
... print("a=",a,"b=",b,"c=",c,"args=",args,"kw=",kw)
...
>>> def f2(a,b,c=0,*,d,**kw):
... print("a=",a,"b=",b,"c=",c,"d=",d,"kw=",kw)
...
>>> f1(1,2)
a= 1 b= 2 c= 0 args= () kw= {}
>>> f1(1,2,3)
a= 1 b= 2 c= 3 args= () kw= {}
>>> f1(1,2,c=3)
a= 1 b= 2 c= 3 args= () kw= {}
>>> f1(1,2,c=3,"a","b")
File "<stdin>", line 1
f1(1,2,c=3,"a","b")
^
SyntaxError: positional argument follows keyword argument
>>> f1(1,2,c=3,"a",sex="b")
File "<stdin>", line 1
f1(1,2,c=3,"a",sex="b")
^
SyntaxError: positional argument follows keyword argument
>>> f1(1,2,3,"a",sex="b")
a= 1 b= 2 c= 3 args= ('a',) kw= {'sex': 'b'}
>>> f1(1,2,3,"a","b")
a= 1 b= 2 c= 3 args= ('a', 'b') kw= {}
>>> f1(1,2,3,"a","b")
a= 1 b= 2 c= 3 args= ('a', 'b') kw= {}
>>> f1(1,2,3,"a","b",d="t")
a= 1 b= 2 c= 3 args= ('a', 'b') kw= {'d': 't'}
>>> f1(1,2,c=3,"a","b",d="t")
File "<stdin>", line 1
f1(1,2,c=3,"a","b",d="t")
^
SyntaxError: positional argument follows keyword argument
>>> f1(1,2,3,"a","b",d="t")
a= 1 b= 2 c= 3 args= ('a', 'b') kw= {'d': 't'}
>>> f1(1,2,3,c="t")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f1() got multiple values for argument 'c'
>>> f1(1,2,c="t")
a= 1 b= 2 c= t args= () kw= {}
>>> f2(1,2,3,5,6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f2() takes from 2 to 3 positional arguments but 5 were given
>>> f2(1,2,3,d=5,6)
File "<stdin>", line 1
f2(1,2,3,d=5,6)
^
SyntaxError: positional argument follows keyword argument
>>> f2(1,2,3,d=5)
a= 1 b= 2 c= 3 d= 5 kw= {}
>>> f2(1,2,3,d=5,sex="d")
a= 1 b= 2 c= 3 d= 5 kw= {'sex': 'd'}
>>> f2(1,2,3,d=5,sex=1)
a= 1 b= 2 c= 3 d= 5 kw= {'sex': 1}
字典对应
>>> args=(1,2,3,4)
>>> kw={"d":9,"x":"#"}
>>> f1(*args,**kw)
a= 1 b= 2 c= 3 args= (4,) kw= {'d': 9, 'x': '#'}
>>> args=(1,2,3)
>>> f1(*args,**kw)
a= 1 b= 2 c= 3 args= () kw= {'d': 9, 'x': '#'}
>>> f2(*args,**kw)
a= 1 b= 2 c= 3 d= 9 kw= {'x': '#'}
>>> kw={"f":88,"x":"&"}
>>> f2(*args,**kw)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError
注意!:任何函数都可以有以上五种参数的组合,但种类越少运行速度越快,尽量不要使用太多参数类型的组合
一些问题
默认值非必要不要指向可变对象
>>> def add_end(l=[]):
... l.append("end")
... return l
...
>>> add_end()
['end']
>>>
>>> add_end()
['end', 'end']
>>> add_end()
['end', 'end', 'end']
如上所示,当默认值参数指向可变参数列表时,参数的值会实际的保存下来,需要改进:
>>> def add_end(l=None):
... if l==None:
... l=[]
... else:
... l.append("end")
... return l
...
>>> add_end()
[]
>>> add_end([1,2,3,4])
[1, 2, 3, 4, 'end']
改进如上