语法:
def 函数名(参数列表):
函数体
实例
def print_welcome(name):
print("Welcome", name)
def SuccessEquation(factor1, factor2):
return str(factor1 + " Plus " + factor2 + " = Success")
print_welcome("IvanZhang")
X = 'Vision'
Y = 'Endeavor'
print(SuccessEquation(X, Y))
# Welcome IvanZhang
# Vision Plus Endeavor = Success
其他:
isinstance()
实现;x = 'red'
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
# TypeError: bad operand type
首先,定义一个函数:给了函数一个名称,指定了函数里包含的参数,和代码块结构。
这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从 Python 命令提示符执行。
其次,python支持非常灵活定义的函数,而且本身内置了很多有用的函数
使用方法:
help(func)
查看对应函数func的帮助文档“函数名其实就是指向一个函数对象的引用”,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”
f = float
print(f(1.2342342352345235234234233984028953))
# 输出 1.2342342352345235
Sample1:
def add(a, b):
return a + b
print(add(1, 2)) # 3
print(add([1, 2, 3], [4, 5, 6])) # [1, 2, 3, 4, 5, 6]
Sample2:
def back():
return [1, 'python practice', 3.14]
print(back()) # [1, 'python practice', 3.14]
Sample3:
def back():
return 1, 'python practice', 3.14
print(back()) # (1, 'python practice', 3.14)
Sample4:
def printme(str):
print(str)
temp = printme('hello') # hello
print(temp) # None
print(type(temp)) #
def discounts(price, rate):
final_price = price * rate
return final_price
old_price = float(input('请输入原价:')) # 98
rate = float(input('请输入折扣率:')) # 0.9
new_price = discounts(old_price, rate)
print('打折后价格是:%.2f' % new_price) # 88.20
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num) # 1
num = 123
print(num) # 123
fun1()
print(num) # 123
def outer():
print('outer函数在这被调用')
def inner():
print('inner函数在这被调用')
inner() # 该函数只能在outer函数内部被调用
outer()
# outer函数在这被调用
# inner函数在这被调用
def funX(x):
def funY(y):
return x * y
return funY
i = funX(8)
print(type(i)) #
print(i(5)) # 40
def make_counter(init):
counter = [init]
def inc(): counter[0] += 1
def dec(): counter[0] -= 1
def get(): return counter[0]
def reset(): counter[0] = init
return inc, dec, get, reset
inc, dec, get, reset = make_counter(0)
inc()
inc()
inc()
print(get()) # 3
dec()
print(get()) # 2
reset()
print(get()) # 0
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
# 100
# 100
Sample01:n! = 1 x 2 x 3 x ... x n
循环:
n = 5
for k in range(1, 5):
n = n * k
print(n) # 120
递归:
def factorial(n):
if n == 1:
return 1
return n * fact(n - 1)
print(factorial(5)) # 120
Samp02:斐波那契数列 f(n)=f(n-1)+f(n-2), f(0)=0 f(1)=1
循环:
i = 0
j = 1
lst = list([i, j])
for k in range(2, 11):
k = i + j
lst.append(k)
i = j
j = k
print(lst)
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
递归:
def recur_fibo(n):
if n <= 1:
return n
return recur_fibo(n - 1) + recur_fibo(n - 2)
lst = list()
for k in range(11):
lst.append(recur_fibo(k))
print(lst)
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
import sys
sys.setrecursionlimit(1000)
需要注意的是,在 python 中,类型属于对象,变量是没有类型的
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
python 函数的参数传递:
'''python 传不可变对象实例'''
def ChangeInt(a):
a = 10
b = 2
print(ChangeInt(b)) # 返回 None
print(b) # 结果是 2
'''
解释:实例中有 int 对象 2,指向它的变量是 b,在传递给 ChangeInt 函数时,按传值的方式复制了变量 b,a 和 b 都指向了同一个 Int 对象,在 a=10 时,则新生成一个 int 值对象 10,并让 a 指向它
'''
'''传可变对象实例'''
def changeList(mylist):
"修改传入的列表"
mylist.append([1, 2, 3, 4])
print("函数内取值: ", mylist)
return
mylist = [10, 20, 30]
changemeList(mylist)
print("函数外取值: ", mylist)
'''
函数内取值: [10, 20, 30, [1, 2, 3, 4]]
函数外取值: [10, 20, 30, [1, 2, 3, 4]]
'''
简单来说:
以下是调用函数时可使用的正式参数类型:
必需参数须以正确的顺序传入函数,调用时的数量必须和声明时的一样;不然会出现语法错误。
def func(a, b, c):
pass
# 必须传入三个参数,否则会报错
def printinfo(name, age=20):
print("Name: ", name, " Grade: ", grade)
printinfo(age=21, name="Ivan") # Name: Ivan Grade: 21
printinfo(name="Zhang") # Name: Zhang Grade: 20
顾名思义,可变参数就是传入的参数个数是可变的,可以是 0, 1, 2 到任意个,是不定长的参数。
需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名
加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数
语法形式:
def functionname([formal_args,] *var_args_tuple ):
"函数_文档字符串"
function_suite
return [expression]
实例:
def printinfo(arg1, *vartuple):
print(arg1)
print(vartuple)
printinfo(70, 60, 50, 40, 30)
'''
打印:
70
(60, 50, 40, 30)
'''
特别的:
还有一种就是参数带两个星号**
用来表示不定长度参数。
加了两个星号 **
的参数会以dict字典
的形式导入
基本语法:
def functionname([formal_args,] **var_args_dict ):
"函数_文档字符串"
function_suite
return [expression]
实例:
def printinfo(arg1, **vardict):
print("输出: ")
print(arg1)
print(vardict)
printinfo(1024, a_1=2, buffer='full')**
输出:
1024
{'a_1': 2, 'buffer': 'full'}
特别的:声明函数时,参数中星号*
可以单独出现
语法形式:
def f(a,b,*,c):
return a+b+c
但是,如果单独出现星号*
后的参数必须用关键字传入
>>> def f(a,b,*,c):
... return a+b+c
...
>>> f(1,2,3) # 报错
Traceback (most recent call last):
File "" , line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
因为有的时候 参数的使用不一定是使用指定顺序 或 部分参数已经输入
def printinfo(name, age, major):
print("名字: ", name)
print("年龄: ", age)
print("专业: ", major)
printinfo(major="CS", age=21, name="Ivan")
'''
名字: Ivan
年龄: 21
专业: CS
'''
上面的描述似乎有问题
def functionname(arg1, arg2=v, *args, **kw):
"函数_文档字符串"
function_suite
return [expression]
**kw - 关键字参数,可以是从零个到任意个,自动组装成字典。
def printinfo(arg1, *args, **kwargs):
print(arg1)
print(args)
print(kwargs)
printinfo(70, 60, 50)
# 70
# (60, 50)
# {}
printinfo(70, 60, 50, a=1, b=2)
# 70
# (60, 50)
# {'a': 1, 'b': 2}
「可变参数」和「关键字参数」的同异总结如下:
def functionname(arg1, arg2=v, *args, *, nkw, **kw):
"函数_文档字符串"
function_suite
return [expression]
*
,nkw
- 命名关键字参数,用户想要输入的关键字参数,定义方式是在nkw 前面加个分隔符 *。def printinfo(arg1, *, nkw, **kwargs):
print(arg1)
print(nkw)
print(kwargs)
printinfo(70, nkw=10, a=1, b=2)
# 70
# 10
# {'a': 1, 'b': 2}
printinfo(70, 10, a=1, b=2)
# TypeError: printinfo() takes 1 positional argument but 2 were given
没有写参数名nwk
,因此 10 被当成「位置参数」,而原函数只有 1 个位置函数,现在调用了 2 个,因此程序会报错。
在 Python 中定义函数,可以用位置参数、默认参数、可变参数、命名关键字参数和关键字参数,这 5 种参数中的 4 个都可以一起使用,但是注意,参数定义的顺序必须是:
要注意定义可变参数和关键字参数的语法:
*args
是可变参数,args
接收的是一个tuple
**kw
是关键字参数,kw 接收的是一个 dict
*
,否则定义的是位置参数。特别的:虽然可以组合多达 5 种参数,但不要同时使用太多的组合,否则函数很难懂
在 Python 里有两种函数:
python 使用 lambda
来创建匿名函数,
def
语句这样标准的形式定义一个函数:lambda
只是一个表达式,函数体比 def
简单很多。lambda
的主体是一个表达式,而不是一个代码块。仅仅能在lambda
表达式中封装有限的逻辑进去。lambda
函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。lambda
函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。lambda 函数的语法只包含一个语句,语法如下:
lambda [arg1 [,arg2,.....argn]]:expression
or
lambda argument_list: expression
lambda
- 定义匿名函数的关键词。argument_list
- 函数参数,它们可以是位置参数、默认参数、关键字参数,和正规函数里的参数类型一样。:-
冒号,在函数参数和表达式中间要加个冒号。expression
- 函数表达式,输入函数参数,输出一些值实例
sumary = lambda arg1, arg2: arg1 + arg2
print(sumary(10, 20)) # 30
func = lambda *args: sum(args)
print(func(1, 2, 3, 4, 5)) # 15
实例:
psum = lambda arg1, arg2: arg1 + arg2
print("相加后的值为 : ", psum(10, 20))
print("相加后的值为 : ", psum(20, 20))
'''
相加后的值为 : 30
相加后的值为 : 40
'''
实例:
lambda x: 2*x+1
g = lambda x:2*x+1
g(5)
g = lambda x,y:x+y
g(1,2)
但需要注意的是,PEP 8 规范 不建议使用赋值语句定义Lambda函数,而是使用def
进行定义
lbd_sqr = lambda x: x ** 2
print(lbd_sqr)
# at 0x000000BABB6AC1E0>
def sqr(x):
return x ** 2
print(sqr)
#
print(sqr(9)) # 81
print(lbd_sqr(9)) # 81
lambda
函数只是为了赋值给一个变量,用def
的正规函数。lbd_sqr
的返回值是以 标识的函数,而 sqr
的返回时是以sqr
为标识的函数,明显后者一看就知道该函数是「计算平方」用的。高阶函数 (high-order function) 在函数化编程 (functional programming) 很常见,主要有两种形式:
filter(function, iterable)
过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list()
来转换。
a = (list(filter(lambda x: x % 2, range(10))))
print(a) # [1, 3, 5, 7, 9]
map(function, iterable, …)
:映射。将iterator中的元素依次作为fun的参数,经过处理的结果加入到结果序列中(根据提供的函数对指定序列做映射)
a = list(map(lambda x: x**2, range(10)))
print(a) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
除了 Python 这些内置函数,我们也可以自己定义高阶函数,如下:
def apply_to_list(fun, some_list):
return fun(some_list)
下面代码分别求出列表中所有元素的和、个数和均值。
lst = [1, 2, 3, 4, 5]
print(apply_to_list(sum, lst))
# 15
print(apply_to_list(len, lst))
# 5
print(apply_to_list(lambda x: sum(x) / len(x), lst))
# 3.0
特别鸣谢