zoukankan      html  css  js  c++  java
  • 函数参数和变量用法

    1 函数的参数

    python的函数参数有四种,分别是位置参数、关键字参数、可变参数和不定长参数.

    a.位置参数,有时也称必选参数

    # 位置参数就是函数定义该参数的时候,没有进行初始化,调用函数传参的时候需要
    # 按位置顺序依次将值赋给位置参数
    def fun1(x,n):
        return x+n
    print(fun1(3,2))
    # 5
    # 当传入的数的个数和参数个数对不上时,会报错
    print(fun1(3))
    # TypeError: fun1() missing 1 required positional argument: 'n'
    View Code

    b.关键字参数

    # 关键字参数是在指在函数定义的时候进行初始化的参数,如下c是关键字参数
    # 调用函数的时候,关键字参数可以传也可以不传,不传的时候默认用初始化时候的
    def fun1(a,b,c=5):
        return a+b+c
    print(fun1(2,3))
    print(fun1(2,3,100))
    
    # 定义函数的时候,必须是位置参数在前,关键字参数在后,否则报错
    def fun2(c=3,a=2,b):
        return a+b+c
    print(fun2(c=2,1,3))
    # SyntaxError: non-default argument follows default argumen
    View Code

     定义关键字参数的时候要注意必须指向不变对象.指向可变对象也可,但要特别注意后续的处理是否真实改变了可变对象

    def fun(a,b,c=[]):
        a = 5
        # print('a的值为')
        b.append(['kkk'])
        c.append(5)
        return c
    A = 1
    B = [1,2,3]
    fun(A, B)
    # A是数字是不可变对象,在函数中赋值5后仍未改变
    print('A的值未改变:',A)
    # B是list是可变对象,在函数中给b添加kkk后,函数外的B也改变了
    print('B的值变了:',B)
    # A的值未改变: 1
    # B的值变了: [1, 2, 3, ['kkk']]
    
    
    # 由于c赋值为[]是可变对象,则每次调用函数后,都会给c添加一个5,而不会释放
    # 如果给c赋值None,None是不变对象,则不会出现这种情况
    print(fun(a=1,b=[2],))
    print(fun(a=1,b=[2],))
    # [5, 5]
    # [5, 5, 5]
    View Code

     当位置参数和关键字参数共用的时候,一定要避免犯下面的错误,位置参数必须要在关键字参数前,且必须要传递,不可省略.

    def fun(x,y=2,z=3):
        print('x变成了y:',x)
        print('y变成了z:',y)
        print(z)
    x = 555
    y = 8
    z = 9
    fun(y,z)
    # 正确写法
    fun(x,y,z)
    # x变成了y: 8
    # y变成了z: 9
    # 3
    # x变成了y: 555
    # y变成了z: 8
    # 9
    View Code

    2 函数的变量

    如果想要在一个函数内部来修改外部变量的值,有下面四种方法:

    a>通过返回值赋值  b>使用全局变量  c>修改list或dict对象的内部元素  d>修改类的成员变量

    # return的时候,把函数内x的引用返回来了,并赋值给a
    def f(x):
        x = 3
        print('x', x, id(x))
        return x
    a = 1
    print('原先a的地址:',id(a))
    a = f(a)
    print('a的地址变了,和函数内x的地址一样', a, id(a))
    # 原先a的地址: 9289312
    # x 3 9289376
    # a的地址变了,和函数内x的地址一样 3 9289376
    
    # x是全局变量,如果在函数内部不加global x的话,函数内部可以调用全局变量x,但不可以直接修改
    # 加上的话就可以修改全局变量的值,一句话,不加global只能调用,加上可以直接修改.
    def func():
        global x
        x = 10
    x = 5
    func()
    print('函数把变量值修改了', x)
    # 函数把变量值修改了 10
    
    def fun1(m):
        m[0] = 20
        # 这一步m变成了新的对象,最后返回的而是[4,5,6]
        m = [4, 5, 6]
        # print(id(m))
        return m
    l = [1, 2, 3]
    # 函数可以通过对可变对象(list dict)内部元素的修改来修改外部变量的值. 注意由于fun1里面没有写global m,所以传过去的m都是局部变量
    # 但函数结束调用后却把变量的值给修改了,就是因为执行fun1(l)的时候,把l的引用传给了m,而又因为list是可变对象的缘故,在函数内部修改m,也会改变外面l的值,
    t = fun1(l)
    # print(id(t))
    print(t)
    print('l的值变了',l)
    # 这一步和上面的不一样,由于用 + 合并list是产生新的对象,所以传参的时候就
    # 这里如果用切片法传也一样,因为切片是浅拷贝,所以传过去是新的对象
    fun1(l+[2])
    print('l的值没变',l)
    # [4, 5, 6]
    # l的值变了 [20, 2, 3]
    # l的值没变 [20, 2, 3]
    View Code

    3 局部变量和全局变量

    局部变量是函数开头声明的,如果没有声明则是全局变量,在函数内部全局变量(仅限于不可变对象)只可调用,不可修改引用,对于可变对象的全局变量,可以修改内容,不可修改引用.

    def fun():
        # 这里b c都是全局变量
        print(b)
        print(c)
        # 由于b是可变对象,所以可以修改其内容,但不能改变其引用,
        b[0] = 11111
        print(b)
        # 以下两行都会报错,因为b,c都是全局变量,下面的两种赋值都改变了对象的引用了,
        # 所以会报错UnboundLocalError: local variable 'b' referenced before assignment
        # b = [2,3,4]
        # c = 999
    b = [1,2,3]
    c = 5
    fun()
    # [1, 2, 3]
    # 5
    # [11111, 2, 3]
    View Code

    全局变量与局部变量的识别,注意嵌套函数中的不是全局变量.

    def fun():
        # 这样写会报错,因为对于不可变的对象的全局变量,在函数内部只能引用,不可修改
        # UnboundLocalError: local variable 'b' referenced before assignment
        # b = b + 4
        # 注意这样写的话,是在函数内部定义了局部变量b,后续可以直接修改
        b = 5
        # 如果局部变量与全局变量变量名一样,则优先调用局部变量
        b = b + 4
        print('b is:',b)
    b = 5
    fun()
    # b is: 9
    
    def fun1(a):
        # 这里的x是定义的局部变量,不是fun2()函数的局部变量
        x = 1
        def fun2(b):
            global x
            x = x + 2
            print('x is:',x)
        fun2(3)
    # 如果把这个x = 10注释掉,会报错,全局变量是函数最外面的变量,嵌套函数外的变量不是全局变量
    x = 10
    fun1(5)
    # x is: 12
    View Code


    1 定义函数的参数时,要将不带默认值的形参放前面,带默认值的形参放后面,否则会报错:non-default argument follows default argument

  • 相关阅读:
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之法阅读笔记03
    学习进度条
    软件工程练习——买书
    软件工程练习——找水王2
    Java作业07
    Java课堂作业06
    读《大道至简》第六章有感
    Java课堂作业05
  • 原文地址:https://www.cnblogs.com/xxswkl/p/11941599.html
Copyright © 2011-2022 走看看