本文实例讲述了python3.5函数的定义与使用。分享给大家供大家参考,具体如下:
1、函数学习框架
2、函数的定义与格式
(1)定义
(2)函数调用
注:函数名称不能以数字开头,建议函数名称的开头用小写的字母
(3)函数有四种格式,分别是:无参数无返回值,有参数无返回值、无参数有返回值、有参数有返回值
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
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:zhengzhengliu
# 无参数无返回值
def hello():
# 函数体/方法体
print ( "hello world" )
hello()
# 有参数无返回值
def add(x, y):
print (x + y)
add( 10 , 20 )
# 无参数有返回值
def sleep():
return "sleep"
s = sleep()
print (s)
# print(sleep()) 等价于上面两句
# 有参数有返回值
def sub(x, y):
return x * y
res = sub( 12 , 6 )
print (res)
|
运行结果
hello world
30
sleep
72
3、函数的参数
注:定义再函数体内的参数是形参,调用时传入的参数是实参。
函数参数包括:位置参数、关键字参数和不定个数参数
(1)位置参数、关键字参数
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#位置参数
def test(x,y,z):
print (x,y,z)
test( 1 , 2 , 3 )
#关键字参数
def test1(x,y,z = 10 ):
print (x,y,z)
test1( 1 , 2 , 3 )
test1( 1 , 2 ) #关键字参数,z采用默认的参数值
test1(x = 2 ,z = 3 ,y = 1 ) #调用时的关键字参数
|
运行结果:
1 2 3
1 2 3
1 2 10
2 1 3
(2)默认参数
注:带有默认值参数的形参必须放在参数的最后面的位置。
(3)不定个数参数,用*args 和 **kwarg
总结:
(1)定义时 *的作用 将位置实参装配成元组
定义时 **的作用 将关键字实参装配成字典
(2)调用时 *作用 将元组或列表打散成位置参数进行参数传递
调用时 **作用 将字典打散成关键字参数进行参数传递
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
|
#不定个数参数
def test2(x,y,z, * args):
print (x,y,z,args)
#定义时 *的作用 将位置实参装配成元组
test2( 1 , 2 , 3 , 4 , 6 , 7 , 8 , 9 )
def test3(x,y,z, * * kwargs):
print (x,y,z,kwargs)
#定义时 **的作用 将关键字实参装配成字典
test3( 1 , 2 , 3 ,a = 6 ,b = 19 ,c = 8 )
def ts(x, * args, * * kwargs):
print (x,args,kwargs)
ts( 1 , 2 , 3 ,a = 6 ,b = 19 ,c = 8 )
def test4(x,y,z):
print (x,y,z)
x = [ 1 , 2 , 3 ]
y = { "x" : 1 , "y" : "hello" , "z" : "你好" }
test4( * x) #调用时 *作用 将元组或列表打散成位置参数进行参数传递
test4( * * y) #调用时 **作用 将字典打散成关键字参数进行参数传递
|
运行结果:
1 2 3 (4, 6, 7, 8, 9)
1 2 3 {'b': 19, 'a': 6, 'c': 8}
1 (2, 3) {'b': 19, 'a': 6, 'c': 8}
1 2 3
1 hello 你好
4、函数的传值:基本类型传值调用、非基本类型参数传递调用(强引用与弱引用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:zhengzhengliu
#基本类型传值调用
def test(x):
print (x)
test( 10 )
#非基本类型参数传递调用
li = [ 1 , 2 , 3 , 4 ]
print ( id (li)) #打印传递前的地址
def test1(x):
print ( id (x))
x[ 0 ] = 2 #修改第一个参数为2
print (x)
test1(li) #强引用(传址调用,列表里面的内容会进行修改)
#test1(list(li)) #弱引用(用list可以消除强引用,不能修改列表里的元素)
for i in li:
print (i)
|
运行结果:(强引用传址调用)
10
17741864
17741864
[2, 2, 3, 4]
2
2
3
4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:zhengzhengliu
#基本类型传值调用
def test(x):
print (x)
test( 10 )
#非基本类型参数传递调用
li = [ 1 , 2 , 3 , 4 ]
print ( id (li)) #打印传递前的地址
def test1(x):
print ( id (x))
x[ 0 ] = 2 #修改第一个参数为2
print (x)
#test1(li) #强引用(传址调用,列表里面的内容会进行修改)
test1( list (li)) #弱引用(用list可以消除强引用,传值调用,不能修改列表里的元素)
for i in li:
print (i)
|
运行结果:(弱引用,传值调用)
10
18501544
18613272
[2, 2, 3, 4]
1
2
3
4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#不可变对象——传递对象的值,修改值修改的是另一个复制对象,不影响原来对象本身
def getnum(a):
a = 10
print ( "函数内变量a的值:" ,a)
a = 8
getnum(a)
print ( "函数外变量a的值:" ,a)
#可变对象——传递对象本身,函数内部修改值会影响对象本身
list01 = [ 0 , 1 , 2 , 3 ]
def getnum1(num):
num.append( 4 )
print (num)
print ( id (num))
getnum1(list01)
print (list01)
print ( id (list01))
|
运行结果:
函数内变量a的值: 10
函数外变量a的值: 8
[0, 1, 2, 3, 4]
5908280
[0, 1, 2, 3, 4]
5908280
5、函数的返回值
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#多个返回值
def re(a,b):
a * = 10
b * = 10
return a,b
num = re( 1 , 2 )
print ( type (num)) #如果返回多个值,并且存在一个变量中,会以元组的形式保存
print (num)
#分别获取多个返回值
re1,re2 = re( 3 , 4 )
print ( type (re1))
print (re1,re2)
|
运行结果:
<class 'tuple'>
(10, 20)
<class 'int'>
30 40
简单实例练习:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
def operation(a,b,opt):
if opt = = "+" :
return a + b
elif opt = = "-" :
return a - b
elif opt = = "*" :
return a * b
elif opt = = "/" :
return a / b
else :
return "输入有误"
num1 = int ( input ( "请输入第一个字符:" ))
num2 = int ( input ( "请输入第二个字符:" ))
op = input ( "请输入运算符:" )
result = operation(num1,num2,op)
print (result)
|
运行结果:
请输入第一个字符:1
请输入第二个字符:2
请输入运算符:+
3
6、变量的作用域:全局变量与局部变量
在函数的内部,不能识别全局变量,想要在函数内部使用全局变量,需要关键字global,但不建议这样使用,使用global具有污染性。
(1)局部变量
(2)全局变量
(3)当全局变量与局部变量同名时,优先使用局部变量
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#全局变量与局部变量同名
a = 10 #全局变量
print ( "全局变量a:%d" % a)
def test01():
a = 20
print ( "test01中的a:%d" % a)
def test02():
print ( "test02中的a:%d" % a)
test01()
test02()
|
运行结果:
全局变量a:10
test01中的a:20
test02中的a:10
(4)修改全局变量
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:zhengzhengliu
i = 20
def test():
#i += 10 #函数内部直接修改全局的值(错误)
global i #函数内部修改全局的值用global关键字
i + = 10
print (i) #获取全局变量的值
test()
|
运行结果:
30
注:上边代码中,函数内修改不可变类型的全局变量,需要通过global关键字
总结:对不可变类型变量重新赋值,实际上是重新创建一个不可变类型对象,并将原来的变量指向新创建的对象。
如果没有其他变量引用原有对象的话(即:引用计数为0),原有对象就会被回收。
(5)可变类型的全局变量:函数内修改可变类型的全局变量,可以不使用global关键字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#函数内修改可变类型的全局变量——直接修改,无需使用global关键字
a = [ 100 , 200 , 300 ]
print ( "可变类型全局变量a:" ,a)
print ( "可变类型全局变量a的地址:%d" % id (a))
def test01():
a.append( 400 )
print ( "test01函数内修改可变类型全局变量a:" ,a)
print ( "test01函数内修改可变类型全局变量后a的地址:%d" % id (a))
def test02():
print ( "test02函数内使用可变类型全局变量a:" ,a)
print ( "test02函数内使用可变类型全局变量a的地址:%d" % id (a))
test01()
test02()
|
运行结果:
可变类型全局变量a: [100, 200, 300]
可变类型全局变量a的地址:18241896
test01函数内修改可变类型全局变量a: [100, 200, 300, 400]
test01函数内修改可变类型全局变量后a的地址:18241896
test02函数内使用可变类型全局变量a: [100, 200, 300, 400]
test02函数内使用可变类型全局变量a的地址:18241896
7、匿名函数
示例代码:
1
2
3
4
5
|
#匿名函数——lambda
#语法:lambda arg1[,arg2...]:表达式 默认return
num = lambda a,b:a + b
print (num( 1 , 2 ))
|
运行结果:
3
简单应用(一):
1
2
3
4
5
6
7
8
9
10
|
#四则运算——利用lambda表达式
def operation(a,b,opt):
re = opt(a,b)
return re
num1 = int ( input ( "请输入第一个字符:" ))
num2 = int ( input ( "请输入第二个字符:" ))
result = operation(num1,num2, lambda a,b:a + b)
print (result)
|
运行结果:
请输入第一个字符:2
请输入第二个字符:3
5
简单应用(二):
1
2
3
4
5
6
7
8
9
10
|
#列表中的字典元素进行排序——lambda表达式
students = [
{ "name" : "joe" , "age" : "18" },
{ "name" : "tom" , "age" : "20" },
{ "name" : "susan" , "age" : "16" }
]
students.sort(key = lambda x:x[ "name" ]) #对字典按照关键字name排序
print (students)
|
运行结果:
[{'age': '18', 'name': 'joe'}, {'age': '16', 'name': 'susan'}, {'age': '20', 'name': 'tom'}]
8、递归函数
代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#函数的嵌套
def test1():
print ( "in test1..." )
def test2():
test1()
print ( "in test2..." )
def test3():
test2()
print ( "in test3..." )
test3()
|
运行结果:
in test1...
in test2...
in test3...
1
2
3
4
5
6
7
8
9
10
11
|
#递归函数
def func(n):
print ( "进入第%d层梦" % n)
if n = = 3 :
print ( "进入潜意识区" )
else :
func(n + 1 )
print ( "从第%d层梦中醒来" % n)
func( 1 )
|
运行结果:
进入第1层梦
进入第2层梦
进入第3层梦
进入潜意识区
从第3层梦中醒来
从第2层梦中醒来
从第1层梦中醒来
应用:求阶乘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#阶乘——利用while
i = 1
num = 1
while i < = 4 :
num = num * i
i + = 1
print (num)
#阶乘——利用递归
def func01(n):
if n = = 1 :
return 1
return n * func01(n - 1 )
print (func01( 4 ))
|
运行结果:
24
24
利用递归实现阶乘的原理过程:
9、常用内置函数
示例代码:
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
|
#abs()——绝对值函数
num = - 1
print ( abs (num))
#sorted()——排序函数
list01 = [ 1 , 4 , 2 , 7 , 9 , 3 ]
print ( sorted (list01)) #由小到大排序
print ( sorted (list01,reverse = true)) #由大到小排序
#sum()——求和
print ( sum (list01))
#round()——四舍五入,获取指定位数的小数
print ( round ( 3.1415926 , 2 ))
#pow()——乘方数(幂)
print ( pow ( 2 , 3 ))
#isinstance——类型判断
num1 = 5
print ( isinstance (num1, int ))
#eval()——执行表达式或字符串作为运算
print ( eval ( "1+3" ))
#exec()——执行python语句
exec ( 'print("hello")' )
|
运行结果:
1
[1, 2, 3, 4, 7, 9]
[9, 7, 4, 3, 2, 1]
26
3.14
8
true
4
hello
10、高阶函数
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#常用高阶函数
#map()
num1 = map ( lambda x:x * 2 ,[ 1 , 2 , 3 , 4 , 5 ])
print (num1)
for i in num1: #遍历map对象的内容
print (i,end = " " )
print ()
#filter()
num2 = filter ( lambda x:x % 2 = = 1 ,[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ])
print (num2)
for j in num2: #遍历filter对象的内容
print (j,end = " " )
print ()
#reduce()
from functools import reduce
print ( reduce ( lambda x,y:x + y,[ 1 , 2 , 3 , 4 ], 10 )) #10是起始值
|
运行结果:
<map object at 0x0059f730>
2 4 6 8 10
<filter object at 0x0059f890>
1 3 5 7 9
20
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
|
name = [ "joe" , "jack" , "tom" , "susan" ]
age = [ 17 , 18 , 20 , 15 ]
sex = [ "m" , "m" , "m" , "f" ]
#案例一——格式化英文名。首字母大写,其他小写
names = map ( lambda t:t[ 0 : 1 ].upper() + t[ 1 :].lower(),name)
for stu_name in names:
print (stu_name,end = " " )
print ()
#案例二——将三个序列结合到一起,形成一个集合
newstu = map ( lambda n,a,s:(n,a,s),name,age,sex)
student = []
for tup in newstu:
student.append(tup)
print (student)
#案例三——过滤性别为男的用户
males = filter ( lambda x:x[ 2 ] = = "m" ,student)
man = []
for m in males:
man.append(m)
print (man)
#案例四——求性别为男的用户的平均年龄
from functools import reduce
man_count = len (man)
total_age = reduce ( lambda x,y:x + y[ 1 ],man, 0 )
print ( "总年龄:" ,total_age)
print ( "平均年龄:%.2f" % (total_age / man_count))
|
运行结果:
joe jack tom susan
[('joe', 17, 'm'), ('jack', 18, 'm'), ('tom', 20, 'm'), ('susan', 15, 'f')]
[('joe', 17, 'm'), ('jack', 18, 'm'), ('tom', 20, 'm')]
总年龄: 55
平均年龄:18.33
11、约瑟夫环
(1)一群人围在一起坐成环状(如:n)
(2)从某个编号开始报数(如:k)
(3)数到某数(如:m)的时候,此人出列,下一个人重新报数
(4)一直循环,直到所有人出列,约瑟夫环结束
约瑟夫环实现代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#约瑟夫环问题
# n=9(总人数) m = 3(报数) k:索引
#k = (k+(m-1))%len(list)
def func(n,m):
#生成一个列表
people = list ( range ( 1 ,n + 1 ))
k = 0 #定义开始的索引
#开始循环报数
while len (people) > 2 :
k = (k + (m - 1 )) % len (people)
print ( "kill:" ,people[k])
del (people[k])
print (k)
return people
print (func( 9 , 3 ))
|
运行结果:
kill: 3
2
kill: 6
4
kill: 9
6
kill: 4
2
kill: 8
4
kill: 5
2
kill: 2
1
[1, 7]
12、函数重载
在python中,没有函数重载,若非要使用函数重载,则后边的同名函数会覆盖掉前面的函数。
1
2
3
4
5
6
7
8
9
|
#函数重载
def test(x):
print (x)
def test(x,y):
print (x + y)
#test(1) #出错
test( 1 , 2 ) #覆盖test(x)
|
运行结果:
3
13、函数的嵌套和闭包
(1)函数嵌套:在函数内部再定义新的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:zhengzhengliu
#函数嵌套
def test():
def test1():
def test2():
print ( "hello" )
return test2
return test1
res = test() #test函数返回值res是一个函数,等价于res ==> test1
re = res() #res() ==>test1() ,test1函数返回值re是一个函数,re==>test2
re() #re() ==> test2()
|
运行结果:
hello
(2)闭包:内部函数可以取到外部函数的局部变量
1
2
3
4
5
6
7
8
9
10
11
|
#闭包:内部函数可以取到外部函数的局部变量
def test(x):
def test1(y):
def test2(z):
print (x + y + z)
return test2
return test1
res = test( 10 )
re = res( 20 )
re( 30 )
|
运行结果:
6
14、装饰器
(1)形象举例:照片与相框
照片:被装饰的对象,相框:装饰对象。
装饰作用:动态扩展装饰,即:不会改变被装饰的对象(照片)的内容,只是动态改变装饰的对象(相框)。
(2)装饰器修饰无参数的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:zhengzhengliu
#装饰器——日志管理
def log(func): #log(func)==> func = delete(delete函数作为实参传入到func)
def warp():
print ( "logger strating..." )
func() #运行delete
print ( "logger ending..." )
return warp
@log #用log来装饰delete,等价于delete = log(delete) = warp
def delete():
print ( "deleting..." )
delete() #执行warp
|
运行结果:
logger strating...
deleting...
logger ending...
(3)装饰器修饰有参数和返回值的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#装饰器修饰有参数、有返回值的函数
def log(func): #log(func)==> func = delete(delete函数作为实参传入到func)
def warp( * args, * * kwargs):
print ( "logger strating..." )
res = func( * args, * * kwargs) #运行delete
print (res)
print ( "logger ending..." )
return warp
@log #用log来装饰delete,等价于delete = log(delete) = warp
def delete(name,age):
print ( "deleting..." )
print (name,age)
return "delete success"
delete( "liu" , 20 ) #执行warp
|
运行结果:
logger strating...
deleting...
liu 20
delete success
logger ending...
(4)装饰器自身带有参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#装饰器带有参数
def log(i):
def warp1(func):
def warp2( * args, * * kwargs):
print ( "logger strating..." )
if i> 0 :
print ( "logging success..." )
func( * args, * * kwargs)
else :
print ( "logging failed..." )
print ( "logger ending..." )
return warp2
return warp1
@log ( 1 )
def delete():
print ( "deleting..." )
delete()
|
运行结果:
logger strating...
logging success...
deleting...
logger ending...
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
|
#装饰器带有参数
def log(i):
def warp1(func):
def warp2( * args, * * kwargs):
print ( "logger strating..." )
if i> 0 :
print ( "logging success..." )
func( * args, * * kwargs)
else :
print ( "logging failed..." )
print ( "logger ending..." )
return warp2
return warp1
@log ( - 1 )
def delete():
print ( "deleting..." )
delete()
#logger strating...
logging failed...
logger ending...
|
15、迭代器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:zhengzhengliu
#迭代器——笛卡尔积
import itertools
x = range ( 1 , 6 )
coml = itertools.combinations(x, 3 ) #排列
coml2 = itertools.permutations(x, 4 ) #组合
y = [ "a" , "b" , "c" ]
coml3 = itertools.product(x,y) #笛卡尔积
coml4 = itertools.chain(coml,coml2,coml3)
for h in coml4:
print (h)
|
运行结果:
(1, 2, 3)
(1, 2, 4)
(1, 3, 4)
(2, 3, 4)
(1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)
(1, 'a')
(1, 'b')
(1, 'c')
(2, 'a')
(2, 'b')
(2, 'c')
(3, 'a')
(3, 'b')
(3, 'c')
(4, 'a')
(4, 'b')
(4, 'c')
希望本文所述对大家python程序设计有所帮助。
原文链接:https://blog.csdn.net/loveliuzz/article/details/78149994