Python基础函数、递归、内置函数

一、数学定义中的函数与Python中的函数

  初中数学定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定值,y都有唯一确定的值与之对应,那么我们就把x称为自变量,把y称为因变量,与是x的函数。自变量x的取值范围叫做这个函数的定义域。

  例如:y=2*x

python中函数的定义:函数是逻辑结构化和过程化的一种编程方法。

# Python中函数定义方法

def test(x):
    "the function definitions"
    x+=1
    return x

def :定义函数的关键字
test:函数名
():内可定义形参
“” :文档描述(非必要,但是强烈建议为你的函数添加描述信息)
x+=1 :泛指代码块或程序处理逻辑
return :定义返回值

调用运行:可以带参数也可以不带
函数名()

补充:

1.编程语言中的函数与数学意义的函数是截然不同的两个概念,编程语言中的函数是通过一个函数名封装好一串用来完成某一特定功能的逻辑,数学定义的函数就是一个等式,等式在传入因变量值x不同会得到一个结果y,这一点与编程语言中类似(也是传入一个参数,得到一个返回值),不同的是数学意义的函数,传入值相同,得到的结果必然相同且没有任何变量的修改,而编程语言中的函数传入的参数相同返回值可不一定相同且可以修改其他全局变量的值(因为一个函数a的执行可能依赖于另一个函数b的结果,b可能得到不同的结果,那即便你给a传入相同的参数,那么a得到的结果也肯定不同)

2.函数式编程:先定义一个数学函数(数学建模),然后按照这个数学模型用编程语言去实现它。至于具体如何实现和这么做的好处、且看后续函数式编程。

二、为何使用函数

背景提要:

现在老板让你写一个监控程序,监控服务器的系统状况、当CPU、Memory、Disk等指标的使用量超过阈值时即发邮件报警,你写出了如下代码

while True:
    if cpu利用率 >90%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

    if  硬盘使用空间>90%
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

    if 内存占用率 >80%
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

上述代码实现了功能,但存在两个主要问题:

  1、代码重复过多。一个劲的copy and paste不符合高端程序的研发标准

  2、如果日后需要修改发邮件这段代码,比如加入群发功能,那你就需要在所有用到这段代码的地方修改一遍。

代码修复成如下的样子,会好的多

def 发送邮件(内容):
    #发送邮件提醒
    连接邮箱服务器
    发送邮件
    关闭连接

while True:
    
    if cpu利用率>90%
        发送邮件(’CPU报警‘)
    if 硬盘使用空间 > 90%
        发送邮件(’硬盘报警’)
    if 内存占用 > 80%
        发送邮件(‘内存报警’)

使用函数的好处:

  1、代码重用性好

  2、保持一致性、易于维护

  3、可扩展性强

三、函数和过程

过程的定义:过程就是简单特殊没有返回值的函数

这么看来我们在讨论为何使用函数的时候引入的函数,都没有返回值,没有返回值就是过程,但是在python中会有如下的现象发生

 1 def test01():
 2     msg='hello The little green frog'
 3     print msg
 4 
 5 def test02():
 6     msg = 'hello Mr Wang'
 7     print msg
 8     return msg
 9 
10 t1=test01()
11 t2=test02()
12 
13 print 'from test01 return is [%s]' %t1
14 print 'from test02 return is [%s]' %t2

总结:当一个函数/过程没有使用return显示定义返回值时,python解释器会隐式的返回None,所以在python中即便是过程也算作函数。

 1 def test01():
 2     pass
 3 
 4 def test02():
 5     return 0
 6 
 7 def test03():
 8     return 0,10,'hello',['Alex','lb'],{'WuDaLang':'lb'}
 9 
10 t1=test01()
11 t2=test02()
12 t3=test03()
13 
14 print 'from test01 return is [%s]:' %type(t1),t1
15 print 'from test02 return is [%s]:' %type(t2),t2
16 print 'from test03 return is [%s]: %type(t3),t3

总结:

  返回值数=0:返回None

  返回值数=1:返回Object

  返回值数>1:返回tuple

四、函数参数

1、形参变量只有在被调用时才分配内存单元,在调用结束时,即可释放所分配的内存单元。因此,形参只有在函数的内部有效,函数调用结束返回主调用函数后则不能再使用该形参变量。

2、实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,再进行函数调用时,它们都必须有确定的值,以便把这些值传给行参。因此,应预先赋值,输入等办法使参数获得确定的值。

3、位置参数与关键字参数

4、默认参数

5、参数组

五、局部变量和全局变量

在子程序中定义的变量称为局部变量,在程序一开始定义的变量称为全局变量。全局变量的作用域是整个程序,局部变量作用域是定义该变量的子程序。

当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用;其他地方全局变量起作用。

六、前向引用之‘函数即变量

 1 def action():
 2     print 'in the action'
 3     logger()
 4 action()
 5 #报错nameError:gloable name 'logger' is not defined
 6 
 7 def logger():
 8     print 'in the logger'
 9 def action():
10     print 'in the action'
11     logger()
12 action()
13 
14 def action():
15     print 'in the action'
16     logger()
17 def logger():
18     print 'in the logger()'
19 action()

七、嵌套函数和作用域

 1 name="Alex"
 2 
 3 def change_name():
 4     name="Alex2"
 5     def change_name2():
 6         name="Alex3"
 7         print("第三层打印“,name)
 8         
 9 
10     change_name2()
11     print("第二层打印”,name)
12 change_name()
13 print("最外层打印“,name)

此时,在最外层调用chang_name2()会出现什么效果,报错了,作用域在定义函数式就已经被固定了,不会随着位置的改变而改变。

八、递归和调用

在函数内部,可以调用其他函数,如果在调用一个函数的过程中直接或间接调用自身本身

1 def cal(n):
2     print(n)
3     if int(n/2)==0
4         return n
5     return cal(int (n/2))
6 
7 cal(10)

递归的特性:

1、必须有一个明确的结束条件

2、每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3、递归效率不高,递归层次过多或导致栈溢出

九、匿名函数

匿名函数就是不需要显式的指定函数

# 这段代码
def calc(n):
    return n**n
print(cal(10))

# 换成匿名函数
calc = lambda n : n**n
print(calc(10))

 你也许会说,用上面这个东西没感觉方便,匿名函数主要是和其他函数搭配使用的,如下

l= [3,2,100,999,213,1111,31121,333]
print(max(l))

dic={'k1':10,'k2':100,'k3':30}

print(max(dic))
print(dic[max(dic,key=lambda k:dic[k])])

res= map(lambda x:x**2,[1,5,7,4,8])

for i in res :
    print(i)

十、函数式编程

通俗的理解:函数的参数传入,是函数吃进去的食物,而函数return的返回值,是函数拉出来的结果,面向过程的思路就是:把程序的执行当成一串首尾相连的函数,一个函数吃,拉出来的东西给另一个函数吃,另一个函数吃了再继续拉给下一个函数吃。。。

例如用户登录程序:

前端接收处理用户请求-->将用户信息传给逻辑层-->将用户的信息写入数据库

高阶函数:

满足如下特征之一的函数就是高阶函数:1、函数的传入参数是一个函数名。2、函数的返回值是一个函数名

十一、内置函数

猜你喜欢

转载自www.cnblogs.com/xuanlin666/p/10804375.html