• python中的函数


    ---恢复内容开始---

    一 数学定义的函数与python中的函数

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

    例如y=2*x

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

    python中函数定义方法:
     2  
     3 def test(x):
     4     "The function definitions"
     5     x+=1
     6     return x
     7      
     8 def:定义函数的关键字
     9 test:函数名
    10 ():内可定义形参
    11 "":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
    12 x+=1:泛指代码块或程序处理逻辑
    13 return:定义返回值
    
    
    调用运行:可以带参数也可以不带
    函数名()

    补充:

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

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

    二 为何使用函数

    背景提要

    现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码

    while True:
     2     if cpu利用率 > 90%:
     3         #发送邮件提醒
     4         连接邮箱服务器
     5         发送邮件
     6         关闭连接
     7      
     8     if 硬盘使用空间 > 90%:
     9         #发送邮件提醒
    10         连接邮箱服务器
    11         发送邮件
    12         关闭连接
    13      
    14     if 内存占用 > 80%:
    15         #发送邮件提醒
    16         连接邮箱服务器
    17         发送邮件
    18         关闭连接
    

    三 函数和过程

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

    这么看来我们在讨论为何使用函数的的时候引入的函数,都没有返回值,没有返回值就是过程,没错,但是在python中有比较神奇的事情

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

    总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,

    所以在python中即便是过程也可以算作函数。

    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  
    15 print 'from test01 return is [%s]: ' %type(t1),t1
    16 print 'from test02 return is [%s]: ' %type(t2),t2
    17 print 'from test03 return is [%s]: ' %type(t3),t3

    返回值数=0:返回None

       返回值数=1:返回object

       返回值数>1:返回tuple

    四 函数参数

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

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

    3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)

    4.默认参数

    5.参数组

    五 局部变量和全局变量

    在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
    全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
    当全局变量与局部变量同名时:
    在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
    name='lhf'
     2 
     3 def change_name():
     4     print('我的名字',name)
     5 
     6 change_name()
     7 
     8 
     9 def change_name():
    10     name='帅了一笔'
    11     print('我的名字',name)
    12 
    13 change_name()
    14 print(name)
    15 
    16 
    17 
    18 def change_name():
    19     global name
    20     name='帅了一笔'
    21     print('我的名字',name)
    22 
    23 change_name()
    24 print(name)

    六 前向引用之'函数即变量'

    def action():
     2     print 'in the action'
     3     logger()
     4 action()
     5 报错NameError: global name 'logger' is not defined
     6 
     7 
     8 def logger():
     9     print 'in the logger'
    10 def action():
    11     print 'in the action'
    12     logger()
    13  
    14 action()
    15  
    16 
    17 def action():
    18     print 'in the action'
    19     logger()
    20 def logger():
    21     print 'in the logger'
    22  
    23 action() 

    七 嵌套函数和作用域

    看上面的标题的意思是,函数还能套函数?of course

    1 name = "Alex"
     2  
     3 def change_name():
     4     name = "Alex2"
     5  
     6     def change_name2():
     7         name = "Alex3"
     8         print("第3层打印",name)
     9  
    10     change_name2() #调用内层函数
    11     print("第2层打印",name)
    12  
    13  
    14 change_name()
    15 print("最外层打印",name)

    此时,在最外层调用change_name2()会出现什么效果?

    没错, 出错了, 为什么呢?

    作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变

    1 例一:
     2 name='alex'
     3 
     4 def foo():
     5     name='lhf'
     6     def bar():
     7         print(name)
     8     return bar
     9 
    10 func=foo()
    11 func()
    12 
    13 
    14 例二:
    15 name='alex'
    16 
    17 def foo():
    18     name='lhf'
    19     def bar():
    20         name='wupeiqi'
    21         def tt():
    22             print(name)
    23         return tt
    24     return bar
    25 
    26 func=foo()
    27 func()()

    八 递归

    在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

    def calc(n):
     2     print(n)
     3     if int(n/2) ==0:
     4         return n
     5     return calc(int(n/2))
     6  
     7 calc(10)
     8  
     9 输出:
    10 10
    11 5
    12 2
    13 1
    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    import time
    
    person_list=['alex','wupeiqi','yuanhao','linhaifeng']
    def ask_way(person_list):
        print('-'*60)
        if len(person_list) == 0:
            return '没人知道'
        person=person_list.pop(0)
        if person == 'linhaifeng':
            return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person
        print('hi 美男[%s],敢问路在何方' %person)
        print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' %(person,person_list))
        time.sleep(3)
        res=ask_way(person_list)
        # print('%s问的结果是: %res' %(person,res))
        return res
    
    
    
    res=ask_way(person_list)
    
    print(res)

    递归特性:

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

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

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

    堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 

    尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

    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("33[31;1m找的数在mid[%s]左面33[0m" % dataset[mid])
                return binary_search(dataset[0:mid], find_num)
            else:# 找的数在mid右面
                print("33[32;1m找的数在mid[%s]右面33[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 #这段代码
    2 def calc(n):
    3     return n**n
    4 print(calc(10))
    5  
    6 #换成匿名函数
    7 calc = lambda n:n**n
    8 print(calc(10))
    复制代码

    你也许会说,用上这个东西没感觉有毛方便呀, 。。。。呵呵,如果是这么用,确实没毛线改进,不过匿名函数主要是和其它函数搭配使用的呢,如下

    复制代码
    1 l=[3,2,100,999,213,1111,31121,333]
    2 print(max(l))
    3 
    4 dic={'k1':10,'k2':100,'k3':30}
    5 
    6 
    7 print(max(dic))
    8 print(dic[max(dic,key=lambda k:dic[k])])
    复制代码
    复制代码
     1 res = map(lambda x:x**2,[1,5,7,4,8])
     2 for i in res:
     3     print(i)
     4 
     5 输出
     6 1
     7 25
     8 49
     9 16
    10 64
    复制代码

     

  • 相关阅读:
    css文本及文本装饰
    css尺寸常用样式
    了解css的两大特性
    css长度单位及字体
    css颜色
    css选择器详解
    了解css
    html行级元素与块级元素以及meta标签的使用
    了解html表单
    html图片和html实体
  • 原文地址:https://www.cnblogs.com/pyyu/p/6814768.html
Copyright © 2020-2023  润新知