内层函数——它们的优点是什么?

让我们看一下写内层函数的三个常见原因。

记住:在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 &gt;= 0:        raise ValueError(\”Sorry. \’number\’ must be zero or positive.\”)     def inner_factorial(number):        if number &lt;= 1:            return 1        return number*inner_factorial(number1)    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 &gt;= 0:        raise ValueError(\”Sorry. \’number\’ must be zero or positive.\”)     def inner_factorial(number):        if number &lt;= 1:            return 1        return number*inner_factorial(number1)    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的调用注释掉,再把对外部函数调用的注释取消,