Python的内置的函数

round()
    a = 1.12586
    #保留小数的函数,四舍五入,参数为保留小数点后的位数
    print(round(a,2))
    快速查看内置函数功能:命令行直接输入python,进入RPEL,使用help()函数
        >>> help(round)
            Help on built-in function round in module builtins:
            round(...)
            round(number[, ndigits]) -> number

            Round a number to a given precision in decimal digits (default 0 digits).
            This returns an int when called with one argument, otherwise the
            same type as the number. ndi
打印出python之禅
    >>> import this
        The Zen of Python, by Tim Peters

        Beautiful is better than ugly.
        Explicit is better than implicit.
        Simple is better than complex.
        Complex is better than complicated.
        Flat is better than nested.
        Sparse is better than dense.
        Readability counts.
        Special cases aren't special enough to break the rules.
        Although practicality beats purity.
        Errors should never pass silently.
        Unless explicitly silenced.
        In the face of ambiguity, refuse the temptation to guess.
        There should be one-- and preferably only one --obvious way to do it.
        Although that way may not be obvious at first unless you're Dutch.
        Now is better than never.
        Although never is often better than *right* now.
        If the implementation is hard to explain, it's a bad idea.
        If the implementation is easy to explain, it may be a good idea.
        Namespaces are one honking great idea -- let's do more of those!

Python函数的特点:

  1. 功能性
  2. 隐藏细节
  3. 避免编写重复代码
  4. 组织代码
  5. 自定义函数

函数定义

def funcname(parameter_list):
    pass
上述函数定义有以下特点:
    1.parameter_list参数列表可以没有
    2.可以使用 return 返回函数结果,如果不写,则认为返回 None
    3.funcname不推荐与内置函数名相同,因为会同名并产生递归
        对于递归而言默认只允许为995,应该使用:
        #import sys
        #sys.setrecursionlimit(1000000) 修改最大递归层数
    4.对于函数不强制返回类型,可以动态返回类型

函数调用:

def add(x,y):
    return x+y
def printA(code):
    print (code)
    return
    print("a") #return 后的代码不执行

print(add(1,2),printA("abc")) #print(A,B,C)可以连续打印,打印在同一行
打印:
    abc            为什么先打印abc?
    3 None         为什么打印None不换行?
解释:
    首先执行add函数,内部没有打印,但是返回3,暂存,接下来执行printA函数
    此时printA内打印出abc,且printA没有return即返回值为None,此时,
    print(3,None),然后就在同一行打印出3,None,之前已经打印了abc

对于多个参数的函数调用:

def re_two_1(skill_1, skill_2):
    re_1 = skill_1
    re_2 = skill_2
    return (re_1,re_2)
def re_two_2(skill_1, skill_2):
    re_1 = skill_1
    re_2 = skill_2
    return re_1,re_2
print(re_two_1(1,2))    #打印 (1, 2)
print(re_two_2(1,2))    #打印 (1, 2)
注意:
    不用显式的使用元组,直接逗号罗列即可返回一个元组

拆分多个返回结果:
    第一种方法:不推荐,只是使用无意义的下标
        res = re_two_2(1,2)
        print(res[0],res[1]) 
    第二种方法:序列解包,有意义
        r1,r2 = re_two_2(1,2)
        print(r1,r2) 

序列解包:

必须严格对照,否则报错
    a = 1
    b = 2
    c = 3
    a,b,c = 1,2,3
    print(a,b,c)
这也是一种解包的形式
    a = 1,2,3
    c,d,e = a
    print(c,d,e)

小贴士:

a = 1
b = 1
等价于 a = b = 1

函数的参数类型

调用上的区分:
1.必须参数,在参数列表中定义的参数,必须按顺序传入,否则报错
2.关键字参数,可以指定传入参数顺序,参数数量要对应,可以增加可读性
    add(y = 3,x = 2),这种形式调用,明确指定形参和实参的对应
    def add(x,y):   形式参数x,y
        return x+y
    print(add(1,2)) 实际参数1,2

3.默认参数
    如果函数输入过多,应该封装成对象,或者是添加默认参数
    如果不是默认参数,那么形参实参必须严格对照

正常的定义和调用:
    def print_student(name,age,school):
        print(name)
        print(age)
        print(school)
print_student('Jack',18,'清华')

带默认参数的定义和调用:
    def print_student_defalut(name,age,school= '清华'):
        print(name)
        print(age)
        print(school)

    print_student_defalut('Tommy',18)   不带默认值

    print_student_defalut('Tommy',18,'北大')            修改默认值
    print_student_defalut('Tommy',18,school = '北大')   修改默认值

