(十)python 全局变量和局部变量 ,作用域,lambda

目录

全局变量和局部变量

    globals() 函数 和 locals函数

    函数的嵌套定义

作用域

    变量名的查找规则:

    global语句

    nonlocal 语句

        nonlocal 说明

lambda 表达式(又称匿名函数)


全局变量和局部变量

    局部变量:
        定义在函数内部的变量称为局部变量(函数的形参也是局部变量)
        局部变量只能在函数内部使用
        局部变量在函数调用时才能够被创建,在函数调用结束后会自动销毁

    全局变量:
        定义在函数外部,模块内部的变量称为全局变量
        所有的函数都可以直接访问全局变量,但函数内部不能直接通过赋值语句来改变全局变量


    局部变量说明:
        1.在函数内首次对变量赋值是创建局部变量,再次为变量赋值是修改局部变量的绑定关系
        2. 在函数内部的赋值语句不会对全局变量造成影响
        3.局部变量只能在其被声明的函数内部访问,而全局变量可以在整个模块同访问

a = 100
b = 200

def fx(c):
    print('hello')
    d = 400
    a = 10  # 此赋值语句在函数内,它只能创建局部变量,不能改变全局变量
    print(a, b, c, d, sep='  => ')  # 10  => 200  => 300  => 400

print('a =', a, 'b =', b)  # a = 100 b = 200

fx(300)
print('a =', a, 'b =', b)
print(c)  #NameError: name 'c' is not defined 局部变量只能在函数内部使用

练习:
    创建一个全局变量: 
        L = []
    写一个函数:
        def input_number():
    读入正整数 放到L列表内

input_number() # 输入 1 2 3
print(L)   #[1,2,3]
input_number() # 输入 4 5
print(L)   #[1,2,3,4,5]

#示例:
L = []
def input_number():
    lst = []
    while True:
        n = int(input("请输入正整数: ") or '-1')
        if n < 0:
            break
        lst.append(n)
    # 走到此时,lst 里是本次函数调用时用户输入的正整数
    return lst

L += input_number()  # 输入1 2 3
print(L)  # [1, 2, 3]
L += input_number()  # 输入4, 5
print(L)  # [1, 2, 3, 4, 5]

    globals() 函数 和 locals函数

        函数变量
            函数名是变量,它在创建时绑定一个函数

def f1():
    print("hello f1")

def f2():
    print("hello f2")

fx = f1  # 注意此处f1没有加()
fx()  # 调用f1
f1()  # 调用f1
f1 = f2  # 让f1 改变绑定关系,去绑定f2
f1()  # 调用f2
f2 = fx
f2()  # 调用f1  # 交换法(三次交换赋值)


    一个函数可以作为另一个函数实参传递
def f1():
    print("f1被调用") 
def f2():
    print("f2被调用")
def fx(fn):
    print("fn绑定的是:",fn)
    fn()  #调用fn绑定的函数,此处等同于调用谁呢? 
fx(f1)
fx(f2)
案例:
  看懂如下代码做什么事?

  def myinput(fn):
      L = []
      while True:
          x = int(input("请输入大于0的整数: " or '-1'))
          if x < 0:
              break
          L.append(x)
      return fn(L)   # <<< 注意此处

print(myinput(max))
print(myinput(min))
print(myinput(sum))

函数作为另一个函数的返回值

# 此示例示意get_op这个函数可以返回其它的函数
def get_op():
    s = input("请输入您要做的操作: ")
    if s == '求最大':
        return max
    elif s == '求最小':
        return min
    elif s == '求和':
        return sum

L = [1, 2, 3, 4]
fx = get_op()
print( fx(L) )


    函数的嵌套定义

        函数嵌套定义是指一个函数里用def 语句来创建其它函数的情况

# 此示例示意函数内部来嵌套定义其它函数
def fun_outer():
    print("fun_outer被调用...")
    # 在此处创建另一个函数,并在下面调用
    def fun_inner():
        print("fun_inner被调用")
    fun_inner()  # 调用一次
    fun_inner()  # 调用二次...

    print("fun_outer调用结束")

fun_outer() # 调用函数

