zoukankan      html  css  js  c++  java
  • day11.函数的全局变量和局部变量

    一、定义

    """
    局部变量 : 在函数内部定义的变量(局部命名空间)
    全局变量 : 在函数外部定义的或者使用global在函数内部定义(全局命名空间)
    
    作用域: 作用的范围
    局部变量作用域: 在函数的内部
    全局变量作用域: 横跨整个文件
    
    生命周期:
        内置变量 > 全局变量 > 局部变量
    
    """

    1、局部变量

    # 1.局部变量
    def func():
        # 定义局部变量
        a = 5
        # 获取局部变量
        print(a)
        # 修改局部变量
        a = 10
        print(a)
    
    func()
    # print(a) error 不能再全局调用局部变量

    2、全局变量

    # 定义全局变量
    b = 10
    # 获取全局变量
    print(b)
    # 修改全局变量
    b = 20
    
    def func():
        # 可以在函数内部获取全局变量
        print(b)
    func()

    3、使用global在函数内部创建全局变量

    def func():
        global c
        c = 200
    func()
    print(c)

    4、使用global在函数内部修改全局变量

    d = 300
    def func():
        global d
        d = 400
    func()
    print(d)
    """
        可以使用global 关键字在函数内部定义一个全局变量
        也可以使用global关键字在函数内部修改一个全局变量
    """

    二、函数名的使用

    def func():
        print("我是func函数")
        return 1111
    
    # 1.函数名是个特殊的变量,可以当做变量赋值
    a = "你好"
    print(a)
    a = func
    a()
    
    # 函数可以像变量一样销毁
    del a
    # a()

    1、函数名可以作为容器类型数据的元素

    def func1():
        print("我是func1函数")
        
    def func2():
        print("我是func2函数")    
        
    def func3():
        print("我是func3函数")
        
    lst = [func1,func2,func3]
    for i in lst:
        print(i)
        i() # func1() func2() func3()

    2、函数名可以作为函数的参数

    def func4(f):
        f()
    
    func4(func3)

    3、函数名可作为函数的返回值

    def func(f):
        return f
        
    res = func(func2) # f <=> func2 =>  res = func2()
    res()
    
    # ### __doc__ 或者 help查看文档
    
    def eat_bigchang(something):
        """
        功能: 大肠刺身
        参数: 肠子名字
        返回值: 吃的状态    
        """
    
    
        print("先把{}洗一洗".format(something))
        print("找出肠子头放嘴里")
        print("嘬!!")
        return "吃完了,满意的放下肠子,擦擦嘴"
    
    res = eat_bigchang("猪肠子")
    print(res)
    help(eat_bigchang)
    res = eat_bigchang.__doc__
    print(res)

    三、函数的嵌套

    """
    函数之间可以互相嵌套
    外层的叫做外函数
    内层的叫做内函数
    """
    def outer():
        
        def inner():
            print("我是inner函数")
        inner()
            
    outer()

    1、 LEGB 原则

    """
    #找寻变量的调用顺序采用LEGB原则(即就近原则)
    B —— Builtin(Python);Python内置模块的命名空间      (内建作用域)
    G —— Global(module); 函数外部所在的命名空间        (全局作用域)
    E —— Enclosing function locals;外部嵌套函数的作用域(嵌套作用域)
    L —— Local(function);当前函数内的作用域            (局部作用域)
    依据就近原则,从下往上 从里向外 依次寻找
    """

    四、nonlocal 修改局部变量

    """
    nonlocal遵循LEGB就近找变量原则
        (1)找当前空间上一层的局部变量进行修改
        (2)如果找不到,会继续向上寻找
        (3)最后什么也没有,直接报错
    """

    1、找当前空间上一层的局部变量进行修改

    def outer():
        a = 100
        def inner():
            nonlocal a
            a = 200
            print(a)
        
        inner()
        print(a)
    
    outer()    

    2、如果找不到,会继续向上寻找

    def outer():
        a = 100
        def inner():
            
            def smaller():
                nonlocal a 
                a = 400
                print(a)
            smaller()
            print(a)
        inner()
        print(a)
    outer()

    注意点:nonlocal只能修改局部变量

    """
    a = 100
    def outer():
        
        def inner():
            def smaller():
                nonlocal a 
                a = 400
                print(a)
            smaller()
            print(a)
        inner()
        print(a)
    outer()
    """

    3、不使用nonlocal 修改局部变量

    def func():
        lst = [1,2,3,4]
        def inner():
            lst[-1] = 10
        inner()
        print(lst)
    func()

    五、locals 和 globals

     locals 获取当前作用域中所有变量

    """
    locals 如果在全局,调用locals之后,获取的是打印之前的所有变量,返回字典,全局空间作用域
    locals 如果在局部,调用locals之后,获取的是调用之前的所有变量,返回字典,局部空间作用域
    """

    例1、打印res 之前的所有变量

    """
    def func():
        ff = 123
    a = 1
    b = 2
    res = locals()
    c = 3
    print(res)
    d = 4
    """
    
    #  'a': 1, 'b': 2, 'res': {...}, 'c': 3

    例2、调用之前的所有变量

    a1 = 10
    def func():
        a = 1 
        b = 2
        res = locals()
        c = 3
        print(res)
        d = 4
    a2 = 20
    func()
    a3 = 30
    
    #  'a1': 10, 'a2': 20

     1、globals 只获取全局空间中所有变量

    """
    globals 如果在全局,调用globals之后,获取的是打印之前的所有变量,返回字典,全局空间作用域
    globals 如果在局部,调用globals之后,获取的是调用之前的所有变量,返回字典,全局空间作用域
    """

    例1、

    def func():
        ff = 123
    a = 1
    b = 2
    res = globals()
    c = 3
    print(res)
    d = 4
    
     # 'a': 1, 'b': 2, 'res': {...}, 'c': 3

    例2、

    a1 = 10
    def func():
        a = 1 
        b = 2
        res = globals()
        c = 3
        print(res)
        d = 4
    a2 = 20
    func()  # globals
    a3 = 30
    
    # 'a1': 10, 'func': <function func at 0x00000289E7B9C1E0>, 'a2': 20

    2、动态批量创建全局变量

    2.1、用字符串定义全局变量

    dic = globals()
    print(dic) # 返回的是系统的字典
    # 在全局的字典当中,通过添加键值对,自动创建全局变量
    # 对应的键时变量名,对应的值是变量指向的值
    dic["name"] = "aa"
    
    print(name)

    2.2、批量定义全局变量

    def func():
        dic = globals()
        # 通过在全局系统字典当中,添加键值对,批量创建变量
        for i in range(1,6):
            # "a%d" % (1) => "a1"  "a%d" % (2) => "a2"  
            dic["a%d" % (i)] = i #  1~5 
            
    func()
    """
    "a%d" % (1) => a1
    "a%d" % (2) => a2
    "a%d" % (3) => a3
    "a%d" % (4) => a4
    "a%d" % (5) => a5
    """

    六、登录注册练习

    写一个登陆注册小程序
    登录:
        # 1.账户密码会预先记录在文件中
        # 2.输入账号密码:如果都正确,登录成功
        # 3.如果用户登录时进行三次校验,都不对,记录黑名单文件中
        # 4.如果是黑名单的用户,禁止下次再次登录
    
    注册:
        # 1.检测两次密码如果相同,确认注册成功
        # 2.检测两次密码如果不同,提示两次密码不一致
        # 3.用户名不能重复
    # 注册:
        # 1.检测两次密码如果相同,确认注册成功
        # 2.检测两次密码如果不同,提示两次密码不一致
        # 3.用户名不能重复
        
    # accountlst存放所有账号
    accountlst = []
    sign = True
    with open("user.txt",mode="a+",encoding="utf-8") as fp:
        while sign:
            # 输入用户名
            username = input("请输入要注册的用户名:")    
            if username == "" or " " in username:
                print("对不起,该名字含有非法字符")
            else:
                # 把数据从文件当中获取            
                fp.seek(0)
                lst = fp.readlines()
                for i in lst:
                    account = i.strip().split(":")[0]
                    accountlst.append(account)
                        
                print(accountlst)
                # 判断该名字是否已经存在
                if username in accountlst:
                    print("抱歉,改名字已经使用~")
                else:
                    # 检测密码
                    pwd = input("请输入您的密码")
                    while True:
                        pwd2 = input("请确认您的密码,按q退出~")
                        # 如果密码相同
                        if pwd == pwd2:
                            # 拼接字符串
                            strvar = username + ":" + pwd + "
    "
                            # 写入文件
                            fp.write(strvar)
                            # 终止循环
                            sign = False
                            # 打印信息
                            print("注册成功~")
                            break
                        elif pwd2.upper() == "Q":
                            # sign = False
                            break
                            
                        else:
                            print("对不起,两次密码不一致~")
                        
        
    注册(register.py)
    # ### 登录
        # 1.账户密码会预先记录在文件中
        # 2.输入账号密码:如果都正确,登录成功
        # 3.如果用户登录时进行三次校验,都不对,记录黑名单文件中
        # 4.如果是黑名单的用户,禁止下次再次登录
    
    # 存账户
    accountlst = []
    # 存密码
    pwdlst = []
    # 存黑名单
    blacklst = []
    
    sign = True
    while sign:
        username = input("请输入您的用户名:")
        # 获取文件当中的账号和密码
        with open("user.txt",mode="a+",encoding="utf-8") as fp:
            fp.seek(0)
            lst = fp.readlines()
            for i in lst:
                user,pwd = i.strip().split(":")
                # print(username,password)
                accountlst.append(user)
                pwdlst.append(pwd)
                
            # print(accountlst)
            # print(pwdlst)
            # 判断该用户是否存在
            if username in accountlst:
                # 判断当前用户是否是黑名单中的用户
                with open("black.txt",mode="a+",encoding="utf-8") as fp:
                    fp.seek(0)
                    lst = fp.readlines()
                    for i in lst:
                        blacklst.append(i.strip())
                        
                # print(blacklst)
                # print(username)
                if username in blacklst:
                    print("抱歉,该用户已经被冻结了")
                else:
                    # 如何找到该账户对应的密码呢?
                    num = accountlst.index(username)
                    pwd = pwdlst[num]
                    # print(num,pwd)
                    """"""
                    # 判断用户输入的密码是否正确
                    times = 1
                    while times <= 3:
                        pwd2 = input("请输入您的密码")
                        # 输入成功情况下,终止循环,程序结束
                        if pwd == pwd2:
                            print("登录成功")
                            sign = False
                            break
                        else:
                            # 剩余的次数 = 总次数 - 使用次数
                            print("你还剩下%s次机会" % (3 - times))                    
                            
                            # 如果用掉了所有的次数,直接加入黑名单,防止下次登录
                            if times == 3:
                                with open("black.txt",mode="a+",encoding="utf-8") as fp:                        
                                    strvar = username + "
    "
                                    fp.write(strvar)
                                print("抱歉,您的账户已经被冻结~")                
                        times += 1 
            else:
                print("该用户不存在~")
            
    登录(login.py)
    ceshi1
    ceshi2
    ceshi3
    ceshi4
    黑名单(black.txt)
    ceshi1:111
    ceshi2:222
    ceshi3:333
    ceshi4:444
    ceshi5:555
    用户(user.txt)

     

  • 相关阅读:
    安卓自带浏览器 position:fixed时 图片模糊问题
    建在ghost的blog
    javascript活动对象
    将json对象通过控制台保存到本地文件
    从用户体验出发的性能指标分析-DOM Ready(转)
    像诗一样的 Javascript 代码(转)
    给数组原型对象添加一个去重的方法,并返回去重后的数组
    如何避免FOUC(转)
    使用JS调用腾讯接口获取天气
    CSS好文推荐
  • 原文地址:https://www.cnblogs.com/kongxiangqun/p/13337575.html
Copyright © 2011-2022 走看看