zoukankan      html  css  js  c++  java
  • Python6

    一、函数的基本知识

    定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

    特性:

    1. 减少重复代码
    2. 使程序变的可扩展
    3. 使程序变得易维护

    1.1函数定义规则:

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

    1.2语法格式:

    def 函数名(参数列表):
        函数体

    1.3函数的参数:

    • 默认参数
    • 位置参数
    • 关键参数
    • 非固定参数  *args 和 **kwargs

    默认参数:

    调用函数时,如果没有传递参数,则会使用默认参数。

    #可写函数说明
    def printinfo( name, age = 35 ):
       "打印任何传入的字符串"
       print ("名字: ", name);
       print ("年龄: ", age);
       return;
     
    #调用printinfo函数
    printinfo( age=50, name="runoob" );
    print ("------------------------")
    printinfo( name="runoob" );
    默认参数实例

    位置参数:

    注意: 位置参数的顺序不可变。

    关键字参数:

    关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。

    使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

    def printme( str ):
       "打印任何传入的字符串"
       print (str);
       return;
     
    #调用printme函数
    printme( str = "菜鸟教程");
    关键字参数实例1

    关键字参数的使用不需要指定顺序

    #可写函数说明
    def printinfo( name, age ):
       "打印任何传入的字符串"
       print ("名字: ", name);
       print ("年龄: ", age);
       return;
     
    #调用printinfo函数
    printinfo( age=50, name="runoob" );
    关键字参数实例2

    非固定参数:

    非固定参数或者不定长参数,上述3种参数不同,声明时不会命名,基本语法:

    def functionname([formal_args,] *var_args_tuple ):
       "函数_文档字符串"
       function_suite
       return [expression]

    加了星号(*)的变量名会存放所有未命名的变量参数。如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。

    # 可写函数说明
    def printinfo( arg1, *vartuple ):
       "打印任何传入的参数"
       print ("输出: ")
       print (arg1)
       for var in vartuple:
          print (var)
       return;
     
    # 调用printinfo 函数
    printinfo( 10 );
    printinfo( 70, 60, 50 );
    不定长参数实例

    需要注意:

    1. 关键参数必须放在位置参数之后。
    2. *args 会把多传入的位置参数变成一个元组(tuple)形式
    3. *kwargs 会把多传入的关键参数变成一个字典dict形式

    1.4全局与局部变量:

    在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
    全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
    当全局变量与局部变量同名时:
    在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
     
    只要有点编程基础,全局和局部变量的概念就应该理解。就不过多赘述了....
    需要注意的:
    • 对于数字和字符串来说在函数内部默认是不能更改全局变量的
    • 如果非要在函数内硬改全局变量,需要在函数内添加 global 函数名,具体见下面global实例1
    • 但是这种做法并不推荐
    Tuple本身不可更改,所以除了数字类型、字符串类型、元组类型,列表和字典在函数内部调用是可以更改的,具体见实例2
    myname = "Rong"
    
    def change_name():
        global myname    #不推荐,不要用
        myname = "TanRong"
    
    change_name()
    print(myname)
    global实例1
    names_list = ["Jack","Tom","xiaohong"]
    info_dict = {"name": "Jack", "age":18, "sex":""}
    
    def change_name():
        # global myname
        # myname = "TanRong"
        names_list[0] = "xiaoming"
        info_dict["age"] = 20
    
    change_name()
    # print(myname)
    print(names_list)
    print(info_dict)
    
    输出:
    ['xiaoming', 'Tom', 'xiaohong']
    {'name': 'Jack', 'age': 20, 'sex': ''}
    实例2

    1.5返回值:

    1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
    2. 如果未在函数中指定return,那这个函数的返回值为None 

    二、特殊函数

    2.1递归函数:

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

    def calc(n):
        print(n)
        if int(n/2) ==0:
            return n
        return calc(int(n/2))
     
    calc(10)
     
    输出:
    10
    5
    2
    1
    Python实例

    递归特性:

    1. 必须有一个明确的结束条件,, 默认深度好像是999

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

    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(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("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)
    递归函数实际应用案例,二分查找

     2.2嵌套函数:

    顾名思义,函数内定义并调用函数

    name = "Tan"
    def change_name():
        name = "Tan2"
    
        def change_name2():
            name = "Tan3"
            print("第3层打印", name)
    
        change_name2()  # 调用内层函数
        print("第2层打印", name)
    
    change_name()
    print("最外层打印", name)
    嵌套函数实例

    修改嵌套作用域:

    要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字

    def outer():
        myage = 118
    
        def inner():
            nonlocal myage # nonlocal关键字声明
            myage = 126
            print(myage)
        inner()
        print(myage)
    
    outer()
    
    输出:
    126
    126
    nonlocal实例

    2.3匿名函数:

    python 使用 lambda 来创建匿名函数。

    所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

    • lambda 只是一个表达式,函数体比 def 简单很多。
    • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
    • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
    • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率

    语法如下:

    lambda [arg1 [,arg2,.....argn]]:expression
    sum = lambda a,b: a + b
    print(sum(30,50))
    匿名函数实例1
    res = map(lambda x:x**2, [1,2,3,4,5])
    for i in res:
        print(i)
    
    输出:
    1
    4
    9
    16
    25
    匿名函数实例2

    2.4高阶函数

    变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

    def add(x,y,f):
        return f(x) + f(y)
     
     
    res = add(3,-6,abs)
    print(res)
    高阶函数实例

    2.5内置函数

    Built-in Functions  
    abs() dict() help() min() setattr()
    all() dir() hex() next() slice()
    any() divmod() id() object() sorted()
    ascii() enumerate() input() oct() staticmethod()
    bin() eval() int() open() str()
    bool() exec() isinstance() ord() sum()
    bytearray() filter() issubclass() pow() super()
    bytes() float() iter() print() tuple()
    callable() format() len() property() type()
    chr() frozenset() list() range() vars()
    classmethod() getattr() locals() repr() zip()
    compile() globals() map() reversed() __import__()
    complex() hasattr() max() round()  
    delattr() hash() memoryview() set()  

    详解:https://docs.python.org/3/library/functions.html?highlight=built#ascii

    #compile
    f = open("函数递归.py")
    data =compile(f.read(),'','exec')
    exec(data)
    
    
    #print
    msg = "又回到最初的起点"
    f = open("tofile","w")
    print(msg,"记忆中你青涩的脸",sep="|",end="",file=f)
    
    
    # #slice
    # a = range(20)
    # pattern = slice(3,8,2)
    # for i in a[pattern]: #等于a[3:8:2]
    #     print(i)
    #
    #
    
    
    #memoryview
    #usage:
    #>>> memoryview(b'abcd')
    #<memory at 0x104069648>
    #在进行切片并赋值数据时,不需要重新copy原列表数据,可以直接映射原数据内存,
    import time
    for n in (100000, 200000, 300000, 400000):
        data = b'x'*n
        start = time.time()
        b = data
        while b:
            b = b[1:]
        print('bytes', n, time.time()-start)
    
    for n in (100000, 200000, 300000, 400000):
        data = b'x'*n
        start = time.time()
        b = memoryview(data)
        while b:
            b = b[1:]
        print('memoryview', n, time.time()-start)
    内置函数实例
  • 相关阅读:
    未能加载文件或程序集“xxx, Version=x.x.x.x, Culture=neutral, PublicKeyToken=xxxxxxxxxxxx”或它的某一个依赖项。系统找不到指定的文件
    RabbitMQ本地正常,发布到服务器上 出行连接失败
    Windows 服务 创建 安装 卸载 和调试
    CSS 格式化 一行一条
    ES6---new Promise()讲解,Promise对象是用来干嘛的?
    Win Server 2008 R2 IIS 默认只能添加一个 443 HTTPS 端口
    MVC 部分视图:Partial() 、RenderPartial() 、 Action() 、RenderAction() 、 RenderPage() 区别
    ;(function ($, undefined){ })(jQuery); 的使用及说明
    JS中的call()方法和apply()方法用法总结
    MongoDB服务无法启动,windows提示发生服务特定错误:100
  • 原文地址:https://www.cnblogs.com/tanrong/p/8467625.html
Copyright © 2011-2022 走看看