首页 > 其他分享 >函数嵌套

函数嵌套

时间:2022-10-10 09:59:11浏览次数:45  
标签:return 函数 filename 嵌套 func print def

# def outer1():
# o=65
# def inner():
# print("inner {}".format(o))
# print(chr(o))
# print("outer {}".format(o))
# inner()
# outer1()
 def outer1():
      o=65
      def inner():
         print("inner {}".format(o))
         print(chr(o))
      print("outer {}".format(o))
      inner()
outer1()

# def outer2():
# o=65
# def inner():
# o=97
# print("inner {}".format(o))
# print(chr(o))
# print("outer {}".format(o))
# inner()
# outer2()

# x=5
# def foo():
# y=x+1
# x+=1
# print(x)
# foo()

# def outer(n):
# def inner_multiple(n):
# return n*2
# num=inner_multiple(n)
# print(num)
# outer(5)
# 这是因为它被定义在 outer() 的内部,被隐藏了起来,所以外部无法访问。
# inner_multiple(5)
'''
嵌套函数的基本概念在前面已经介绍过了,参见:Python 函数的高级用法

那么,一般在什么情况下使用嵌套函数?

封装 - 数据隐藏
贯彻 DRY 原则
闭包
除此之外,嵌套函数还有其他用法,只不过这些是比较常用的。另外,闭包的内容较为丰富,后面做单独分享。

封装 - 数据隐藏
可以使用内层函数来保护它们不受函数外部变化的影响,也就是说把它们从全局作用域隐藏起来。

来看一个简单的例子 - 求一个数字 n 的倍数:

'''

# def factorial(n):
# # 错误处理
# if not isinstance(n, int): # 仅限整形
# raise TypeError("Sorry. 'n' must be an integer.")
# if n < 0: # 仅限 0 和 正数
# raise ValueError("Sorry. 'n' must be zero or positive.")
#
# def inner_factorial(n):
# if n <= 1:
# return 1
# return n * inner_factorial(n - 1)
# return inner_factorial(n)

# factorial('Py')

# factorial(-10)
# 使用这种模式的主要优势在于:利用外部函数执行所有的参数检查,便可以在内部函数中跳过错误检查,并安全放心地进行使用。
# print(factorial(5))

'''
贯彻 DRY 原则

DRY(Don’t Repeat Yourself)- 是指在程序设计以及计算中避免重复代码,因为这样会降低灵活性、简洁性,
并且有可能导致代码之间的矛盾。

DRY 更多的是一种架构设计思想,在软件开发过程中的万事万物均可能重复,大到标准、框架、开发流程;中到组件、
接口;小到功能、代码均纯存在自我重复。而 DRY 提倡的就是在软件开发过程中应消除所有这些自我重复。

'''
# 支持文件对象:

# def print_file(f):
# for line in f:
# print(line)
# f=open('data.txt','r')
# print_file(f)

# 支持文件名:
# def print_file_content(file_name):
# if isinstance(file_name,str):
# with open(file_name,'r') as f:
# for line in f:
# print(line)
# print_file_content('data.txt')


# def print_file(file):
# def inner_print(file_process):
# for line in file_process:
# print(line,end=' ')
# if isinstance(file,str):
# with open(file,'r') as f:
# inner_print(f)
# else:
# inner_print(file)

# f=open('data.txt','r')
# print_file(f)

# print_file('data.txt')

# def out_func(out_name):
# def in_func(in_name):
# print(out_name.title(),end='\n') # 内部函数可以访问外部函数的变量,但不能使用不能改变
# print("=++="+in_name.title())
# print("this is user()")
# return in_func # 返回的是内部函数对象,也就是内部函数地址。

# a=out_func("tom")
# print(a)
# print(type(a))

# this is user()
# <function out_func.<locals>.in_func at 0x00000247A1C9DB80>
# <class 'function'>


# a=out_func("tom") #返回的是in_func这个函数对象
# a("jerry") #相当于in_func("jerry")
# out_func("tom")("jerry")

# def func(a,b):
# return a+b
# add=func
# print(func(1,2))
# print(add(3,4))

