Python入门篇之函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python入门篇之函数相关的知识,希望对你有一定的参考价值。
1、函数
1.1、编程的方式:
(1)面向对象 -->华山派 -->独门秘籍:类 -->定义关键字:class
(2)面向过程 -->少林派 -->独门秘籍:过程 -->定义关键字:def
(3)函数式编程 -->逍遥派 -->独门秘籍:函数 -->定义关键字:def
1.2、函数是什么?
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
2.3、函数语法定义:
函数语法:
def 函数名(参数1,参数2,参数3,...):
‘‘‘注释‘‘‘
函数体
return 返回的值
python演示:
def auth(user,password):
‘‘‘
auth function
:param user: 用户名
:param password: 密码
:return: 认证结果
‘‘‘
if user == ‘kim‘ and password == ‘123‘:
return 0
else:
return 1
user = input("用户名:").strip()
pwd = input("密码:").strip()
res=auth(user,pwd)
print(res)
执行结果:
用户名:kim
密码:123
0
2.4、函数返回值
无return->None
return 1个值->返回1个值
return 逗号分隔多个值->元组
要想获取函数的执行结果,就可以用return语句把结果返回
注意:
函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
如果未在函数中指定return,那这个函数的返回值为None
什么时候该有返回值?
调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
什么时候不需要有返回值?
调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
通常无参函数不需要有返回值
2.5、函数的参数
形参:形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参(实参个数,类型应该与形参一一对应)
实参:实际参数,调用函数时传给函数的参数,可以是变量,常量,表达式,函数,传给形参。
区别:形参是虚拟的,不占用内存空间,形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据单向传送,实参传给形参,不能形参传给实参。
★★★★★关键参数是不能写在位置参数前面的!!!!!!
def test1(x,y):
print(x,y)
test1(1,2)-->位置调用,和形参一一对应
test1(x=1,y=2)-->关键字调用,与形参顺序无关
****************************************
默认参数:
def test1(x,y=2): -->y有默认值为2
print(x,y)
test1(1,3)
默认参数特点:调用参数的时候,默认参数非必须传递
默认参数用途:默认安装值,端口等
参数组:
*args-->接收多个参数,以元组的方式进行存储
**kwargs-->接受N个关键字参数,以字典的方式进行存储
2.6、总结:
#1、位置参数:按照从左到右的顺序定义的参数
位置形参:必选参数
位置实参:按照位置给形参传值
def test1(x,y):
print(x,y)
test1(1,2) #位置参数
test1(x=4,y=6) #关键字参数
执行结果:
1 2
4 6
#2、关键字参数:按照key=value的形式定义的实参
无需按照位置为形参传值
注意的问题:
1. 关键字实参必须在位置实参右面
2. 对同一个形参不能重复传值
#3、默认参数:形参在定义时就已经为其赋值
可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
注意的问题:
1. 只在定义时赋值一次
2. 默认参数的定义应该在位置形参右面
3. 默认参数通常应该定义成不可变类型
def test2(x,y=3): #默认参数y的值为3
print(x,y)
test2(2)
test2(2,6)
执行结果:
2 3
2 6
#4、可变长参数(*args,**kwargs):
可变长指的是实参值的个数不固定
而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它
def test3(*args): #可变长参数,使用*args接收N个位置参数,并且以元组的方式存储
print(args)
test3(1,2,3,4,5,6)
执行结果:(1, 2, 3, 4, 5, 6)
def test4(name,*args): #可变长参数和位置参数混合使用
print(name,args)
test4(‘alex‘,4,5,6)
test4(1,*[1,2,3])
执行结果:
alex (4, 5, 6)
1 (1, 2, 3)
def test5(x,y,**kwargs): #**kwargs接受N个关键字参数,以字典的方式进行存储
print(x,y)
print(kwargs)
test5(1,2,c=3,d=4,e=5)
test5(1,y=2,**{‘a‘:1,‘b‘:2,‘c‘:3})
执行结果:
1 2
{‘d‘: 4, ‘e‘: 5, ‘c‘: 3}
1 2
{‘a‘: 1, ‘b‘: 2, ‘c‘: 3}
def test6(*args,**kwargs):
print(args)
print(kwargs)
test6(5,6,7,a=1,b=5) #位置参数必须在关键参数的前面,否则会报错
执行结果:
(5, 6, 7)
{‘a‘: 1, ‘b‘: 5}
3、全局与局部变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
school="oldboy" --->全局变量school
def change_name(name):
#global school -->强制修改全局变量,需要进行申明:global 变量名,最好别用此方法
school="MaGe linux"
print("before change:",name,school)
name="Alex li" #局部变量,只在函数体内生效,这个函数就是此变量的作用域
print("after change:",name)
name="alex"
change_name(name)
print(name)
print(school)
执行结果:
before change: alex MaGe linux
after change: Alex li
alex
oldboy
★★注意:在列表,字典,集合,类等特殊类型变量在函数体内是可以进行修改的,如下演示:
names = ["Alex","Jack","Rain"]
def change_name():
names[0] = "哈哈"
print("inside :",names)
change_name()
print(names)
执行结果:
inside : [‘哈哈‘, ‘Jack‘, ‘Rain‘]
outside : [‘哈哈‘, ‘Jack‘, ‘Rain‘]
4、函数递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
递归特性:
(1).必须有一个明确的结束条件
(2)每次进入更深一层递归时,问题规模相比上次递归都应有所减少
(3)递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
def calc(n):
print(n)
if int(n / 2) == 0:
return n
return calc(int(n / 2))
calc(10)
执行结果:
10
5
2
1
5、函数式编程介绍
函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。
函数式编程中的函数这个术语不是指计算机中的函数(实际上是Subroutine),而是指数学中的函数,即自变量的映射。也就是说一个函数的值仅决定于函数参数的值,不依赖其他状态。比如sqrt(x)函数计算x的平方根,只要x不变,不论什么时候调用,调用几次,值都是不变的。
Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
一、定义
简单说,"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。
主要思想是把运算过程尽量写成一系列嵌套的函数调用。举例来说,现在有这样一个数学表达式:
(1 + 2) * 3 - 4
传统的过程式编程,可能这样写:
var a = 1 + 2;
var b = a * 3;
var c = b - 4;
函数式编程要求使用函数,我们可以把运算过程定义为不同的函数,然后写成下面这样:
var result = subtract(multiply(add(1,2), 3), 4);
这段代码再演进以下,可以变成这样
add(1,2).multiply(3).subtract(4)
这基本就是自然语言的表达了。再看下面的代码,大家应该一眼就能明白它的意思吧:
merge([1,2],[3,4]).sort().search("2")
因此,函数式编程的代码更容易理解。
###13.10、高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def add(x,y,f):
return f(x)+f(y)
res = add(3,-6,abs) #abs本身为一个函数,取绝对值
print(res)
执行结果:
9
6、函数练习:
1、写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批了修改操作
2、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
def count(msg):
res={
‘num‘:0,
‘string‘:0,
‘space‘:0,
‘other‘:0
}
for s in msg:
if s.isdigit():
res[‘num‘]+=1
elif s.isalpha():
res[‘string‘]+=1
elif s.isspace():
res[‘space‘]+=1
else:
res[‘other‘]+=1
return res
res=count(‘hello world ! 123‘)
print(res)
3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
def check_list(msg):
while type(msg) == list:
if len(msg) >2:
msg=msg[0:2]
return msg
print(check_list([1,2,3,4,5,6,7]))
5、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
def check_list2(seq):
seq=seq[::2]---------->从头遍历到尾,步长为2
return seq
print(check_list2([1,2,3,4,5]))
6、写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
方法一:
def check_dict(seq):
d={}
for k, v in seq.items():
if len(v) > 2:
d[k] = v[0:2]
return d
print(check_dict({‘k1‘:‘abcdef‘,‘k2‘:[1,2,3,4],‘k3‘:(‘a‘,‘b‘,‘c‘)}))
执行结果:
{‘k2‘: [1, 2], ‘k1‘: ‘ab‘, ‘k3‘: (‘a‘, ‘b‘)}
方法二:
def check_dict(seq):
d={}
for i in seq:
if len(seq[i]) > 2:
d[i] = seq[i][0:2]
return d
print(check_dict({‘k1‘:‘abcdef‘,‘k2‘:[1,2,3,4],‘k3‘:(‘a‘,‘b‘,‘c‘)}))
执行结果:
{‘k2‘: [1, 2], ‘k1‘: ‘ab‘, ‘k3‘: (‘a‘, ‘b‘)}
以上是关于Python入门篇之函数的主要内容,如果未能解决你的问题,请参考以下文章