Python基础——认识函数(二)

   日期:2020-04-29     浏览:113    评论:0    
核心提示:Python基础——认识函数(二)1.函数的返回值2.文档字符串3.函数的作用域1.函数的返回值返回python

Python基础——认识函数(二)

  • 1.函数的返回值
  • 2.文档字符串
  • 3.函数的作用域
  • 4.命名空间
  • 5.递归函数
  • 小试牛刀

1.函数的返回值

  • 返回值是函数执行后的结果
  • 通过return来指定函数的返回值
  • return后面可以跟任何对象,甚至是一个函数
  • return会直接跳出函数,不会执行后续的语句
    注意:如果仅仅写一个return或不写,返回是None
# 函数的返回值
# 函数一
def my_fun1(a,b):
    c = a + b
    # 返回值通过return传递
    return c

# 函数二
def my_fun2(a,b):
    # 返回值是函数
    return my_fun1(a,b)

# 函数三
def my_fun3():
    # 返回值空
    return

# 函数四
def my_fun4(a,b):
    c= a + b
    return c
    d = a - b
    print(d)

result = my_fun1(1,2)
print(result)           #3
result2 = my_fun2(3,2)
print(result2)          #5
result3 = my_fun3()
print(result3)          #None
result4 = my_fun4(7,5)
print(result4)          #12

2.文档字符串

  • 文档字符串是用于解释文档程序的重要工具,它没有被执行,但它能帮助解释程序文档
  • 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是对函数的说明
  • help()是Python中内置函数,通过help()函数可以查询Python中函数的用法
# 文档字符串
def my_sum(a,b):
    # 下面'''xxx'''内的内容就是文档字符串,起解释函数参数的作用
    ''' :param a:the first number used to add :param b:the second number used to add :return c:the result of (a + b) '''
    c = a + b
    return c
    
# 调用help()查看函数
help(my_sum)
# Help on function my_sum in module __main__:
# 
# my_sum(a, b)
# :param a:the first number used to add
# :param b:the second number used to add
# :return c:the result of (a + b)

3.函数的作用域

  • 作用域(scope):作用域指的是变量生效的区域
  • 在Python中一共有两种作用域
    • 全局作用域
      • 全局作用域在程序执行时创建,在程序执行结束时销毁
      • 所有函数以外的区域都是全局作用域
      • 在全局作用域中定义的变量,都是全局变量,全局变量可以在程序的任意位置进行访问
    • 函数作用域
      • 函数作用域在函数调用时创建,在调用结束时销毁
      • 函数每调用一次就会产生一个新的函数作用域
      • 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问
  • 可以使用global在函数内部声明,使其能在函数内部对函数外的变量进行操作
# 作用域
# 在函数外,为全局变量
num1 = 10
num2 = 20
def my_sum(a,b):
    c = a + b
    # 在函数内,为局部变量
    num1 = 5
    # 使用global将num2声明为全局变量
    global num2
    num2 = 66
    print('函数内部:num1 =',num1)
    print('函数内部:num2 =', num2)
    return c
result = my_sum(7,8)
# 函数内部:num1 = 5
# 函数内部:num2 = 66
print('函数外部:num1 =',num1)     #函数外部:num1 = 10
print('函数外部:num2 =',num2)     #函数外部:num2 = 66

4.命名空间

  • 命名空间实际上就是一个字典,是一个专门用来存储变量的字典
  • locals()用来获取当前作用域的命名空间
  • 如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间
  • 返回值是一个字典
# 命名空间
num = 6
def fun(a,b):
    c = a * b
    return c

result = fun(12,4)
print(result)               #48

#获取当前命名空间
namespace = locals()
print(type(namespace))      #<class 'dict'>
print(namespace)
# 输出结果:
# {'__name__': '__main__', '__doc__': None, '__package__': None,
# '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000027B6E416080>,
# '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
# '__file__': 'E:/day10/函数.py', '__cached__': None, 'num': 6,
# 'fun': <function fun at 0x0000027B70079620>, 'result': 48, 'namespace': {...}}

# 可以查看我们在当前页面定义的num、fun以及result是否在其中
print(namespace['num'])             #6
print(namespace['fun'])             #<function fun at 0x000001856B5196A8>
print(namespace['result'])          #48
# 试试查看当前空间不包含的参数 s
print(namespace['s'])               #KeyError: 's'
# 使用命名空间调用函数
print(namespace['fun'](12,4))       #48

5.递归函数

  • 递归是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,在去解决问题
  • 递归式函数有2个条件:
    • 1.基线条件:问题可以被分解为最小问题,当满足基线条件时,递归就不执行了
    • 2.递归条件:可以将问题继续分解的条件
# 递归函数
def my_fun(my_str):
    ''' :function:评定输入是否为回文字符串 :my_str: 输入字符串 type:str :return : True(是回文字符串) False(不是回文字符串) '''
    # 基线条件
    if len(my_str) <2:
        return True
    elif my_str[0] != my_str[len(my_str)-1]:
        return False
    else:
        # 递归条件:字符串首尾相同,去掉字符串首尾
        return my_fun(my_str[1:-1])