'''
函数是第一类对象
和list, tuple, dict以及用House创建的对象一样,当你定义一个函数时,函数也是对象:
在全局域,函数对象被函数名引用着,它接收两个参数a和b,计算这两个参数的和作为返回值。

说明⚠️:所谓第一类对象,意思是可以用标识符给对象命名,并且对象可以被当作数据处理,例如赋值、作为参数
传递给函数,或者作为返回值return 等

因此,你完全可以用其他变量名引用这个函数对象:

'''
# def caller_func(f):
# return f(3,5)
# if __name__=="__main__":
# print(caller_func(func))
'''
可以看到:
1.函数对象func作为参数传递给caller_func函数,传参过程类似于一个赋值操作f=func;
2.于是func函数对象,被caller_func函数作用域中的局部变量f引用,f实际指向了函数func;
3.当执行return f(1, 2)的时候,相当于执行了return func(1, 2);
因此输出结果为3。
'''
# filename="foo.py"
#
# import foo
# filename="test19-函数嵌套.py"
# def show_filename():
# # return "filename: %s" % filename
# return "filename: %s" % filename
# if __name__=="__main__":
# print(foo.call_func(show_filename))
# import foo
# def wrapper():
# filename="test19-函数嵌套.py"
# def show_filename():
# return "filename: %s" % filename
# return "filename: %s" % filename #输出:filename: enclosed.py
# if __name__ == "__main__":
# print(foo.call_func(wrapper)) #注意:实际发生调用的
# filename: test19-函数嵌套.py

"""
当代码执行到show_filename中的return "filename: %s" % filename语句时,解析器按照下面的顺序查找
filename变量:

Local - 本地函数(show_filename)内部,通过任何方式赋值的,而且没有被global关键字声明为全局变量的
filename变量;
Enclosing - 直接外围空间(上层函数wrapper)的本地作用域,查找filename变量(如果有多层嵌套,则由内而外逐
层查找,直至最外层的函数);
Global - 全局空间(模块enclosed.py),在模块顶层赋值的filename变量;
Builtin - 内置模块(builtin)中预定义的变量名中查找filename变量;
在任何一层先找到了符合要求的filename变量,则不再向更外层查找。如果直到Builtin层仍然没有找到符合要求的
变量,则抛出NameError异常。这就是变量名解析的:LEGB法则。

总结⚠️:

闭包最重要的使用价值在于:封存函数执行的上下文环境;
闭包在其捕捉的执行环境(def语句块所在上下文)中,也遵循LEGB规则逐层查找,直至找到符合要求的变量,或者
抛出异常。

"""
# def lazy_sum():
# return reduce(lambda x,y:x+y,alist)
# alist=range(1,101)
# from functools import reduce
# # import reduce
# def wrapper():
# alist=range(1,101)
# def lazy_sum():
# return reduce(lambda x,y:x+y ,alist)
# return lazy_sum
# lazy_sum=wrapper()
# if __name__=="__main__":
# print(lazy_sum())

标签:return,函数,filename,嵌套,func,print,def
From: https://www.cnblogs.com/mengdie1978/p/16774573.html

相关文章

  • 上位笔记_01_窗口间传递信息(构造函数)
    在登录窗口登录后,给下一级窗口传递当前登录用户名登录按键中进行新窗口实例创建构造函数中增加对username的初始化  ......
  • python 字典的嵌套使用案例
    staff_infor_dict={#员工信息"王力宏":{"部门":"科技部","工资":3000,"级别":1},"周杰伦":{"部门":"市......
  • 网络字节序与主机字序的转换函数实践
    1.网络字节序网络上传输的数据都是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它将这个字节作为高位字......
  • TCP与UDP的联系与区别(以及网络字节序与主机字节序的转换函数实践)
    TCP和UDP区别这两种传输方式都在实际的网络编程中使用,重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则可以通过UDP方式进行传递,在一些程序中甚至结合使用这两......
  • 函数的基本使用
    函数的基本使用函数存在的意义''' 在我们平时打代码的时候,有些代码重复量很大,为了代码的简洁性,可循环利用性,所以我们要使用函数'''name_list=['jason','kevin','o......
  • 函数相关基础知识
    昨日内容回顾文档的打开方式open()withopen()asf文档的读写模式r(只读)w(只写)a(追加写)文档的操作模式t(文本模式)b(二进制模式)文......
  • 函数的基本使用
    函数前戏name_list=['jason','kevin','oscar','jerry']#print(len(name_list))'''突然len不准用了'''#count=0#foriinname_list:#count+=1#pr......
  • Day10函数基础学习以及计算机硬盘修改数据的原理(了解)
    今日内容概要文件内光标的移动实战演练计算机硬盘存取数据的原理文件内容修改函数简介函数的语法结构函数的定义与调用内容详细文件内光标移动案例(了解)im......
  • 文件相关知识点及函数基本知识点
    文件相关知识点及函数基本知识点目录文件相关知识点及函数基本知识点一、文件读写总概括二、计算机硬盘修改数据的原理(了解)三、文件内容修改(了解)四、函数简介五、函数语法......
  • 文件操作及函数基本知识
    文件操作利用python代码的编写来读写文件1.文件的概念就是操作系统暴露给用户操作硬盘的快捷方式eg:双击一个文件其实是从硬盘将数据加载到内存ctrl+s保存文件其实......