Python基础练习——函数作用域+递归

变量作用域

  • 变量由作用范围限制
  • 分类:按照作用域分类
    • 全局(global): 在函数外部定义
    • 局部(local):在函数内部定义
  • 变量的作用范围:
    • 全局变量:在整个全局范围都有效
    • 全局变量在局部可以使用(即函数内部可以访问函数外部定义的变量)
    • 局部变量在局部范围可以使用
    • 局部变量在全局范围无法使用
  • LEGB原则
    • L(Local)局部作用域
    • E(Enclosing function locale)外部嵌套函数作用域
    • G(Global module)函数定义所在模块作用域
    • B(Buildin): python内置魔抗的作用域
In [4]:
# 认为a1是全局的
a1 = 100

def fun():
    print(a1)
    print("I am in fun")
    # a2的作用范围是fun
    a2 = 99
    print(a2)
    
    
print(a1)         #全局变量a1
fun()
print(a2)         #局部变量a2
100
100
I am in fun
99
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
 in ()
     12 print(a1)         #全局变量a1
     13 fun()
---> 14 print(a2)         #局部变量a2

NameError: name 'a2' is not defined

提升局部变量为全局变量

  • 使用global
  • 案例如下
In [6]:
def fun():
    global b1
    b1 = 100
    print(b1)
    print("I am in fun")
    # a2的作用范围是fun
    b2 = 99
    print(b2)
    
    

#print(b2)
fun()
# print(b1)如果在函数调用上面,则不好使,报错,为什么???
print(b1)
100
I am in fun
99
100

globals, locals函数

  • 可以通过globals和locals显示出局部变量和全局变量
  • 参看以下案例
In [10]:
# globals 和 locals
# globals 和 locals 叫做内建函数
a = 1
b = 2

def fun(c,d):
    e = 111
    print("Locals={0}".format(locals()))
    print("Globals={0}".format(globals()))
    
