在Python中函数是一等公民(first-class citizen),函数也是对象。Python 中的函数具有一等公民的地位,这使得 Python 可以很方便地编写高阶函数、闭包和装饰器等特性,并且在函数式编程中也有着广泛的应用。
在编程语言中,一个对象如果满足以下三个条件之一,就可以被称为“一等公民”(first-class citizen):
可以存储在变量中。
可以作为参数传递给函数。
可以作为函数的返回值。
Python 中的函数满足这些条件,因此被称为一等公民。
函数可以存储在变量中
举例说明,下面的代码定义了一个函数 add(x, y),实现两个数相加,然后将该函数赋值给变量 func:
def add(x, y):
return x + y
func = add #func 变量保存了函数 add 的引用
result = func(1, 2) #可以像调用普通函数一样来调用它func
print(result) # 输出:3
函数作为参数传递给函数
例子源码如下:
def add(x, y):
return x + y
def subtract(x, y):
return x - y
def apply(func, x, y):
return func(x, y)
result1 = apply(add, 3, 4) # 调用 add 函数并将其作为参数传递给 apply 函数
result2 = apply(subtract, 3, 4) # 调用 subtract 函数并将其作为参数传递给 apply 函数
print(result1) # 输出:7
print(result2) # 输出:-1
上面的例子中,我们定义了三个函数 add()、subtract() 和 apply()。其中,apply() 函数接受三个参数:一个函数 func 和两个数值 x 和 y。它会调用 func(x, y) 并返回结果。接着,我们分别调用了 apply() 函数两次,第一次将 add() 函数作为参数传递进去,第二次将 subtract() 函数作为参数传递进去。这样就可以通过函数参数来指定具体的计算操作,并得到不同的结果。
函数作为参数传递给函数是 Python 编程语言中常见的编程技巧之一,这种方式可以让函数更加通用和灵活。
函数可以作为函数的返回值
例子源码如下:
def calculator(operation):
def add(x, y):
return x + y
def subtract(x, y):
return x - y
if operation == 'add':
return add
elif operation == 'subtract':
return subtract
else:
return None
# 返回 add 函数并将其赋值给 calc_add 变量
calc_add = calculator('add')
# 调用 calc_add 函数计算结果
result = calc_add(3, 4)
print(result) # 输出:7
上面的例子中,我们定义了一个 calculator() 函数,它接受一个字符串参数 operation,并根据参数返回不同的函数。如果 operation 参数为 'add',则返回加法函数 add();如果 operation 参数为 'subtract',则返回减法函数 subtract();否则返回 None。
接着,我们调用 calculator() 函数并将其返回值赋值给变量 calc_add。由于我们传递了 'add' 参数,因此 calc_add 变量保存了加法函数 add() 的引用。最后,我们使用 calc_add() 函数计算 3 和 4 的和,并得到结果 7。
函数作为返回值的一种用法。通过返回不同的函数,我们可以让同一个函数实现不同的功能,从而提高代码的复用性和灵活性。
函数可以接受一个函数作为参数并返回一个新的函数作为结果
例子源码如下:
def add_suffix(func):
def wrapper(text):
return func(text) + "!"
return wrapper
def greet(name):
return "Hello, " + name
greet_with_exclamation = add_suffix(greet)
print(greet_with_exclamation("Alice")) # Hello, Alice!
在这个例子中,我们定义了两个函数:
add_suffix 函数接受一个函数作为参数(这里是 func),并返回一个新的函数(内部定义的 wrapper 函数)作为结果。
greet 函数用于招呼某个人,并返回相应的问候语字符串。
我们调用 add_suffix 并将 greet 函数作为参数传递给它。add_suffix 函数内部定义了一个新的函数 wrapper,该函数在原始函数(这里是 greet 函数)的基础上添加了一个感叹号后缀。最后,add_suffix 函数返回了这个新的函数 wrapper。
当调用 greet_with_exclamation 时,实际上是调用了内部的 wrapper 函数,并得到了修改后的问候语结果。
这个例子展示了高阶函数的概念,其中一个函数接受另一个函数作为参数,并返回一个新的函数。这种模式在许多情况下都非常有用,使得代码更加灵活和可复用。但是,使用这种方式会使代码变得冗长和复杂,特别是当有多个函数需要修饰时。
修改上面这个例子——使用用装饰器,代码更简洁和易读:
def add_suffix(func):
def wrapper(text):
return func(text) + "!"
return wrapper
@add_suffix
def greet(name):
return "Hello, " + name
print(greet("Alice")) # Hello, Alice!
这里我们定义了一个装饰器 add_suffix,它接受一个函数作为参数,并返回一个新的函数。通过在 greet 函数的定义之前添加 @add_suffix,我们将 greet 函数应用了装饰器。
装饰器的作用是在不修改原始函数定义的情况下,为其添加额外的功能或行为。在本例中,add_suffix 装饰器的作用是在原始的问候语输出后添加一个感叹号。
通过使用装饰器,我们可以避免显式地调用装饰器函数来生成新的函数,而是直接在函数定义时使用 @decorator_name 语法糖来应用装饰器。换句话说,装饰器语法糖简化了我们使用装饰器的步骤,不再需要手动调用装饰器函数和赋值操作。
通过使用装饰器,我们可以避免显式地调用装饰器函数来生成新的函数,而是直接在函数定义时使用 @decorator_name 语法糖来应用装饰器。“语法糖”(Syntactic Sugar)是指一种编程语言中的特殊语法,它可以让程序员用更加简洁、易读的方式来表达某些常见的编程模式或操作。尽管这些语法糖并不影响编程语言本身的功能和能力,但却可以显著地提高代码的可读性、可维护性和开发效率。
在 Python 中,装饰器就是一个典型的语法糖。使用装饰器语法,我们可以用更加简洁、直观的方式来定义函数,并为函数添加额外的功能,如:
@my_decorator
def my_function():
# 函数体
其中,@my_decorator 就是一个语法糖,它实际上等同于以下代码:
def my_function():
# 函数体
my_function = my_decorator(my_function)
关于装饰器更多情况,可以参见https://blog.csdn.net/cnds123/article/details/115588075