09函数-返回值、作用域、递归...

1. 函数的返回值

  • 返回值就是函数执行后返回的结果
  • 通过return来指定返回结果
  • return后面可以是任意类型的结果
#求任意个数的和
# def s(*b):
#     r = 0
#     for i in b:
#         r += i
#     print(r)
# s(1, 2, 3, 4, 5, 99) # 114
'''
return后面可以是任意类型的值,是什么函数就返回什么
'''
def fn():
    return 123
r=fn()
print(r)    # 123
print(fn)   # <function fn at 0x0000000002862598>
print(fn()) # 123

def fn1():
    print('执行fn1啦')
    def fn2():
        print('执行fn2啦')
    return fn2
    # return后的语句是永远不会执行的
    print('执行完return啦')
m = fn1()   # 执行fn1啦
print(m)    # <function fn1.<locals>.fn2 at 0x00000000028E2730>
m()         # 执行fn2啦
'''
break与return的区别
break是退出循环,函数中后面其他语句可以执行
return是退出函数,return后面函数中语句不能执行
return是用来结束函数的
'''
def fn3():
    for i in range(5):
        print(i)
        if i==3:
            # break
            # continue 仅跳过当次循环
            return
    print('循环执行完毕')
fn3()

# 求任意个数的和
def s(*b):
    r = 0
    for i in b:
        r += i
    # print(r)
    return r
n= s(1, 2, 3, 4, 5, 99) # 114
print(n+2)      # 116

# fn函数对象  fn()调用函数
def fn():
    # return 123
    print('python')
print(fn)       # <function fn at 0x00000000028A28C8>
print(fn())
# 结果是:
# python  # 打印语句执行
# None   # 没有返回值,是空
fn()            # python  直接调用函数,执行打印语句

2. 文档字符串

  • help()是python的内置函数
  • 通过help(函数对象)可以查询定义的函数对象的用法
  • 定义函数时在函数内部编写文档字符串,文档字符串是对函数的说明
'''
help()可以查询python中函数的用法
语法:help(函数对象)
help(print)
'''
# help(print)
def fn(a:int, b:str, c:bool)->int:
    '''
    这是一个文档字符串案例
    :param a:
    :param b:
    :param c:
    :return:
    '''
    return 123
help(fn)

3. 函数的作用域(scope)

  • 作用域指变量生效的区域
  • 分为全局作用域和函数作用域
  • 全局作用域在程序执行时创建,在程序执行结束时销毁
    。所有函数以外的区域都是全局作用域
    。所有在全局作用域定义的变量都是全局变量,可以从程序的任意位置访问调用全局变量
  • 函数作用域在函数调用时创建,在函数调用结束时销毁
    。函数每调用一次,产生一个新的函数作用域
    。在函数作用域中定义的变量是局部变量,只能在函数内部被访问
# 作用域scope
# 作用域指变量生效的区域
# 全局作用域b
# 函数作用域a
# b=20
# def fn():
#     a=2
#     print('函数内部:', 'a =', a)
#     print('函数内部:', 'b =', b)
#
# fn()
# # print('函数外部:', 'a =', a)  # NameError: name 'a' is not defined
# print('函数外部:', 'b =', b)

# 从函数内部可以访问外部的数据,从外部却不能访问里面的数据
def fn1():
    a=10
    def fn2():
        b=40
        print('fn2中的a', a)
        print('fn2中的b', b)
    fn2()
    print('fn1中的a', a)
    # print('fn1中的b', b)  # NameError: name 'b' is not defined
fn1()
# 在函数内部修改全局变量
a = 20
def fn3():
    global a
    a = 3
    print('函数内部:', 'a =', a)    # 函数内部: a = 3

fn3()

print('函数外部:', 'a =', a)    # 函数外部: a = 3

4. 命名空间

  • 命名空间实际上是一个专门存储变量的字典
  • locals()用来获取当前作用域的命名空间
  • 返回值是字典
# 命名空间是一个专门用来存储变量的字典
# locals()是用来获取当前作用域的命名空间,返回值时字典

a=20
b=30
scope=locals()

print(scope)
print(scope['a'])
print(scope['b'])
# 可以通过向字典添加k-v值向全局的命名空间增值,但不建议使用
# 而且在函数中这种添加方式会失败
scope['c']=99
print(scope['c'])
print(c)    # 99  添加成功
def fn():
    a = 33
    b = 22
    scope = locals()
    # scope['d'] = 55
    # print(scope)
    # print(scope['a'])
    # print(scope['b'])
    # print(scope['d'])
    # print(d)    # NameError: name 'd' is not defined

    # globals() 获取全局变量
    global_scope=globals()
    print(global_scope)     # ...'a': 20, 'b': 30, 'scope': {...}, 'c': 99, 'fn': <function fn at 0x0000000002892730>

