跟着lucky老师学Python

第六章 函数

2019-04-01  本文已影响0人  帅气的Lucky

一 函数

  1. 什么是函数?

    函数是可以实现一些特定功能的小方法或是小程序。

    优点:

    1. 增加了代码的重复使用率 简化代码结构,增加了代码的复用度(重复使用的程度)
    2. 减少了代码量 提高了 代码 的可读性
    3. 提高了代码的维护
  2. 函数的定义

    使用def关键字 + 函数名():

    ​ 函数体

    def 函数名([参数]):
        函数体
    

    函数名:

    ​ 遵循变量命名规则

    注意:最后的return 表达式,可以不写,相当于return None

  3. 函数名

    使用统一标识符来定义函数名

    注意:

    • 函数名区分大小写
    • 函数可以重名 但是会被覆盖
  4. 函数的参数问题

    (1) 形参

    ​ 在函数定义的时候 在括号里 写入的变量称为 形参

    注意:

    1. 如果定义的函数有形参 且 没有默认值 那么在调用的时候 必须传实参 且传的实参的个数 不能大于 形参的个数
    2. 函数在定义的时候 如果形参都有默认值 那么传的实参 会将默认值 覆盖掉 此时的实参可传可不传
    3. 函数的形参的默认值 如果在形参中有的参数有默认值 有的没有 那么要将有默认值的参数 放在后面
    def add(x,y):  #形参  且没有默认值
        print(x,y)
    add(10,20)  #实参  实参的个数要和形参的个数对应上  前提是 形参没有默认值
    
    def test(x=10,y): #函数的形参的默认值  如果在形参中有的参数有默认值 有的没有 那么要将有默认值的参数 放在后面
    print(x,y)
    test() #SyntaxError   non-default argument follows default argument
    

    (2)关键字参数

    ​ 可以使用关键字 来改变我的形参与实参的默认从左到右的对应关系

    注意:

    ​ 关键字 要么就都给 要么就不给

    def test(x,y):
        print('x为',x,'y为',y)
    test(y=10,x=100)
    

    注意:

    1. 有形参的且没有默认值的时候 必须要有实参
    2. 有形参且有默认值的时候 实参可有可无( 默认参数必须放在最后面,否则会报错)
    3. 参数的位置可以改变 但是在使用的时候 形参名=实参的值
    4. 当有不确定参数传进来的时候 形参前方加* 来接收不确定的实参的值
python 函数的参数传递 注意:

不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

列如:

def demo1():
    print("我是函数")

#有参数
def sum(num1,num2):
    print(num1+num2)
sum(1,2) #默认值按照顺序传给形参
sum(num2=2,num1=1) #指定形参接收值
  1. 函数的返回值

  2. return 当函数体遇到return 那么return下面的代码将不会在执行 有return的函数可以将值赋给变量

    def demo():
        return "hello" #返回单个值
     return ["a","b"] #返回多个值 == return 1,2,4#元祖的形式
     print("我将不会在输出")
    var = demo()
    print(var)
    
  3. 如果没有返回值的函数 不能将值赋给变量 当赋值给变量 打印该变量为None

    def demo():
        print("没有返回值")
    print(demo()) #None
    

二 不定长参数

也就是传入的参数的个数不固定

​*(1) 不确定参数 形参名 以元组的形式去接收

def func(*args):
    print(args)#(1,5345,34) 元组类型
func(1,5345,34)

def func(a,b,*args):
    print(a) #1
    print(b) #5
    print(args)#(2,34)
func(1,5,2,34)
(2)不确定实参的接收 必须是 关键字 加值 接收以后 是 字典类型**
def func(**args):  #接收不确定的形参的值  以元组的形式
    print(args)
    for i in args:  #遍历元组
        print(i,args[i])

func2(x=1, y=2, z=3) #函数调用

(3) * 和 **一起作为形参
def func(*args,**dargs):
    print(args,dargs)
func(1,2,3,4,username="张三",password="123456")
(4)** 函数调用的时候的** 和参数**的接收
def func(**dic):
    print(dic) #{'name':'zs'}
x = {'name': 'zs'}
func(**x)

三 变量的作用域

  1. 在函数外部声明的变量为全局变量 在函数外部声明的变量为局部变量

    num = 10 #全局变量
    def demo():
        num = 2 #局部变量
    
  2. 在函数外部声明的变量 在函数内部可以获取到 在函数内部声明的变量在函数外部不能够获取到

    num = 3
    def demo():
        print(num)
    
  3. 关键字 global 声明变量函数内外使用同一个

    str1 = x
    def test():
        global str1  #将str1变量 声明为 全局变量  内外使用的都为同一个变量
                      #否则在函数内部是可以获取函数外的变量 但是修改以后 就会生成一个新的局部变量 和函数外的变量 不是同一个变量
        str1 = 2
    test()
    print(str1)
    
  4. 如果函数发生嵌套 那么内部的函数通过 nonlocal 可以获取外层函数的变量

    def  Test():
        num=10 #函数内部都是局部变量
        def Testin():
            nonlocal num #内层testin,直接操作外层Test,
            num=1000 #没有noloacal解释为新建一个变量,否则解释为重新赋值
            print("test in",num,id(num))
    
        Testin()
        print("test",num,id(num))
    
    Test()
    
  5. 在函数内部如果修改函数外部的变量(如整形 字符串...) 那么在函数内部相当于是声明了一个新的变量 和函数外部的变量没有关联 (如列表 是可以修改值 但是重新赋值一个新的列表 那么就为一个新的变量)

    num = 10
    def demo():
        num = 20
        print(num)#20 此刻num为局部变量 一个新的变量 和函数外部的变量没有关联
    def()
    print(num)#10
    

四 匿名函数

关键字 lambda

注意:

  1. lambda 只是一个表达式,函数体比 def 简单很多

  2. llambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去

  3. lambda 函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。

    #第一种
      #定义匿名函数  返回a+b的值
      func = lambda a,b:a+b
      #调用匿名函数
      func(1,2)
    #第二种 定义并调用
    (lambda a,b:a+b)(100,200)
    #第三种 没有参数的
    a = 10
    func = lambda:a
    print(func())
    

五 递归函数

#输入一个数(大于等于1),求1+2+3+……+n的和
#普通写法
def sum1(n):
 sum = 0
 for x in range(1, n + 1):
     sum += x
     return sum
#递归写法
def sum2(n):
if n == 1:
    return 1
else:
    return n + sum2(n - 1)
res = sum2(5)
#递归的分解
def a(x):
 print(x)
 b(x-1)
 print(',',x)

def b(x):
 print(x)
 c(x-1)
 print(x)

def c(x):
 print(x)
 print(x)

a(3)

六 特殊情况

a = 10
def test():
    a = a + 1
    print(a)
test()

错误信息为局部作用域引用错误,因为 test 函数中的 a 使用的是局部,未定义,无法修改。

七 函数的导入

From 文件名 import 方法名 #从文件里导入某个方法

**from **xxx **import **myfunc #从某个文件夹里 导入 某个文件

import 文件名 #将某个文件里的所有方法都导入到当前的文件

impo 文件名 as 别名 #将导入的文件 起 一个别名

__name__ #判断是否在当前的文件里
上一篇 下一篇

猜你喜欢

热点阅读