# 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()
标签:return,函数,filename,嵌套,func,print,def From: https://www.cnblogs.com/mengdie1978/p/16774573.html
# 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())