fn()

5. 递归函数

  • 递归是将一个大问题分解为一个一个小问题,直到无法再分解为止
  • 递归函数有两个条件
    。基线——大问题可以被分解为的最小问题,满足基线条件时,递归不再执行
    。递归条件——将问题继续分解的条件(此处就像剥洋葱,直到无法再剥)
# 求10!,10的阶乘
# 1!=1
# 2!=2*1
# 3!=3*2*1
# .....
# 10!=10*9*8*7*6*5*4*3*2*1
# r = 10
# for i in range(1,10):
#     r*=i
# print(r)
# print(10*9*8*7*6*5*4*3*2*1)

# 定义一个函数来求任意数num的阶乘num!

# def factorial_num(num):
#     '''
#
#     :param num: int,
#     :return: int
#     '''
#     for i in range(1,num):
#         num*=i
#     return num
#
# r = factorial_num(10)
# print(r)

# 递归是一种解决问题的方式
# 简单来说递归就是自己引用自己,递归函数就是在函数中调用自己
# 递归的两个条件:
#   1.基线条件——问题可被分解为的最小条件,当满足次条件时递归不再执行
#   2.递归条件——将问题继续分解的条件
# 如果缺少递归中的条件基线,则为无穷递归,类似死循环
# def factorial_some():
#     基线条件
#         return
#     递归条件
#     factorial_some()
# factorial_some()

# 用递归的解决方案来实现任意数的阶乘
# 10!=10*9!
# 9!=9*8!
# ...
# 1!=1
def factorial_num(num):

    # 基线条件——最小为1阶乘为1(这里我们没有考虑0!=1)
    if num == 1:
        return 1

    # 递归条件——继续分解条件
    return num*factorial_num(num-1)

r = factorial_num(5)
print(r)
  • 递归练习:
# 练习一 定义一个函数:计算任意数的任意次幂
# caculate_num(num,p)

# 循环的方式:
# def caculate_num(num, p):
#     res = 1
#     for i in range(1, p+1):
#         res *= num
#
#     return res
# r = caculate_num(1, 4)
# print(r)

# 递归的方式:
# 参数 num 的 p 次幂
# def caculate_num(num, p):
#
#     # 条件一:基线条件 分解的最小事件
#     if p == 1:
#         return num
#
#     # 条件二:递归条件 继续分解的条件
#     return num*caculate_num(num, p-1)
# res = caculate_num(3, 5)
# print(res)

# 练习二 : 创建函数检查一个字符串是否是回文,是返回True,不是返回False
# check_Palindrome(s)
# 把字符串存入列表中处理 获取字符串长度len()

# 循环方式:

# s = list(input('输入字符串:'))
# m = len(s)
# print(m)
# for i in range(m):
#
#     if s[i] == s[m-i-1]:
#         if i == m//2:
#             print(s[i])
#             print('True')
#     else:
#         print('False')
#         break

# 循环放入函数中
# s = list(input('输入字符串:'))
# def check_palindrome(s):
#     m = len(s)
#     for i in range(m):
#
#         if s[i] == s[m - i - 1]:
#             if i == m // 2:
#                 print(s[i])
#                 return 'True'
#         else:
#             return 'False'
# print(check_palindrome(s))

# 递归方式:
# 是不是考虑类似剥洋葱的思想,剥掉一层还一层
# 比较 abcdefgfedcba 第一个和最后一个是否一致
# 比较 bcdefgfedcb 第一个和最后一个是否一致
# 比较 cdefgfedc 第一个和最后一个是否一致
# 比较 defgfed 第一个和最后一个是否一致
# 比较 efgfe 第一个和最后一个是否一致
# ...
# 比较 fgf 第一个和最后一个是否一致
# g 字符串长度小于2时,一定为回文
# 字符串第一个和最后一个不一致时,一定不是回文
s = list(input('输入字符串:'))
def check_palindrome(s):
    print(s[1:-1])
    # 条件一:基线
    if len(s)<2:
        return True
    elif s[0]!=s[-1]:
        return False
    # 条件二:循环
    return check_palindrome(s[1:-1])    # 相当于s1=s[1:-1],s2=s1[1:-1]...

print(check_palindrome(s))

# 递归另一种写法
def another_check(s):
    if len(s) < 2:
        return True
    return s[0] == s[-1] and another_check(s[1:-1])

print(another_check(s))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章