目录
3.4 函数调用
函数是组织好的、可重复使用的用来实现单一或相关联功能的代码段。定义一个函数包括给函数一个名称,指定函数里包含的参数和代码块结构。这个函数的基本结构完成以后,我们就可以通过调用执行这个函数,提高应用的模块性和代码的重复利用率。
3.4.1 内置函数:让你偷懒的工具
我们在编程过程中会用到很多函数,但我们不需要每个函数都自己去编写,因为 Python 内置了很多十分有用的函数,我们在编程过程中可以直接调用。
数学运算
abs()
:返回数值的绝对值,例如:
>>> abs(-4)
4
divmod()
:返回两个数值的商和余数,例如:
>>> divmod(7,2)
(3,1)
max()
:返回元素中的最大值,例如:
>>> max(2,6,1,7)
7
min()
:返回元素中的最小值,例如:
>>> min(2,6,1,7)
1
sum()
:返回传入元素之和,例如:
>>> sum((1,2,3,4))
10
>>> sum([1,2,3,4])
10
>>> sum((1,2,3,4),-10)
0
类型转换
bool()
:根据传入的参数的逻辑值创建一个新的布尔值,例如:
>>> bool()
False
>>> bool(1)
True
>>> bool(0)
False
>>> bool('str')
True
int()
:根据传入的参数创建一个新的整数,例如:
>>> int('3')
3
>>> int('3.6')
3
float()
:根据传入的参数创建一个新的浮点数,例如:
>>> float() # 不提供参数的时候,返回0.0
0.0
>>> float(3)
3.0
>>> float('3')
3.0
complex()
:根据传入的参数创建一个新的复数,例如:
>>> complex() # 当两个参数都不提供时,返回复数0j
0j
>>> complex('2+4j')
(2+4j)
>>> complex(1,2)
(1+2j)
序列操作
all()
:判断可迭代对象的每个元素是否都为True
值,例如:
>>> all([1,2,3]) # 列表中每个元素逻辑值均为True,返回True
True
>>> all([0,1,2]) # 列表中0的逻辑值为False,返回False
False
>>> all(()) # 空元组
True
any()
:判断可迭代对象的元素是否有为True
值的元素,例如:
>>> any([0,1,2]) # 列表元素有一个为True,则返回True
True
>>> any([0,0]) # 列表元素全部为False,则返回False
False
>>> any([]) # 空列表
False
sorted()
:对可迭代对象进行排序,返回一个新的列表。例如:
>>> a = ['a','b','d','c','B','A']
>>> a
['a', 'b', 'd', 'c', 'B', 'A']
>>> sorted(a) # 默认按字符ascii码排序
['A', 'B', 'a', 'b', 'c', 'd']
对象操作
help()
:返回对象的帮助信息;
dir()
:返回对象或者当前作用域内的属性列表。
交互操作
print()
:向标准输出对象打印输出;
input()
:读取用户输入值。
文件操作
open()
:使用指定的模式和编码打开文件,返回文件读写对象。例如:
# t为文本读写,b为二进制读写
>>> a = open('test.txt','rt')
>>> a.read()
some text
>>> a.close()
3.4.2 函数调用
函数被定义后,本身是不会自动执行的,只有在被调用后,函数才会被执行,得到相应的结果。
定义函数与调用函数的顺序
在定义了函数之后,就可以调用该函数了。但是在 Python 中我们要注意一个关键点,就是Python
不允许前向引用,即在函数定义之前,不允许调用该函数。
print plus(1,2)
def plus(a,b):
return a+b
运行结果为:
NameError: name 'plus' is not defined
从报错结果可以看出,名字为plus
的函数还没进行定义(虽然我们是在后面进行了定义)。所以当我们在调用函数时,一定要确定在调用之前进行了函数定义。
正确使用参数
我们要在调用函数时,需要正确调用函数的名称和参数,例如我们定义了一个加法函数:
def plus(a,b):
return a+b
我们在调用plus()
函数时,如果传入的参数类型不对,会报TypeError
错误。而且有时我们传入的参数类型不是规定类型的话,就算调用函数运行结果没有报错,也会产生逻辑错误。例如:
# 定义plus函数,作用是求两个正整数之和
def plus(a,b):
return a+b
# 调用plus函数,参数类型为'1','2'
print(plus('1','2'))
输出结果:
12
虽然上述例子的程序运行结果没有报错,但是结果却与我们的预期不符,因为我们的本意是调用plus()
函数实现两个整数的加法。但是如果我们传入的是字符串类型的数值时,结果就是两个字符串的拼接。所以这个例子告诉我们一定要注意传入参数的类型。
当我们传入正常类型的参数时,传入的参数个数不一致时,也会报TypeError
错误。例如:
# 定义plus函数,作用是求两个正整数之和
def plus(a,b):
return a+b
# 调用plus函数,参数为1,2,3
print(plus(1,2,3))
报错:
TypeError: plus() takes 2 positional arguments but 3 were given
报错原因显示,因为plus()
函数允许有且仅有2个参数,但是却在调用时传入了3个参数,所以程序报错。
小结
函数的调用十分重要,只有学会正确调用函数,才会得到正确的函数运行结果。
3.4.3 函数与函数调用-分清主次
我们一般将字符串、列表等变量作为参数进行函数调用。但函数本身也是一个对象,所以我们也可以将函数作为参数传入另外一个函数中并进行调用。
我们要学习函数与函数之间的调用,就应该对函数调用的顺序与参数有清晰的认识,我们将会从五种情况让读者了解并掌握函数与函数之间的调用的基本关系和联系。
第一种情况
程序代码如下:
def x(f):
def y():
print(1)
return y
def f():
print(2)
x(f)
运行结果:
无结果
分析:因为第9行中的x(f)
中的f
没有带括号,f
只是一个普通的参数,所以程序只调用执行了x(f)
函数,没有调用执行f()
函数。x(f)
函数中虽然也定义了y()
函数,但是x(f)
函数中没有调用执行y()
函数,只是执行了return y
。而y
变量也没有值,所以整个程序的返回值就为无结果。
第二种情况
程序代码如下:
def x(f):
def y():
print(1)
return y
def f():
print(2)
x(f())
运行结果:
2
分析:因为第9行中的x(f())
中的f()
带括号,所以程序先调用执行f()
函数,先输出2
。然后2
作为参数传入到x(f)
函数中,程序开始调用执行x(f)
函数。x(f)
函数中虽然也定义了y()
函数,但是x(f)
函数中没有调用执行y()
函数,只是执行了return y
。而y
变量也没有值,所以调用执行x(f)
函数没有产生任何结果。因此该程序最终只输出了2
。
第三种情况
程序代码如下:
def x(f):
def y():
print(1)
return y()
def f():
print(2)
x(f)
运行结果:
1
分析:因为第9行中的x(f)
中的f
没有带括号,f
只是一个普通的参数,所以程序只调用执行了x(f)
函数,没有调用执行f()
函数。x(f)
函数中也定义了y()
函数,并且返回是y()
函数。因此程序调用执行了y()
函数,输出结果是1
。
第四种情况
程序代码如下:
def x(f):
def y():
print(1)
return y()
def f():
print(2)
x(f())
运行结果:
2
1
分析:因为第9行中的x(f())
中的f()
带括号,所以程序调用执行了f()
函数,先输出2
。然后2
作为参数传入到x(f)
函数中,程序开始调用执行x(f)
函数。x(f)
函数中也定义了y()
函数,并且返回是y()
函数。因此程序也调用执行了y()
函数,也输出了1
。最终该程序先后输出了2
和1
。
第五种情况
程序代码如下:
def x(f):
def y():
print(1)
print(f())
return y()
def f():
#print(2)
return 2
x(f)
运行结果:
1
2
分析:因为第9行中的x(f)
中的f
没有带括号,f
只是一个普通的参数,所以程序只是先调用执行了x(f)
函数。在x(f)
函数中也定义了y()
函数,而且返回值是y()
函数,所以程序会调用执行y()
函数。在y()
函数中先是执行print(1)
语句,输出1
,接着执行print(f())
语句,所以程序在这时也会调用执行f()
函数,输出2
。最终该程序先后输出了1
和2
。
小结
以上是对函数与函数之间调用的五种情况的探讨与分析。函数作为参数传入另外一个函数中并进行调用的情况有很多,我们需要时刻注意函数调用的相关要求与细节,才能正确使用函数。