fun(100, 200)
Locals={'e': 111, 'd': 200, 'c': 100}
Globals={'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': , '__builtins__': , '_ih': ['', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\nprint(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\n#print(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\nprint(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)         #全局变量a1\nfun()\nprint(a2)         #局部变量a2', '\ndef fun():\n    global b1\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    b2 = 99\n    print(b2)\n    \n    \n\n#print(b2)\nfun()\n# print(b1)如果在函数调用上面,则不好使,报错,为什么???\nprint(b1)', 'def fun():\n    global b1\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    b2 = 99\n    print(b2)\n    \n    \n\n#print(b2)\nfun()\n# print(b1)如果在函数调用上面,则不好使,报错,为什么???\nprint(b1)', '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', 'a = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)'], '_oh': {}, '_dh': ['C:\\Users\\Administrator\\Python练习\\基础语法练习'], 'In': ['', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\nprint(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\n#print(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\nprint(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)         #全局变量a1\nfun()\nprint(a2)         #局部变量a2', '\ndef fun():\n    global b1\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    b2 = 99\n    print(b2)\n    \n    \n\n#print(b2)\nfun()\n# print(b1)如果在函数调用上面,则不好使,报错,为什么???\nprint(b1)', 'def fun():\n    global b1\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    b2 = 99\n    print(b2)\n    \n    \n\n#print(b2)\nfun()\n# print(b1)如果在函数调用上面,则不好使,报错,为什么???\nprint(b1)', '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', 'a = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)'], 'Out': {}, 'get_ipython': >, 'exit': , 'quit': , '_': '', '__': '', '___': '', '_i': 'a = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '_ii': '\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '_iii': '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '_i1': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\nprint(a2)', 'a1': 100, 'fun': , '_i2': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\n#print(a2)', '_i3': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)\nfun()\nprint(a2)', '_i4': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    a2 = 99\n    print(a2)\n    \n    \nprint(a1)         #全局变量a1\nfun()\nprint(a2)         #局部变量a2', '_i5': '\ndef fun():\n    global b1\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    b2 = 99\n    print(b2)\n    \n    \n\n#print(b2)\nfun()\n# print(b1)如果在函数调用上面,则不好使,报错,为什么???\nprint(b1)', 'b1': 100, '_i6': 'def fun():\n    global b1\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    # a2的作用范围是fun\n    b2 = 99\n    print(b2)\n    \n    \n\n#print(b2)\nfun()\n# print(b1)如果在函数调用上面,则不好使,报错,为什么???\nprint(b1)', '_i7': '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', 'a': 1, 'b': 2, '_i8': '\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '_i9': 'a = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)', '_i10': '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n    \nfun(100, 200)'}

eval()函数

  • 把一个字符串当成一个表达式来执行, 返回表达式执行后的结果
  • 语法: eval(string_code, globals=None, locals=None)

exec()函数

  • 跟eval功能类似, 但是,不返回结果
  • 语法: exec(string_code, globals=None, locals=None)
In [14]:
#eval()函数
x = 100
y = 200
#执行 x+y
#  z= x + y
z1 = x + y
z2 = eval('x + y')
print(z1)
print(z2)
300
300
In [28]:
#exec()函数
x = 100
y = 200
#执行 x+y
#  z= x + y
z1 = x + y

 # 1, 注意字符串中引号的写法
 # 2. 比对exec执行结果和代码执行结果
z2 = exec("print('x + y = ', x + y)")
x + y =  300
In [29]:
print(z2)
print(z1)
None
300

递归函数

  • 在函数中调用当前函数本身的函数就是递归函数。
  • 优点:简洁,理解容易
  • 缺点:对递归深度有限制,消耗资源大
  • python对递归深度有限制,超过限制报错
  • 在写递归程序的时候,一定注意结束条件
In [30]:
#定义递归函数

def recursion(n):
    #输出当前的n的值
    print(n)

    #判断n的值是否>0,决定下一步操作
    if n>0:        #n>0 在此调用当前函数digui,将n - 1放进去
        recursion(n-1)
    else:
        #n>0 为False 输出分隔线
        print('------')

    #再次输出n的值
    print(n)


#调用递归函数
recursion(3)
3
2
1
0
------
0
1
2
3
In [33]:
# 斐波那契数列
# 一列数字,第一个值是1, 第二个也是1, 从第三个开始,每一个数字的值等于前两个数字出现的值的和
# 数学公式为: f(1) = 1, f(2) = 1, f(n) = f(n-1) + f(n-2)
# 例如: 1, 1,2,3, 5, 8, 13.。。。。。。。。

# 下面求斐波那契数列函数有一定问题,比如n一开始就是负数,如何修正
# n表示求第n个数子的斐波那契数列的值
def fib(n):
    if n == 1:
        return 1
    
    if n == 2:
        return 1
    
    # 思考:为什么后面return能够正确执行,而不用else语句
    return fib(n-1) + fib(n-2)

print(fib(3))
print(fib(10))
2
55

递归——汉诺塔问题

  • 规则:
      - 每次移动一个盘子
      - 任何时候大盘子在下面,小盘子在上面
  • 方法:
      - n=1: 直接把A上的一个盘子移动到C上, A->C
      - n=2:  把小盘子从A放到B上, A->B
              把大盘子从A放到C上, A->C
              把小盘子从B放到C上, B->C
      - n=3:
              把A上的两个盘子,通过C移动到B上去, 调用递归实现
              把A上剩下的一个最大盘子移动到C上, A->C
              把B上两个盘子,借助于A,挪到C上去, 调用递归
      - n = n:
              把A上的n-1个盘子,借助于C,移动到B上去,调用递归
              把A上的最大盘子,也是唯一一个,移动到C上,A->C
              把B上n-1个盘子,借助于A,移动到C上, 调用递归
In [50]:
def hannuota(n,A,B,C):
    '''
    汉诺塔的递归实现
    n:代表几个盘子
    a:代表第一个塔,开始的塔
    b:代表第二个塔,中间过渡的塔
    c:代表第三个塔, 目标塔
    '''
    if n == 1:
        print(A,'------>',C)
        return None

    if n == 2:
        print(A,'------>',B)
        print(A,'------>',C)
        print(B,'------>',C)
        return None
        

    
    # 把n-1个盘子,从a塔借助于c塔,挪到b塔上去
    hannuota(n-1,A,C,B)
    #把A上的最大盘子,也是唯一一个,移动到C上,A->C
    print(A,'------>',C)
    # 把n-1个盘子,从b塔,借助于a塔,挪到c塔上去
    handuota(n-1,B,A,C)

'''
A = 'a'
B = 'b'
C = 'c'
'''
n = 2
hannuota(n,a,b,c)
    
A ------> B
A ------> C
B ------> C
In [49]:
def hano(n, a, b, c):
    '''
    汉诺塔的递归实现
    n:代表几个盘子
    a:代表第一个塔,开始的塔
    b:代表第二个塔,中间过渡的塔
    c:代表第三个塔, 目标塔
    '''
    if n == 1:
        print(a, "-->", c)
        return None
    '''
    
    if n == 2:
        print(a, "-->", b)
        print(a, "-->", c)
        print(b, "-->", c)
        return None
    '''
    # 把n-1个盘子,从a塔借助于c塔,挪到b塔上去
    hano(n-1, a, c, b)
    print(a, "-->", c)
    # 把n-1个盘子,从b塔,借助于a塔,挪到c塔上去
    hano(n-1,b, a, c)
    
a = "A"
b = "B"
c = "C"

n = 3
hano(n, a, b, c)
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C

你可能感兴趣的:(Python基础,Python基础,语法练习)