Python web开发 函数

一、函数的基本语法和特性

函数的定义

函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的。函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可。

python中函数的分类

  1. 内置函数
  2. 自定义函数

特性:

  1. 减少重复代码
  2. 使程序有更好的扩展性
  3. 让程序更容易维护
定义一个函数

你可以定义一个由自己想要功能的函数,以下是简单的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

 函数的语法

#函数
def fun1(a,b):      #a,b 是指形参       
    '''fun1'''
    print('in the fun1')
    return 0

#注意函数是有返回值的
#过程
def fun2():
    '''fun2'''
    print('in the fun2')
#没有返回值的函数我们一般让我是函数的过程
#函数式编程就是这种模式

二、函数的参数

参数:

首先说明,在python中,函数定义好后是存放在内存里面的,类似我们通常所说的变量。而形参没有任何实际意义,只有在被调用的时候才会分配内存单元,而函数调用结束后则会被释放;而实参可以是常量,变量、表达式、函数等,实参被调用时必须得有确定的值,这样才可以把这些值传给形参。

参数的分类:形参,默认参数,不定长参数,关键字参数

默认参数:即有些情况下,一些参数必须提供,默认的情况下是一个固定的值,只有在少数情况下会修改,这种情况可以选择默认参数。

不定长参数:在定义函数时,不确定用户需要传入多少个参数,这时使用不定长参数。

关键字参数:一般情况下,传入参数必须按照给定的参数顺序传入,若不一定知道参数的顺序,可以使用关键字参数来传入。

注意:在传入参数的时候位置参数必须在关键字参数的前面。

##参数形式
#1不传参
def fun1():
     print('不能传参数')


#2必备参数
def fun2(a):
     print('必须传参数:',a)


#3默认参数
def fun3(b=2):
     print('默认参数:',b)  #可传可不传
#可选参数
def fun4(*arg):  
     print('可传0个到多个:',arg)#可传0个到多个 包装成元组
#fun4(*[1,2])    加个* ,就把里面的壳去掉(解包)



#关键字参数
#定义的时候是跟必备参数一样的
#必须放到最后

def fun6(**kwarg):
     print('关键字参数',kwarg)# 可传0个到多个 包装成字典
#fun6(a=1,b=2)  遵循变量命名规则
#fun6(**{'a':1})   必须是字符串


##参数混合的时候   关键字参数放最后 根据定义的顺序 确保必备参数只能拿到值,并且只能一个
#必备参数+默认参数
def fun7(a,b=1):   #默认参数必须在必备参数的后面
     print(a,b)
     
def fun8(b,m=1,*a):
     print(b)
     print(m)
     print(a)

def fun8(*a,b,m):  #尽量不用这种方式,这种方式需要用关键字的方式传入参数
     print(a,b,m)
     print(b)

def fun9(*a,b,m=1):
     print(a,b,m)
     print(b)

一般情况下按照以下形式传入参数:这样更容易理解程序。

def fun1(x,y=2):
    print(x)
    print(y)

# fun1(1)      #默认参数,在调用函数的时候可以不传参
# fun1(1,3)     #也可以选择传参

def fun2(*args):   #不定长参数,当不确定参数的长度时用不定长参数
    print(args)

# fun2(1,3,4,5,'d')

def fun3(**kwargs):#关键字参数,接受N个关键字参数,并把它们转换为字典
    print(kwargs)

fun3(i = 'lll')

def fun4(a,b = 1,*args,**kwargs):
    print(a)
    print(b)
    print(args)
    print(kwargs)
fun4(1,2,3,3,3,x = 'lll')   #传参的时候关键字参数必须在位置参数后面

变量:

在函数中,变量分为全局变量和局部变量。

在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。

全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。

当全局变量与局部变量同名时:

在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。

school = 'oleboy'  #全局变量

def charge_school():
    school = 'TANZHOU'   #在函数里面是一个局部变量
    print(school)
# charge_school()
# print(school)
#上面可以看出,在调用函数后,函数外部并没有改变school的值

def charge_school2():
    global school
    school = 'TANZHOU'
    print(school)
charge_school2()
print(school)
#重上面看出,当申明global之后,函数内的变量成为了全局变量,在函数
#内也可以进行访问并修改,在日常工作中做好不要这么做


names = ['Alex','Jack','Wallace']
name_tuple= (1,2,3,4)

def charge_name():
    names[1]='金角大王'
    print(names)
charge_name()
print(names)

'''从上可看出,当函数内的变量和全局变量为可变对象时,在函数内可以对其进行修改
'''
a = 1   #全局变量

def fun():
    global a
    a = 2   #局部变量,正常情况下无法修改全局变量,若要修改用global  最好不要这么做
    print(a)

print(a)
b = fun()
print(a)

虽然在实例上,通过global可以将一个局部变量声明为全局变量,但是这种方式对于代码的可维护上非常不好,尽量避免这种操作。

三、返回值

函数的返回值可以是大多数的数据类型,也可以是变量名,函数名也可以是函数本身:

def text1():
    print('in the text1')
    return 0,{0,1},[0,1,3]

def text2():
    return text1  返回的是函数

y = text2()()  #可以进行调用

四、嵌套函数

嵌套函数指的是,函数内定义另一个函数例:

def fun1():
    print("fun1")
    def fun2():
       print("fun2")
    fun2()
>>a = fun1()
fun1  #先调用fun1,在fun1里面调用fun2
fun2

嵌套函数的具体用法将会在后面的学习中提到。

五、递归

递归函数是指函数内部调用自己,这样的函数就是递归函数。

def fun1(n):
    if n == 1:
        return 1      #递归的结束条件
    else:
        return fun1(n-1)+1
>>print(fun1(3))
3

递归的必备条件:

  1. 必须有一个明确的结束条件
  2. 每次进入更深层递归时,问题的规模相比上次递归都应有所减少

递归的局限性:

    递归的效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一次函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。有用栈的大小不是无限的,所以递归掉用的次数过多,就会导致栈溢出)

递归的应用,二分法查找:

data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]

def binary_search(dataset,find_num):
    print(dataset)

    if len(dataset) >1:
        mid = int(len(dataset)/2)
        if dataset[mid] == find_num:  #find it
            print("找到数字",dataset[mid])
        elif dataset[mid] > find_num :# 找的数在mid左面
            print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
            return binary_search(dataset[0:mid], find_num)   #再次调用原函数
        else:# 找的数在mid右面
            print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
            return binary_search(dataset[mid+1:],find_num)
    else:
        if dataset[0] == find_num:  #find it
            print("找到数字啦",dataset[0])
        else:
            print("没的分了,要找的数字[%s]不在列表里" % find_num)

>>binary_search(data,66)
[1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
找的数在mid[18]右面
[20, 21, 22, 23, 30, 32, 33, 35]
找的数在mid[30]右面
[32, 33, 35]
找的数在mid[33]右面
[35]
没的分了,要找的数字[66]不在列表里

六、匿名函数

匿名函数没有函数名,一般情况就是只调用一次,后续不会再调用。

cala = lambda n:n*n  #一般用于只调用一次
'''
相当于
def fun1(n):
    return n*n
'''
print(cala(10))

七、高阶函数

高阶函数指的是将函数名作为参数传入。

def high_fun(a,b,f):
    return f(a)+f(b)

>>a = high_fun(1,-2,abs)  #abs()求一个函数的绝对值
3

上面例子中,参数f可以任意的函数名。

八、内置函数

注:内置函数将会作为另一章进行详细的讲解。

转载于:https://my.oschina.net/u/3783639/blog/1788335

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值