********以下笔记参考廖雪峰老师的Python教程
1. Python内置函数调用(如)
求绝对值:abs()
求最大值:max()
数据类型转换:int()
函数名是指向一个函数对象的引用,把函数名赋给一个变量相当于给这个函数起别名。
2. 函数定义:
定义一个函数quadratic(a,b,c),接收3个参数,返回一元二次方程的两个解。
import math
def quadratic(a,b,c):
t=math.sqrt(b**2-4*a*c)
x1=(-b+t)/(2*a)
x2=(-b-t)/(2*a)
return x1,x2
print(quadratic(2, 3, 1))
这是我自己写的廖老师该章节的练习,对比其他同学的答案发现很不严密:1.没有考虑非法值的判断;2.没有考虑(b^2-4ac)是否大于0
另外在写代码中,发现:1. Python中幂的表示 x**y;2. *不可省略
以下是重写代码:
注:raise显示错误:
当程序出现错误,python会自动引发异常,也可以通过raise显示地引发异常。一旦执行了raise语句,raise后面的语句将不能执行。
import math
def quadratic(a,b,c):
if not isinstance(a, (int,float)):
raise TypeError('bad oprand type')
if not isinstance(b, (int,float)):
raise TypeError('bad oprand type')
if not isinstance(c, (int,float)):
raise TypeError('bad oprand type')
if a==0:
return('非一元二次方程')
t=b**2-4*a*c
if t>0:
t=math.sqrt(t)
x1=(-b+t)/(2*a)
x2=(-b-t)/(2*a)
return('方程有两个根',x1,x2)
elif t==0:
x=-b/(2*a)
return('方程有一个跟',x)
elif t<0:
return('无解')
------------------------------------
print(quadratic(2, 3, 1))
print(quadratic(1, 3, -4))
print(quadratic(1, 1, 1))
print(quadratic(0, 1, 1))
输出结果为:
('方程有两个根', -0.5, -1.0)
('方程有两个根', 1.0, -4.0)
无解
非一元二次方程
函数体内部的语句在执行时,一旦执行到return,函数就执行完毕,并将结果返回。
如果没有return语句,函数执行完毕后会自动返回None;return None可以简写为return。
注:Python函数中print()和return()的区别:
这两个看起来输出结果一样,但是内涵是完全不一样的
return的作用之一是返回计算的值
print的作用是输出数据到控制端
def add (x, y):
z = x + y
return/print z
如此段代码中,如果是return z,则返回了z,如果不在之后print z 的话则没有输出
如果是print z,则该函数没有return,默认返回值是None,会多出一个空值,但会直接输出z的值
3. 定义函数调用,如需要调用abstest.py中的quadratic函数,应写为:
from abstest import quadratic
print(quadratic(0, 1, 1))
4. 空函数:
def nop():
pass
5. Python函数返回值:
python函数可以返回多个值,但这是个假象,Python返回的多个值其实是一个tuple,所以Python函数返回的仍然是个单一值
6. 函数的参数:
① 位置参数:
调用函数的时候,传递的参数都是根据位置来跟函数定义里的参数表匹配的,比如funcB(100, 99)和funcB(99, 100)的执行结果是不一样的。
对于func(x)函数,参数x就是一个位置参数。
② 关键字参数:(个人感觉廖老师这部分解释较为复杂,建议参见该blog)
http://www.iplaypython.com/jinjie/jj130.html
目的:在程序比较繁琐的时候,参数顺序是很难能记住的,为了让程序简单不出错,会为参数起一个名字,这就是关键字参数的作用;另外,可以为关键字参数设置默认值。
③ 默认参数:
func(x,y=2)
把参数y的默认值设定为2,此时,调用func(5)时,相当于调用func(5,2)
如果需要改变y的值,则可直接传入(5,3)
注:设定参数时:1) 必选参数在前,默认参数在后;2) 变化大的参数放在前面,变化小的参数放在后面。
默认参数易错点:
def add_end(L=[]):
L.append('END')
return L
>>>add_end()调用默认参数,输出['END'],再次调用时结果为['END','END']
原因:
Python函数在定义的时候,默认参数的L的值被定义为[],因为默认参数L也是一个变量,它指向[],每次调用该函数,如果改变了L 的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时候的L了。
传入参数[1,2,3]时,接下来的代码都是针对[1,2,3],和L=[]没有关系。当没有传入参数时,之后的代码针对L的默认值[]进行修改。
默认参数必须指向不变对象!
④ 可变参数:
1)可变参数:*list
目的:传入不确定个数的参数。
其他方法:可通过构建一个list或tuple传入不确定个数的参数。如:func([1,2,3,4,5])
,如:
def func(names)
for name in names:
print(name)
传值时,需要先构建list,func(['Zhangsan','Lisi','Wangwu'])
可变参数:在参数前加*,如:
def func(*names)
for name in names:
print(name)
可以直接传:func(‘Zhangsan’,'Lisi','Wangwu');在函数内部,参数names收到的是一个tuple
2)关键字参数**kw
传入dict的key值,常用**kw表示
和可变函数的区别:可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
a. 判断关键字参数:
def persons(name,age,**kw)
if 'city' in kw
pass
if 'job' in kw
pass
b. 命名关键字参数(即只接收指定的关键字作为关键字参数)
如:只接收city和job作为关键字参数
def persons(name,age,*,city,job):
print(name,age,city,job)
*后面的参数被视为命名关键字参数。
命名关键字参数必须传入参数名。
如果函数定义中已经有一个可变参数,后面跟着的命名关键字参数不需要单独出一个*了
⑤ 参数组合:
5种参数定义的顺序必须是:必选参数(位置参数)、默认参数、可变参数、命名关键字参数和关键字参数。
如:
def f1(a,b,c=0,*args,**kw):
print('a=',a,'b'=,b,'c=',c,'args=',args,'kw=',kw)
输入:
args=(1,2,3,4)
kw={'d':99,'x':'#'}
f1(*args,**kw)
输出:
a=1,b=2,c=3,args=(4,),kw={'d':99,'x':'#'}
7. 递归函数:在一个函数内调用自身本身。
如:fact=n!
即:fact(n)=n*fact(n-1),当n=1时特殊处理
def fact(n):
if n==1:
return 1
return n*fact(n-1)
print(fact(5))
个人理解相当于利用递推公式和截止条件计算。(不用人脑算通项公式了哈哈哈)
使用递归函数需要防止栈溢出。
④ 关键字参数:
目的:在程序比较繁琐的时候,参数顺序是很难能记住的,为了让程序简单不出错,会为参数起一个名字,这就是关键字参数的作用。