学习笔记:Python3 函数
仅为个人查阅使用,如有错误还请指正。
在数学中:函数表示每个输入值对应唯一输出值的一种对应关系。
在编程中:可以理解为,它执行一个指定的运算或操作。
Python内置了很多有用的函数,可以直接调用。包括数据类型转换函数。
常用函数
abs
,set
,help
,enumerate
,eval
,id
, len
,max
, min
,open
, print
, range
, reversed
, super
,sum
还有很多,官方链接https://docs.python.org/3.6/library/functions.html
调用函数
调用函数最基本的操作就是你要知道函数的名称和参数。
并且根据函数的定义:正确的传入参数,否则报错。
可以通过内置函数help(xx)
去查看该函数的信息。
编写函数
Python自定义函数使用def关键字,一般格式如下:
def 函数名(参数列表):
函数体
实例
函数体内部的语句在执行时,一旦执行到return
时,函数就执行完毕,并将结果返回。
def my_abs(x):
if x >= 0:
return x
else:
return -x
实际开发过程中,暂时想不到该函数的具体实现方法,可以使用pass语句进行占位。
使用pass语句主要是为了程序还能正常运行。
def my_sum(x):
if x >= 0:
# 比如我暂时不确定,如果x大于等于0,要怎么操作。写个pass先保证程序正常运行。
pass
else:
return 0
实例升级
个人的建议:第一步有必要检查参数的数据类型。比如只允许传入的参数是整数,其他全部报错。
下面这个例子说明:传入一个x值,返回两个值(一个是x²,一个是2^x),且该值必须是整数,如果不是整数,就会抛出异常。
def operate_x(x):
if not isinstance(x, int):
raise TypeError('arguments must be int type')
a = x ** 2
b = pow(2, x)
return a, b
print(operate_x(5))
# output:(25, 32)
print(operate_x('2'))
"""
Traceback (most recent call last):
File "E:\Code\demo\demo1.py", line 10, in <module>
print(operate_x('2'))
File "E:\Code\demo\demo1.py", line 5, in operate_x
raise TypeError('arguments must be int type')
TypeError: arguments must be int type
"""
总结:函数是可以返回多个值,其实就是一个元组。
递归函数
顾名思义就是调用函数本身。
优点:定义简单,逻辑清晰。
以大家所熟悉的阶乘来举例子:
5! = 1 x 2 x 3 x 4 x 5
,用函数fact(5)
表示。
def fact(n):
if n == 1:
return 1
return n * fact(n - 1)
写递归函数,需要有一定的逻辑性 + 数学基本功。
函数的参数
默认参数
如果看过int()函数的源代码,就知道,它有两个参数。
int(x, base=10)
第二个参数是转换进制,如果不传,默认是十进制。也可以转二进制,八进制,十六进制。
int("123", 8)
int("1010", 2)
默认参数,其实用来简化调用。因为一般我们需要的功能,默认参数能够满足。
但是在需要的时候,又可以传入额外的参数来覆盖默认参数值。
注意:默认参数只能定义在必须参数的后面,或者只有一个默认参数。
实例
# 如果不传参数,就返回Hello world。
def greet(name='world'):
return "Hello %s" % name
print(greet())
print(greet('Bart'))
# output:
Hello world
Hello Bart
位置参数
顾名思义就是参数要按照位置顺序传入。
以计算平方和n方为例
平方
def power(x):
return x * x
print(power(5))
对于power()
函数,参数x
就是一个位置参数。当我们调用时,必须传入有且仅有一个参数。
n方(想什么方就什么方)
def n_power(x, n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
print(n_power(5, 3))
对于n_power()
函数,参数x
,n
就是位置参数,且调用的时候要按照位置顺序依次传入。
可变参数
顾名思义就是参数随便你传,我只需要把你传入的参数,封装起来就好。
在参数前面使用 * ,函数内部,参数接收到的就是一个元组(tuple)。
def fn(*args):
return args
print(fn("a", "b", "c")) # output:('a', 'b', 'c')
print(fn(1, 2)) # output:(1, 2)
实例
# 求平均数的一个函数
def average(*args):
if len(args)!=0:
return sum(args)*1.0/len(args)
else:
return 0.0
print(average()) # 0.0
print(average(1, 2)) # 1.5
print(average(1, 2, 2, 3, 4)) # 2.4
关键字参数
可变参数是允许你传入0个或任意个参数,且这些参数在调用函数时自动组装成一个元组。
而关键字参数允许你传入0个或任意个含参数名的参数,且这些参数在调用函数时自动组装成一个字典。
只需要在参数前面使用 **
实例
def student(name, age, **kw):
return "name:",name,"age:",age,"kw:",kw
print(student("aobazhu", 35))
print(student("aobazhu", 40, city="zhejiang"))
print(student("aobazhu", 40, city="zhejiang", hobby="liaomei"))
# output:
('name:', 'aobazhu', 'age:', 35, 'kw:', {})
('name:', 'aobazhu', 'age:', 40, 'kw:', {'city': 'zhejiang'})
('name:', 'aobazhu', 'age:', 40, 'kw:', {'city': 'zhejiang', 'hobby': 'liaomei'})
命名关键字参数
就是来限定关键字,不让你随便传。
第一种:可以使用 * 来进行分割。因为 * 后面只能是关键字参数。
注意:这个时候city
就不是一个字典了。而传入的参数要按照关键字传。
def student(name, age, *, city):
return "name:",name,"age:",age,"city:",city
print(student("aobazhu", 40, city="zhejiang"))
# output:
('name:', 'aobazhu', 'age:', 40, 'city:', 'zhejiang')
第二种,就是已经存在可变参数(*args
),就不需要 * 这个符号了。
def student(name, age, *args, city):
return "name:",name,"age:",age,"city:",city
print(student("aobazhu", 40, city="zhejiang"))
# output:
('name:', 'aobazhu', 'age:', 40, 'city:', 'zhejiang')
终极螺旋参数组合
前面说了这么多,你没有发现不管传什么参数,都可以用一种形式去涵盖。
args
是可变参数,args
接收的是一个tuple
。
kwargs
是关键字参数,kwargs
接收的是一个dict
。
所以可以组合成:func(*args, **kwargs)
这是一种习惯写法,需要去适应。