python3基础10

day10

全局变量和局部变量

 局部变量:
  定义在函数内部的变量称为局部变量(函数的形参也是局部变量)
  局部变量只能在函数中使用
  局部变量在函数调用时才能被创建,在函数调用之后会自动销毁
 
 全局变量:
  定义在函数外部,模块内部的变量称为全局变量
  全局变量所有的函数都可以直接访问(但函数内部不能将其赋值)
 
 示例见:
   global_local.py
 
 说明:
  1.局部变量只能在其被声明的函数内部访问,而全局变量可以在整个模块范围内访问
  2.在函数内部赋值语句不会对全局变量造成影响
  3.在局部范围内可以访问全局变量,但是在全局不能访问局部变量,因为在函数调用完毕后,局部变量销毁
  4.函数名也是全局变量(fn)
 def fn(c, d):
    e = 300

 示意:
   L = []
   def input_number():
       L2 = []
       while True:
           n = int(input("请输入正整数:"))
           if n < 0:
               break
            L2.append(n)
       L = L2
    input_number()
    print(L)


globals()/locals()函数
  globals()  返回当前全局作用域内变量的字典
  locals()   返回当前局部作用域内变量的字典
 
示例见:
   globals_locals.py

a = 1
b = 2
c = 3


def fn(c, d):
    e = 300
    print("locals()返回",locals())
    print("globals()返回",globals())
    print(c)    #打印局部变量绑定的对象
    print(globals()['3'])   #打印全部变量绑定的对象

fn(100, 200)

函数变量:
  函数名是变量,它在创建函数时绑定一个函数
 
 示例见:
   function_variable.py

def fn():
    print("hello world!")   #fn绑定函数


f1 = fn    #f1也绑定这个函数
print(fn)   #<function fn at 0x7f138e4d6f28>
print(f1)   #<function f1 at 0x7f138e4d6f28>
print(f1())   #None


def f1():
    print("函数f1被调用")

def f2():
    print("函数f2被调用")

f1, f2 = f2, f1   #f1,f2交换绑定

f1()    #f2被调用
f2()    #f1被调用

 
  一个函数可以作为另一个函数的实参传递
 
 示例见:
   function_give_function.py

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

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

def fx(fn):
    print(fn) #<function f1 at 0x7fb921cebf28>
    fn()    #调用fn绑定的函数

fx(f1)  #请问如何执行?#fn是函数 fn()是调用函数fn
fx(f2)


#fx(f1)就是将f1绑定的语句块交给fn绑定

 看懂下面的代码在做什么:
   def myinput(fn):
       L = [1,3,5,7,9]
       return fn(L)
   print(myinput(max))   #9
   print(myinput(min))   #1
   print(myinput(sum))   #25

函数可以返回另一个函数:
 示例见:
  return_function.py

def get_function():
    s = input("请输入您要做的操作:")
    if s == '求最大':
        return max
    elif s == '求最小':
        return min
    elif s == '求和':
        return sum

L = [2,4,6,8,10]
f = get_function()  #让get_function返回给我们一个函数
print(f(L))


练习一:
 写一个计算公式的解释执行器
 已知有如下函数:
   def myadd(x, y):
       return x + y
   def mysub(x, y):
       return x -y
   def mymul(x, y):
       return x * y

   def get_fun(op):
   .....#自己实现
   get_fun(op)函数传入字符串'加'或'+'返回myadd
   get_fun(op)函数传入字符串'乘'或'*'返回mymul
   在主函数中程序如下:
     def main():
         while True:
             s = input("请输入计算公式:")  #10加20
             L.s.split()   #L = ['10','加','20']
             a = int(L[0])
             b = int(L[2])
             fn = get_fun(L[1])
             print("结果是:",fn(a,b))   #结果是:30
#方法一:
def myadd(x, y):
    return x + y
def mysub(x, y):
    return x - y
def mymul(x, y):
    return x * y

def get_fun(op):
    if op == '加' or op == '+':
        return myadd
    if op in ('减', '-'):
        return mysub
    if op in ('乘', '*'):
        return mymul

def main():
    while True:
        s = input("请输入计算公式:")  #10 加 20
        L = s.split()   #L = ['10','加','20']
        a = int(L[0])
        b = int(L[2])
        fn = get_fun(L[1])
        print("结果是:",fn(a,b))   #结果是:30
main()


#方法二:

def get_fun(op):
    if op == '加' or op == '+':
        def myadd(x, y):
            return x + y
    if op in ('减', '-'):
        def mysub(x, y):
            return x - y
    if op in ('乘', '*'):
        def mymul(x, y):
            return x * y

def main():
    while True:
        s = input("请输入计算公式:")  #10 加 20
        L = s.split()   #L = ['10','加','20']
        a = int(L[0])
        b = int(L[2])
        fn = get_fun(L[1])
        print("结果是:",fn(a,b))   #结果是:30
main()

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

 示例:

  def fn_outter():
      print("fn_outter()被调用")
      def fn_inner():
          print("fn_inner被调用")
      fn_inner()  #调用嵌套函数fn_inner
      fn_inner()  #第二次调用
      print('fn_outter调用结束')
  fn_outter()   #调用外层函数


python3 的四个作用域
 作用域也叫名字空间,是访问变量时查找变量名的范围空间

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

 注:
 内建函数: max min sum 等都在python内置模块的作用域,不能改变,只能读取

示例见:
  namespace.py

v = 100  #函数定义所在模块作用域


