zoukankan      html  css  js  c++  java
  • day4_函数的参数、全局变量、拆包和闭包

    函数即变量,函数名可以赋值
    函数如果要有返回值的话,就写return,函数里面遇到return,函数立即结束,函数不是必须有返回值的,如果不写return,默认返回None
    全局变量是大家都可以用的变量,局部变量就是在函数内部定义的变量,在函数内部可以随便用,出了函数就不能用了,全局变量是list,用不用global声明,都可以直接修改,其他的类型(tuple,str,set,bool,dict,普通的变量赋值)如果要修改值必须用global声明,尽量不要用全局变量,全局变量容易被修改,代码如下

    # s = [1, 2, 56, "list"]  # list不用global
    # s = {'name': '小明'} # 字典要使用global
    s = ('name', '小明', 3) # tuple要使用global
    # s = 'hello' # str要使用global
    # s = {22, 33} # 集合要使用global
    # s = False # 布尔值要使用global
    # s = 1 # 普通赋值要使用global


    def change_value():
    global s
    # s.append("over") # list
    # s = {'name': 'blue'} # 字典
    s = ('大明', '好') # tuple
    # s = 'red' # 字符串
    # s = {1, 3} # 集合
    # s = True # bool类型
    # s = 2 # 普通变量赋值
    return s


    res = change_value()
    print(res) # 打印出('大明', '好')
    print(s) # 打印出('大明', '好')

    函数的参数有四种方式,如果这四种参数一起用的话,顺序是位置参数、默认参数、可变参数、关键字参数
    1、位置参数
    位置参数,如add(x, y),x和y就是位置参数,位置参数是必传的,有几个位置参数在调用的时候就要传几个,否则就会报错,那如果有多个位置参数的话,记不住哪个位置传哪个了怎么办,可以使用位置参数的名字来指定调用,比如说上面的那个add函数也可以使用add(y=1, x=2)这样来调用,这种调用方式叫做关键字传参

    def add(x, y):  # 函数名
    return x + y # 函数体
    print(add(2, 3)) # 调用的方法一
    print(add(y=2, x=3)) # 调用的方法二

    会打印出5

    2、默认参数
    默认参数就是在定义形参的时候,默认参数不是必填的,如果给默认参数传值的话,它就会使用你传入的值,如果使用默认值参数的话,必须放在位置参数后面定义

    def user(name, sex='男'):  # sex就是默认参数
    print('你的名字是 %s,你的性别是 %s' % (name, sex)) # 函数体

    传参时user('哈哈'),会打印出你的名字是 哈哈,你的性别是男

    3、可变参数
    可变参数用*args来接收,后面想传多少个参数就传多少个,如果位置参数、默认值参数、可变参数一起使用的的话,可变参数必须在位置参数和默认值参数后面,可变参数也是非必传的,args是一个tuple,args这个名字随便叫,叫别的名字也行

    def test(name, *args):
    print('你的名字是:', name)
    print('*args的值是:', args)
    test('hello', 10086, '北京')

    会打印出你的名字是: hello *args的值是(10086, '北京')  # args是一个tuple

    4、关键字参数
    关键字参数使用**kwargs来接收,这个名字也不固定,写成**aa也可以,关键字参数也可以和上面的三种一起来使用,如果要一起使用的话,关键字参数必须在最后面,使用关键字参数的话,是指函数在调用的时候,带上参数的名字去指定具体调用的是哪个参数,从而可以不用按照参数的顺序调用函数,关键字参数也是非必传的

    def test(name, **kwargs):
    print('你的名字是:', name)
    print('**kwargs的值是:', kwargs)
    test('hello', a=1, b=2)

    会打印出你的名字是: hello **kwargs的值是{'a': 1, 'b': 2}  # kwargs是一个字典

    def redis(ip, password, port=6379):
    print('连接redis')
    print(ip)
    print(password)
    print(port)
    print('=' * 10)

    # 用list
    redis_info = ('127.0.0.1', '123456', 6378)
    # redis_info = ['127.0.0.1', '123456', 6378]
    redis(redis_info[0], redis_info[1], redis_info[2])
    # redis(*redis_info)  # 这种方式叫拆包

    
    

    # 用字典
    redis_info2 = {'ip': '127.0.0.1', 'password': '123456', 'port': 6378}
    redis(**redis_info2)

    # 全局变量

    count = 5


    def my():
    global count
    count = 10
    print(count)


    my() # 打印出10
    print(count) # 如果不写global count,打印出5,否则打印10

    # 如果在一个内部函数里,对外部作用域(但不是在全局作用域的变量的引用)的变量的引用,内部函数就称为闭包,fun2就是一个闭包

    def fun1(x):
    def fun2(y): # 满足三点,第一是有内部函数,第二是内部函数引用了外部作用域(fun1)的变量x,第三外部函数的返回值必须是内部函数

    return x * y
    return fun2


    res = fun1(5)(6)
    print(res)
    
    
    def fun1():
    x = 5

    def fun2():
    x *= x
    return x
    return fun2()

    print(fun1())
    
    

    打印出UnboundLocalError: local variable 'x' referenced before assignment,意思是赋值之前引用了局部变量x
    在fun2()把x当成了局部变量,所以x *= x就报错了,在嵌套的函数中,如果希望在内部函数修改外部函数的局部变量,使用nonlocal,让x不是局部变量,修改代码如下:

    def fun1():
    x = 5

    def fun2():
    nonlocal x
    x *= x
    return x
    return fun2()


    print(fun1())

    打印出UnboundLocalError: local variable 'var' referenced before assignment,意思是变量var没有被定义就拿来使用,肯定错啦,解决办法有三种,一是注释var = 3,二是把var = 3放到print上面,三是在print上输入nonlocal var
    这里outside()函数里有一个var变量,但要注意的是,内嵌函数inside()也有一个同名的变量,python为了保护变量的作用域,故将outside()的var变量屏蔽起来,因此此时是无法访问到外层的var变量的

    def outside():
    var = 5

    def inside():
    print(var)
    var = 3
    inside()


    outside()

    以下是闭包的一个例子,请你目测下会打印什么内容?

    def fun1():
    x = 5

    def fun2():
    nonlocal x
    x += 1
    return x
    return fun2


    a = fun1()
    print(a()) # 打印6
    print(a()) # 打印7
    print(a()) # 打印8

    当a=fun1()的时候,只要a变量没有被重新赋值,fun1()就没有被释放,也就是说局部变量x就没有被重新初始化

  • 相关阅读:
    Mysql DQL语言执行顺序
    MySQL核心技术——DQL语言
    Java基础第二十九天总结——Java8新特性
    Java基础第二十八天总结——反射机制
    在对csv文件做批量获取时无法获取,程序不动
    tensorflow 对csv数据进行批量获取
    tensorflow 做多元线性回归时怎样对非数据型数据(分类型数据)进行处理(编码)
    flatten函数
    用 sklearn包中的 linear_model 实现多元线性回归
    tensorflow实现多元线性回归时预测出的参数为nan
  • 原文地址:https://www.cnblogs.com/laosun0204/p/7696346.html
Copyright © 2011-2022 走看看