# fun_inner()  # 调用失败


作用域

    也叫命名空间,是访问变量时查找变量名的范围空间

    四个作用域 LEGB
        作用域 英文解释 英文简写
        局部作用域(函数内) Local(function)  L
        外部嵌套函数作用域 Enclosing function locals  E
        函数定义所在模块(文件)的作用域 Globals(module) G
        python 内置模块的作用域 Builtin(python)    B

# 此示例示意 python的四个作用域
v = 100
def fun1():
    # v = 200
    print('fun1.v = ', v)
    def fun2():
        # v = 300
        print('fun2.v=', v)

    fun2()

fun1()
print("全局的v=", v)

    变量名的查找规则:

        1.在访问变量时先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内置(内建)变量
            L ---> E  ---->  G ----> B
        2.在默认情况下,变量名赋值会创建或者改变本地作用域变量

    global语句

        作用: 
            1. 告诉解释器,global语句声明的一个或多个变量
            ,这些量的作用域为模块级的作用域,也称作全局变量
            2.全局声明(global)将赋值变量映射到模块内部的作用域
        语法:
            global 变量1,变量2 .....

# 此示例示意globals 声明

v = 100
def fn():
    # 添加全局声明,告诉解释执行器,本函数内的变
    # 量v为全局变量
    global v
    v = 200  # 本意想要修改全局变量v让它绑定200

fn()
print("v =", v)

        说明:
            1.全局变量如果要在函数内部被赋值,则必须经过全局声明(否则会被默认为是局部变量)
            2.全局变量在函数内部不经过全局声明就可以直接访问
            3.不能先创建局部变量,再用global声明为全局变量,此做法不符合规则
            4.global 变量列表的变量名不能出现再此作用域内的形参列表里

练习:
    写一个函数名 
        def hello(name):
            ...
        count = 0
        hello("小张")
        hello("小李")
        print("函数hello已经被调用%d次" % count )  # 2
        hello("小赵")
        print("函数hello已经被调用%d次" % count )  # 3

def hello(name):
    global count
    count +=1
    print("您好",name)
count = 0
hello("小张")
hello("小李")
print("函数hello已经被调用%d次" % count)  # 2
hello("小赵")
print("函数hello已经被调用%d次" % count)  # 3

    nonlocal 语句

        作用:告诉解释器,nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量
        语法:
        nonlocal 变量名1,变量名2,....

var = 100
def f1():
    var = 200
    print("f1里的var=", var)
    def f2():
        nonlocal var  # 声明var为f2以外,全局变量以内的变量
        var = 300

    f2()
    print('f1调用结束时var=', var)

f1()
print("全局的var=", var)

        nonlocal 说明

            1.nonlocal语句只能在被嵌套函数内部进行使用
            2.访问nonlocal变量将对外部嵌套函数的作用域的变量进行操作
            3.当有两层或两层以上的函数嵌套时,访问nonlocal变量只对最近一层的变量进行操作
            4.nonlocal语句的变量列表的变量名,不能出现在此函数的参数列表中


lambda 表达式(又称匿名函数)

    作用:
        创建一个匿名函数对象
        同def类似,但不提供匿名数名
    语法格式:
        lambda[参数1,参数2,...]:表达式 
        []里的内容可以省略

#示例:
def myadd(x,y)
    return x+y
#以上函数可以改写为:
myadd = lambda x,y:x+y
print(“2+3=”,myadd(x,y))

    语法说明:
        1.lambda 只是一个表达式,它用来创建一个函数对象
        2.当lambda表达式调用时,先执行冒号后(:)的表达式,并返回表达式的结果的引用
        3. lambda表达式创建的函数只能包含一条“表达式”
        4.lambda比函数简单,且可以随时创建和销毁,有利于减少程序的偶合度

练习:
    1.写一个lambda 表达式,判断这个数2次方+1是否能被5整除,如果能被整除
      返回True,否则返回False
     fx = lambda n : ...
     print(fx(3))  # True

#1.
fx = lambda n:(n ** 2 + 1) % 5 == 0
print(fx(3))  # True
print(fx(4))  # False