print(my_fun('123321'))         #True
print(my_fun('pytyp'))          #True
print(my_fun('ajfoij'))         #False

小试牛刀

  • 汉诺塔游戏:
      现在有ABC三根柱子。要求:将A柱所有的圆盘放到C柱。在移动的过程中可以借助B柱。并且规定大圆盘不能放小圆盘上面,每次只能移动一个盘子。用递归的方式来解决汉诺塔问题。

对于初学者来说真心有难度,下面可能只是现在能想到的一种较难的实现方法,若有更好的方法,欢迎提出,谢谢!

# 汉诺塔游戏:
# 现在有ABC三根柱子。要求:将A柱所有的圆盘放到C柱。
# 在移动的过程中可以借助B柱。并且规定大圆盘不能放小圆盘上面,
# 每次只能移动一个盘子。用递归的方式来解决汉诺塔问题

# 分析
''' # 初始化 在游戏开始时,假设放置了n个圆盘在A柱子上,由于大圆盘不能在小圆盘上, 所以A上的圆盘从上往下以此变小,我们将这n个从上到下的圆盘编号为: 1,2,3,4...n-1,n # 分析 当有1个盘子:A->C mov(A,C,1) <=> mov(A,C,1) 当有2个盘子:A->B,A->C,B->C mov(A,C,2) <=> mov(A,B,1) + mov(A,C,1) + mov(B,C,1) 当有3个盘子:A->C,A->B,C->B, A->C, B->A,B->C,A->C mov(A,C,3) <=> mov(A,B,2) + mov(A,C,1) + mov(B,C,2) ... 当有n个盘子: mov(A,C,n) <=> mov(A,B,n-1) + mov(A,C,1) + mov(B,C,n-1) 其中 :mov(src,dst,n)表示将n个圆盘从src移到dst(不是直接一下移动了n个,是一步步通过空余柱子转移从而移动n个的) # 基线条件 只剩最后一个圆盘需要移动 # 递归条件 mov(A,C,n) <=> mov(A,B,n-1) + mov(A,C,1) + mov(B,C,n-1) 其中为了表示哪个柱子做了桥梁用于给传递圆盘用作过渡,便还需要添加一个参数med作为这个"桥梁" 即上面的式子可一般化为: mov(src,dst,med,n) = mov(src,med,dst,n-1) + mov(src,dst,med,1) + mov(med,dst,src,n-1) '''

# 获取A,B,C三个柱子上的圆盘数量
def put_A_num(n):
    # A柱子
    src = ['A',':']
    for i in range(n,0,-1):
        src.append(i)
    return src

def put_B_num(n):
    # B柱子
    src = ['B',':']
    for i in range(n,0,-1):
        src.append(i)
    return src

def put_C_num(n):
    # C柱子
    src = ['C',':']
    for i in range(n,0,-1):
        src.append(i)
    return src

# 用于显示每一步移动操作后柱子上圆盘的情况
def show_data(data1,data2,data3,character):
    # 显示对应character的柱子上的圆盘
    if data1[0] == character:
        print(data1[0:1],data1[2:])
    elif data2[0] == character:
        print(data2[0:1], data2[2:])
    else:
        print(data3[0:1], data3[2:])

# 用于实现从A柱子上将n个圆盘移到C柱子上
def mov(src, dst, med, n):
    global step
    if n == 1:
        # 当只需移动一个盘子时
        step += 1
        disk = src.pop()
        dst.append(disk)
        # 下面全是用于显示的操作,与移动盘子无关
        print('第'+str(step)+'步:')
        print('将'+str(disk)+'从'+src[0]+'中移到'+dst[0])
        show_data(src, dst, med, 'A')
        show_data(src, dst, med, 'B')
        show_data(src, dst, med, 'C')
        print()
    else:
        # 将移动n个盘子分为三步执行
        mov(src, med, dst, n-1)
        mov(src, dst, med, 1)
        mov(med, dst, src, n-1)
        print('共用了'+str(step)+'步!')

# 将所有函数整合在一个函数中
def HNT_game_start(n):
    global step
    step = 0
    src = put_A_num(n)
    med = put_B_num(0)
    dst = put_C_num(0)
    print('下面是你输入的参数生成的对应柱子上的圆盘!')
    print(src[0:1], src[2:])
    print(med[0:1], med[2:])
    print(dst[0:1], dst[2:])
    print()
    mov(src, dst, med, n)

# 通过你输入的参数查看如何移动
num = int(input('欢迎使用汉诺塔游戏破解版,请输入你想从A柱子移动到A柱子的数量:'))
HNT_game_start(num)

当A上悬挂的盘子数量为3时(太长了不好截图,),执行结果如下:

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服