注意:
    如果默认参数在必传参数的的中间,则报错:
        def print_student_defalut(name,school= '清华',age)
        上述定义不合规则,应该必传在前,默认参数在后
    如果有多个默认参数,例如2个,只想修改第二个默认参数时,必须使用关键字参数指明赋值
        def add(a,b,c=1,d='加法')
        上述只修改d时,调用add(2,3,'减法'),这是错误的,默认参数列表对应错误
    同样,多个默认参数在调用时,调用的形参也必须按照默认参数都放在后面的规范,不能夹杂调用
        add(2,c=1,3,d='减法')
        上述虽然使用了关键参数,但是夹杂定义,仍然报错
4.可变参数
    print('a','b','c') 具有可变的形参列表

    通过一般参数来实现可变输入:
        def nomal(param):
            print(param,type(param))
        nomal((1,2,3,5))    输出#(1, 2, 3, 5) <class 'tuple'> 

    可变输入形式:
        def change(*param):
            print(param,type(param))
        change(1,2,3,5)     输出#(1, 2, 3, 5) <class 'tuple'>
    注意:
        对于有动态参数的change函数,如果change((1,2,3)),传入元组
        那么进入函数后会生成二维元组((1,2,3)),此时可以用change(*(1,2,3))
        上述方式采用*号,将传入元组类似解包,去掉元组外壳

注意混合参数的调用:

def demo(param1,param2 = '默认值',*param3):
    print(param1,type(param))
    print(param2,type(param))
    print(param3,type(param))

如果想跳过默认值,直接赋值可变参数,如下形式:    
    demo(1,2,3)这样仍然给 默认参数赋值2 ,这是不行的

首先要修改默认参数,都放到最后
    def demo(param1,,*param2,param3 = '默认值'):
        print(param1,type(param))
        print(param2,type(param))
        print(param3,type(param))
    如果想修改默认值,使用demo(1,2,3,'修改'),并不能达到目的,其会将(2,3,'修改')作为可变参数
然后:
    正确方法是demo(1,2,3,param3 ='修改')
    上述方法,指明默认参数,而且可变参数也正确的识别为(2,3)

综上,混合参数函数的调用比较复杂,在函数中尽量避免使用

高级传参:

带可变参数的函数在调用时传入参数的解包:
    def pingfanghe(*param):
        sum = 0
        for i in param:
            sum += i*i
        print(sum)
    pingfanghe(1,2,3)           # 14
    pingfanghe(*[1,2,3,4])      # 30    注意此处的*号

使用**传入字典:
    def print_age(**param):
        print(param)
    print_age(xiaoming=18,Tom=24,Lina=13)
    # {'xiaoming': 18, 'Tom': 24, 'Lina': 13}

遍历字典;
    def print_age1(**param):
        for c in param:
            print(c)
    print_age1(xiaoming=18,Tom=24,Lina=13)
    输出:
        #Tom
        #Lina
        #xiaoming

    def print_age2(**param):
        for a,b in param:
            print(b)
    print_age2(xiaoming=18,Tom=24,Lina=13)
    输出:
        #Lina : 13
        #xiaoming : 18
        #Tom : 24

传入字典:
    dic = {'xiaoming':18,'Tom':24,'Lina':13}
    print_age2(**dic)
    输出:
        #xiaoming : 18
        #Tom : 24
        #Lina : 13
    传入空值时什么都不做
        print_age2()    输出空白

指明传入字典的映射:
    def print_age2(**param):
        print(param)
        for a,b in param:
            print(a,b)
    print_age2( Jack = 18,Tom = 24,Lina = 13) #注意使用方式

变量作用域

示例代码:
    c = 50  #全局变量
    def add(x, y):
        c = x + y   # 局部变量 c 作用域只是在函数内部,相当于新变量,与外部的 c 无关
        print(c)
    add(1,2)    # c = 3
    print(c)    # c = 50

注意:
    对于控制语句,python的特性:
        for while if 内定义的变量,在结束体之外也能访问
            for x in range(0,3):
            a = 'a'
            print(a)    # 可以输出a
        for while if 内接收的变量,与for同级的变量可以直接引用
            a = 10
            for x in range(0,1):
            print(a)       # 可以打印出10
    原因:Python只有函数作用域,没有块作用域

函数的作用域:同变量一样

示例代码:
    c = 1
    def func1():
        c = 2
        def func2():
            c = 3
            print(c)
        func2()     #func2作用域 只限于函数func1内
    func1()         #调用func1最终会调用func2,然后执行打印

作用域链

作用域具有逐级寻找的过程:
    c = 1
    def func1():
        def func2():
            print(c)    # 可以打印c,作用域链,逐级寻找
            a = 2
        func2()      
    func1()         
    print(a)    # 不可以打印a,作用域出错

global关键字:

示例代码:
    c = 1
    def func1():
        def func2():
            print(c)    # 可以打印c,作用域链,逐级寻找
            global a    # 注意这里使用global关键字
            a = 2       # 注意:使用global a = 2 是错误的
        func2()      
    func1()         
    print(a)    # global修饰后可以打印,同样体现了作用域链
注意:
    对于全局变量,包括global,可以在全部模块中都被使用,只需 import相关模块