#2.
mymax = lambda x,y:max(x,y)
print(mymax(100,200))    #200
print(fx(4))  # False

  2. 写一个lambda 表达式求两个变量的最大值
    def mymax(x,y):
     ....
     mymax = lambda ......
     print(mymax(100,200))  #200


练习:
    1.写一个函数mysum(n),给出一个数n写一个函数来计算
    1 + 2 + 3 + 4 + ...+ n 的和
    (要求用函数来做)
    def mysum(n):
        ...
    print(mysum(100))  # 5050
  2. 写一个函数myfac 来计算n!(n的阶乘)
   n! = 1*2*3*4*...*n 
     def myfac(n):
       ...
     print(myfac(5))  # 120
  3.给出一个数n,写一个函数计算:
     1 + 2**2 + 3**3 + 4**4 + ....+ n**n的和
      (n给小点的数)
 4.修改之前的student_info.py 学生信息管理项目
 为项目添加菜单界面
 +-----------------------------+
    | 1)    添加学生信息            | 
    | 2)    显示学生信息            |
    | 3)    删除学生信息            |
    | 4)    修改学生成绩            |
    | q)    退出程序                |
    +-----------------------------+
  请选择:
   (要求,每个功能至少对应一个函数)

#1.
def mysum(n):
    s = 0
    for i in range(1,n+1):
        s += i
    return s

print(mysum(100))

#2
n! = 1*2*3*4*...*n 
def myfac(n):
    s = 1
    for i in range(1,n+1):
        s *= i
    return s
print(myfac(5))  # 120

#3
def sum3(n):
    s = 0
    for i in range(1,n+1):
        s += i **i
    return s
print(sum3(10))
def input_student():
    '''此函数返回用户输入的学生信息的列表
    返回的列表格式写之前完全相同
    '''
    L = []  # 创建一个列表,用来保存所有学生的字典
    # 读取学生数据放入列表中
    while True:
        n = input("请输入学生姓名: ")
        if not n:  # 如果学生姓名为空则结束输入
            break
        a = int(input("请输入学生年龄: "))
        s = int(input("请输入学生成绩: "))
        # 把上述n, a, s 所表示的信息形成字典,并加入到列表
        d = {}  # 创建一个新字典,准备存入学生信息数据
        d['name'] = n
        d['age'] = a
        d['score'] = s
        L.append(d)  # 把字典存入列表中
    return L

def output_student(L):
    '''此函数把传入的列表L 打印成为表格'''
    # 第二步,显示所有学生的信息
    print("+---------------+----------+----------+")
    print("|      name     |    age   |  score   |")
    print("+---------------+----------+----------+")
    # 此处打印所有学生的信息
    for d in L:  # 把每个学生的数据取出来,用d绑定对应的字典
        center_name = d['name'].center(15)
        str_age = str(d['age'])  # 先将年龄转为字符串
        center_age = str_age.center(10) # 生成居中的字符串
        center_score = str(d['score']).center(10)
        line = "|%s|%s|%s|" % (center_name,
                              center_age,
                              center_score)
        print(line)
    print("+---------------+----------+----------+")


def del_student(L):  # 删除学生信息
    name = input("请输入要删除学生的姓名: ")
    print('删除成功')

def modify_student_score(L):  # 删除学生信息
    name = input("请输入要修改学生的姓名:")
    # 查找name 是不是在列表L里
    # 如果name在L里
    score = int(input("请输入要修改的成绩: "))
    # ...

def show_menu():
    print("+-----------------------------+")
    print("| 1)  添加学生信息            |")
    print("| 2)  显示学生信息            |")
    print("| 3)  删除学生信息            |")
    print("| 4)  修改学生成绩            |")
    print("| q)  退出程序                |")
    print("+-----------------------------+")

def main():
    docs = []
    while True:
        show_menu()
        s = input("请选择: ")
        if s == '1':
            docs += input_student()
        elif s == '2':
            output_student(docs)
        elif s == '3':
            del_student(docs)  # 删除学生信息
        elif s == '4':
            modify_student_score(docs)  # 删除学生信息
        elif s == 'q':
            break  # 退出循环

main()

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值