def fun1():
    v = 200        # 外部嵌套函数作用域 
    print("fun1.v=",v)
    def fun2():
        v = 300  #局部作用域(函数内)
        print('fun2.v=',v)
    fun2()


fun1()
print("全局变量v=",v)


变量名查找规则:
  在访问变量时,先查找本地(局部)变量,然后是包裹此函数外部的函数内的变量,之后是全局变量,最后是内建作用域内的变量
  即: L----->    E------>  G----->B
  在默认情况下,变量名赋值(赋值语句)会在当前作用域内创建变量和修改变量
 
 v = 0
 def fn(x):
     v += x   #错误,把v看做局部变量,在局部内未绑定

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

v = 100


def fn():
    global v    # 告诉解释执行器python3,v是全部变量,不是局部变量
    v = 200


fn()
print('v=',v)
 说明:
   1.全局变量如果要在函数内部被赋值,则必须经过全局声明(否则
     会被认为是局部变量)
   2.全局变量在函数内部不经过声明就可以直接访问
   示例: global2.py

v = 100


def fn():
    v = 200     # 不建议在globalz之前声明局部变量
    print(v)

    global v   #v不能既是全局又是局部变量
    v = 300
    print(v)


fn()
print('v=',v)

   3.不能先声明局部变量,再用global声明全局变量,此做法不和规则
   4.global变量列表里的变量名不能出现在函数的形参列表里
   示例: global3.py

v = 100 


def fx(v):
    global v  #此处错误,fx(v)形参中的v与全局变量中的v冲突
    v = 300


fx(v)
print(v)

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

 示例见:
   nonlocal.py

v = 100


def f1():
    v = 200
    print("f1.v=",v)


    def f2():
        nonlocal v
        v = 300
        print("f2.v=",v)
    f2()
    print("调用f2()后的f1.v=",v)


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


#结果为:
# f1.v= 200
# f2.v= 300
# 调用f2()后的f1.v= 300
# 全局的v= 100

 说明:
  1.nonlocal 语句只能被嵌套函数的内部进行使用
  def fx():
      nonlocal v
      v = 100
    #没有嵌套不能使用
  2.访问nonlocal变量进行赋值操作,将对外部嵌套函数作用域内的
    变量进行操作
  
  3.当有两层或两层以上函数嵌套时,访问nonlocal变量只是
    对近一层变量进行操作

  示例见nonlocal2.py

def f1():
    v = 200
    def f2():
        v = 300
        
        def f3():
            nonlocal v    #修改f2中的局部变量v
            v = 400
        f3()
        print("f2.v",v)
    f2()
    print("f1.v",v)
f1()

#结果是
# f2.v 400
# f1.v 200

  4.nonlocal语句的变量列表里的变量名,不能出现在此函数形参列表中


 
def 语句
  语法:
   def 变量名/函数名(形参):
      语句块


lambda 表达式
  作用:
   创建一个匿名函数对象
   同def 类似,但不提供函数名
  语法:
   lambda [形参名1,形参名2,....]:表达式

  示例见:
   lambda.py

# def myadd(x, y):
#     return x + y
# 等同于
myadd = lambda x, y: x + y #创建函数

print('20 + 30 =',myadd(20, 30))
print('40 + 50 =',myadd(40, 50))

fx = lambda:print("hello world!")
fx()
# hello wprld!

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

练习二:
 1.写一个lambda表达式,创建一个函数,此函数判断参数n 的平方
   加1能否被5整除,如果能整除返回True,否则返回False
    fx = lambda n:...
    print(fx(3))  #True
    print(fx(4))  #False

fx  = lambda n: True if (n ** 2 + 1) % 5 == 0  else False
# fx = lambda n:(n ** 2 + 1) % 5 == 0

print(fx(3))
print(fx(4))

 2.写一个lambda表达式,返回两个形参的最大值
   def mymax(x, y):
   ...
   mymax = lambda...
   print(mymax(100,200))   #200


 def mymax(x, y):
    if x > y:
        return x
    else:
        return y

mymax = lambda x, y:max(x, y)
#mymax = lambda x, y:x if x > y else y
print(mymax(100,200))  


看懂下面的程序在做什么?
def fx(f, x, y):
    print(f(x, y))

fx((lambda a, b:a + b),100,200)  
fx((lambda x, y:x ** y),3,4)

#lambda附给f

eval,exec函数
eval()函数
  作用:
   把一个字符当成一个表达式来执行,返回表达式执行后的结果

  注:eval只能给表达式不能给语句
  格式:
   eval(source, globals=None, locals=None)

  示例见:
    eval.py

x = 100
y = 200
s = "x + y"

a = eval(s)   #解释执行s字符串,把表达式的值返回回来
print(a)    #300

b = eval(s,None,{'x':1,'y':2})
print(b)    #3

c = eval(s,{'x':10,'y':20},{'x':1})
print(c)    #21

exec()函数
  作用:
    把一个字符串当成一个程序来执行
  格式:
    exec(source, globals=None, locals=None)
  示例:
s = "x=100\ny=200\nprint('x+y=',x+y)\ndel x, y"   
exec(s)

课后练习:
1.给出一个数n,写一个函数myfac(n)来计算n!(n的阶乘)
 n! = 1*2*3*4*5*....*n

 print(myfac(5))   #120

2.给出一个数n,写一个函数计算:
  1 +2**2+3**3+4**4+....+n**n的和

3.写程序打印杨辉三角(只打印六层)
      
      1
     1 1
    1 2 1
   1 3 3 1
  1 4 6 4 1
1 5 10 10 5 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值