内层函数——它们的优点是什么?
让我们看一下写内层函数的三个常见原因。
记住:在Python中,函数是“一等公民”,这意味着它们和其他对象平起平坐(例如:整型,字符串,列表,模块等)。你可以动态地创建和销毁它们,把它们传递给其他函数,把它们作为值返回,等等。
本文使用Python 3.4.1版本
1.封装
你使用内层函数来保护它们不受函数外部变化的影响,也就是说把它们从全局作用域藏起来。
这里有一个简单的例子来强调这一概念:
12345678 | def outer(num1): def inner_increment(num1): # hidden from outer code return num1 + 1 num2 = inner_increment(num1) print(num1, num2) inner_increment(10)# outer(10) |
尝试调用inner_increment()
函数
1234 | Traceback (most recent call last): File \”inner.py\”, line 7, in <module> inner_increment()NameError: name \’inner_increment\’ is not defined |
现在,把inner_increment
的调用注释掉,再把对外部函数调用的注释取消,outer(10)
,把10作为参数传入:
1 | 10 11 |
请记住这仅仅是一个例子,尽管代码得到了期望的结果,但是使用一个前置的下划线把
inner_increment()
函数变为“私有”函数:_inner_increment()
更好。
下面这个递归的例子与使用嵌套函数相比稍微好一些:
12345678910111213141516 | def factorial(number): # error handling if not isinstance(number, int): raise TypeError(\”Sorry. \’number\’ must be an integer.\”) if not number >= 0: raise ValueError(\”Sorry. \’number\’ must be zero or positive.\”) def inner_factorial(number): if number <= 1: return 1 return number*inner_factorial(number–1) return inner_factorial(number) # call the outer functionprint(factorial(4)) |
同样测试一下这段代码。使用这种设计模式的一个主要优势在于:在外部函数中对全部参数执行了检查,你可以在内部函数中跳过全部的检查过程。
关于这个递归更加详细的解释请看Problem Solving with Algorithms and Data Structures
2.贯彻DRY(Don’t Repeat Yourself )原则
也许你有一个巨型函数,在很多很多地方执行一大段的代码。比如,你可能写了一个函数用来处理文件,并且你希望它既可以接受一个打开文件对象或是一个文件名:
123456789 | def process(file_name): def do_stuff(file_process): for line in file_process: print(line) if isinstance(file_name, str): with open(file_name, \’r\’) as f: do_stuff(f) else: do_stuff(file_name) |
同样,通常会把
do_stuff()
作为一个顶层私有函数,但是如果你想要把它作为一个内层函数隐藏起来,你也可以这样做。
来个实际的例子怎么样?
让我们假设你想知道纽约市全部WiFi热点的数量。而且确实有提供这些信息的原始数据: 数据。
访问这个网站并下载CSV.
if key > max_key:
max_key = key
business = name
print(\’There are {0} WiFi hot spots in NYC and {1} has the most with {2}.\’.format(
all_locations, business, max_key))
if isinstance(file_name, str):
with open(file_name, \’r\’) as f:
do_stuff(f)
else:
do_stuff(file_name)
process(\”NAME_OF_THE.csv\”)
v>
内层函数——它们的优点是什么?
让我们看一下写内层函数的三个常见原因。
记住:在Python中,函数是“一等公民”,这意味着它们和其他对象平起平坐(例如:整型,字符串,列表,模块等)。你可以动态地创建和销毁它们,把它们传递给其他函数,把它们作为值返回,等等。
本文使用Python 3.4.1版本
1.封装
你使用内层函数来保护它们不受函数外部变化的影响,也就是说把它们从全局作用域藏起来。
这里有一个简单的例子来强调这一概念:
12345678 | def outer(num1): def inner_increment(num1): # hidden from outer code return num1 + 1 num2 = inner_increment(num1) print(num1, num2) inner_increment(10)# outer(10) |
尝试调用inner_increment()
函数
1234 | Traceback (most recent call last): File \”inner.py\”, line 7, in <module> inner_increment()NameError: name \’inner_increment\’ is not defined |
现在,把inner_increment
的调用注释掉,再把对外部函数调用的注释取消,outer(10)
,把10作为参数传入:
1 | 10 11 |
请记住这仅仅是一个例子,尽管代码得到了期望的结果,但是使用一个前置的下划线把
inner_increment()
函数变为“私有”函数:_inner_increment()
更好。
下面这个递归的例子与使用嵌套函数相比稍微好一些:
12345678910111213141516 | def factorial(number): # error handling if not isinstance(number, int): raise TypeError(\”Sorry. \’number\’ must be an integer.\”) if not number >= 0: raise ValueError(\”Sorry. \’number\’ must be zero or positive.\”) def inner_factorial(number): if number <= 1: return 1 return number*inner_factorial(number–1) return inner_factorial(number) # call the outer functionprint(factorial(4)) |
同样测试一下这段代码。使用这种设计模式的一个主要优势在于:在外部函数中对全部参数执行了检查,你可以在内部函数中跳过全部的检查过程。
关于这个递归更加详细的解释请看Problem Solving with Algorithms and Data Structures
2.贯彻DRY(Don’t Repeat Yourself )原则
也许你有一个巨型函数,在很多很多地方执行一大段的代码。比如,你可能写了一个函数用来处理文件,并且你希望它既可以接受一个打开文件对象或是一个文件名:
123456789 | def process(file_name): def do_stuff(file_process): for line in file_process: print(line) if isinstance(file_name, str): with open(file_name, \’r\’) as f: do_stuff(f) else: do_stuff(file_name) |
同样,通常会把
do_stuff()
作为一个顶层私有函数,但是如果你想要把它作为一个内层函数隐藏起来,你也可以这样做。
来个实际的例子怎么样?
让我们假设你想知道纽约市全部WiFi热点的数量。而且确实有提供这些信息的原始数据: 数据。
访问这个网站并下载CSV.
span>is not defined
现在,把inner_increment
的调用注释掉,再把对外部函数调用的注释取消,