1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# 定义函数
# 在Python中,定义一个函数要使用def语句,函数的返回值用return语句返回
# import math 语句表示导入math包,并允许后续代码引用math包里的sin、cos等函数
import  math
 
 
def  my_abs(x):
     if  x > =  0 :
         return  x
     else :
         return  - x
print ( 'invoke my_abs(-3)' , my_abs( - 3 ))
 
# --------------------------------------------------------------------
# 在函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。
# 因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑
# 如果没有return语句,函数执行完毕后也会返回结果,只是结果为None
# return None可以简写为return
# --------------------------------------------------------------------
 
# 定义一个什么事也不做的空函数,可以使用pass语句
 
 
def  nop():
     pass
# pass语句什么都不做,实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来
 
# pass还可以用在其他语句里
age  =  20
if  age > =  18 :
     pass
 
# 参数检查
# 调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError: my_abs() takes 1 positional argument but 2 were given
# my_abs(1, 2)
# 但是如果参数类型不对,Python解释器就无法帮我们检查
# my_abs('A')
# abs('A')
# 当输入了不恰当的参数时,内置函数abs会检查出参数错误,而我们定义的my_abs没有参数检查,会导致if语句出错,出错信息和abs不一样
# 所以这个函数定义不够完善
# 让我们修改一下my_abs的定义,对参数类型做检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance()实现
 
 
def  my_abs(x):
     if  not  isinstance (x, ( int float )):
         raise  TypeError( 'bad operand type' )
     if  x > =  0 :
         return  x
     else :
         return  - x
# print('after add isinstance,test my_abs(str)', my_abs('A'))
 
# 返回多个值
# 函数可以返回多个值
# 比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的坐标
 
 
def  move(x, y, step, angle = 0 ):
     nx  =  +  step  *  math.cos(angle)
     ny  =  +  step  *  math.sin(angle)
     return  nx, ny
# 然后我们同时获得返回值
x, y  =  move( 100 100 60 , math.pi  /  6 )
print ( 'print x,y' , x, y)
# 但其实这只是一种假象,Python函数返回的仍然是单一值
=  move( 100 100 60 , math.pi  /  6 )
print ( 'print r' , r)
# 原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋值给对应的值
# 所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。
# 如果接收变量的个数超过了tuple元素的个数,会报ValueError: not enough values to unpack (expected 3, got 2)
# x, y, z = move(100, 100, 60, math.pi / 6)