1. Python高阶函数深度解析:从入门到实战
在Python编程中,高阶函数(Higher-order function)是函数式编程范式的核心概念之一。简单来说,高阶函数就是能够接收其他函数作为参数,或者将函数作为返回值的函数。这种特性让Python具备了强大的抽象能力和灵活性,也是许多高级编程技巧的基础。
我第一次真正理解高阶函数的威力是在重构一个数据处理脚本时。原本需要写几十行重复代码的逻辑,通过合理使用高阶函数,最终缩减到了不到10行,而且可读性和可维护性都大大提升。从那以后,高阶函数就成了我Python工具箱中的常备武器。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 高阶函数核心概念与原理
2.1 什么是高阶函数
在Python中,函数是一等公民(first-class citizen),这意味着函数可以像其他数据类型一样被传递和使用。高阶函数正是利用了这一特性,主要表现为两种形式:
- 接收函数作为参数
- 返回函数作为结果
这种设计模式在Python标准库中随处可见,比如最常用的map()、filter()和sorted()函数都是典型的高阶函数。
2.2 Python中的函数对象
理解高阶函数的前提是理解Python中的函数对象。在Python中,函数名实际上是一个指向函数对象的引用变量:
python复制def greet(name):
return f"Hello, {name}!"
print(greet) # <function greet at 0x...>
print(type(greet)) # <class 'function'>
我们可以将函数赋值给其他变量,甚至作为参数传递:
python复制my_func = greet
print(my_func("World")) # Hello, World!
3. Python内置高阶函数详解
3.1 map()函数实战
map()函数可能是最广为人知的高阶函数,它接收一个函数和一个可迭代对象,将函数应用于可迭代对象的每个元素:
python复制numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # [1, 4, 9, 16, 25]
在实际项目中,我经常用map()来处理数据转换。比如从数据库查询结果中提取特定字段:
python复制user_records = [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]
user_names = list(map(lambda user: user['name'], user_records))
注意:在Python 3中,map()返回的是一个迭代器(iterator),而不是列表。如果需要列表,记得用list()转换。
3.2 filter()函数应用
filter()函数用于过滤序列,保留使函数返回True的元素:
python复制def is_even(n):
return n % 2 == 0
numbers = [1, 2, 3, 4, 5, 6]
evens = list(filter(is_even, numbers))
print(evens) # [2, 4, 6]
在数据处理中,filter()非常有用。比如筛选出日志中的错误信息:
python复制log_entries = [
{'level': 'INFO', 'message': 'System started'},
{'level': 'ERROR', 'message': 'Disk full'},
{'level': 'DEBUG', 'message': 'Initializing cache'}
]
errors = list(filter(lambda entry: entry['level'] == 'ERROR', log_entries))
3.3 sorted()的高级用法
sorted()函数的高阶特性体现在它的key参数上,可以接收一个函数来自定义排序规则:
python复制students = [
{'name': 'Alice', 'grade': 89},
{'name': 'Bob', 'grade': 72},
{'name': 'Charlie', 'grade': 93}
]
# 按成绩降序排序
sorted_students = sorted(students, key=lambda s: s['grade'], reverse=True)
我曾经在一个项目中需要按文件名的数字部分排序,key参数就派上了大用场:
python复制files = ['file1.txt', 'file10.txt', 'file2.txt', 'file20.txt']
def extract_number(filename):
return int(''.join(filter(str.isdigit, filename)))
sorted_files = sorted(files, key=extract_number)
4. 自定义高阶函数开发
4.1 函数作为参数
创建接收函数作为参数的函数是Python高阶编程的基础。比如实现一个简单的计时器装饰器:
python复制import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} executed in {end - start:.4f} seconds")
return result
return wrapper
@timer
def long_running_operation():
time.sleep(2)
long_running_operation()
4.2 函数作为返回值
高阶函数也可以返回函数,这在创建工厂函数时特别有用。比如创建一个乘法器工厂:
python复制def multiplier(factor):
def multiply(number):
return number * factor
return multiply
double = multiplier(2)
triple = multiplier(3)
print(double(5)) # 10
print(triple(5)) # 15
在实际项目中,我曾经用这种模式创建了一个数据验证器工厂:
python复制def validator_factory(min_value, max_value):
def validate(value):
if not min_value <= value <= max_value:
raise ValueError(f"Value must be between {min_value} and {max_value}")
return True
return validate
validate_age = validator_factory(0, 120)
validate_percentage = validator_factory(0, 100)
5. functools模块中的高阶工具
5.1 partial函数应用
functools.partial可以固定函数的部分参数,创建新的函数:
python复制from functools import partial
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(square(5)) # 25
print(cube(5)) # 125
在GUI编程中,partial特别有用,可以预先绑定回调函数的部分参数:
python复制import tkinter as tk
from functools import partial
root = tk.Tk()
def on_click(button_name):
print(f"{button_name} was clicked")
button1 = tk.Button(root, text="Button 1", command=partial(on_click, "Button 1"))
button2 = tk.Button(root, text="Button 2", command=partial(on_click, "Button 2"))
5.2 reduce函数深度解析
虽然Python 3中将reduce移到了functools模块,但它仍然是一个强大的高阶函数:
python复制from functools import reduce
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product) # 120
我曾经用reduce实现过一个优雅的路径拼接函数:
python复制def join_path(*parts):
return reduce(
lambda path, part: f"{path.rstrip('/')}/{part.lstrip('/')}",
parts,
""
)
print(join_path("a", "b", "c")) # a/b/c
6. 高阶函数在实际项目中的应用
6.1 数据处理管道
高阶函数特别适合构建数据处理管道。比如一个简单的ETL流程:
python复制def extract(data):
return data
def transform(func):
def wrapper(data):
return func(data)
return wrapper
def load(data):
print(f"Loading: {data}")
@transform(lambda x: x * 2)
def process(data):
return load(extract(data))
process(5) # Loading: 10
6.2 回调机制
高阶函数是实现回调机制的理想选择。比如一个简单的事件系统:
python复制class EventSystem:
def __init__(self):
self.handlers = []
def register(self, handler):
self.handlers.append(handler)
def trigger(self, event):
for handler in self.handlers:
handler(event)
def log_event(event):
print(f"Event logged: {event}")
system = EventSystem()
system.register(log_event)
system.trigger("System started")
6.3 策略模式实现
高阶函数可以简化策略模式的实现:
python复制def strategy_add(a, b):
return a + b
def strategy_multiply(a, b):
return a * b
def execute_strategy(strategy, a, b):
return strategy(a, b)
print(execute_strategy(strategy_add, 3, 5)) # 8
print(execute_strategy(strategy_multiply, 3, 5)) # 15
7. 高阶函数性能考量与优化
7.1 性能对比
虽然高阶函数提供了代码的简洁性,但有时会带来性能开销。下面是一个简单的性能对比:
python复制import timeit
# 使用map
def with_map():
return list(map(lambda x: x * 2, range(1000)))
# 使用列表推导式
def with_comprehension():
return [x * 2 for x in range(1000)]
print("map:", timeit.timeit(with_map, number=10000))
print("列表推导式:", timeit.timeit(with_comprehension, number=10000))
在我的测试中,列表推导式通常比map+lambda快20-30%。但在使用内置函数时,map可能更快:
python复制# 使用map和str函数
def with_map_str():
return list(map(str, range(1000)))
# 使用列表推导式和str函数
def with_comprehension_str():
return [str(x) for x in range(1000)]
print("map with str:", timeit.timeit(with_map_str, number=10000))
print("列表推导式 with str:", timeit.timeit(with_comprehension_str, number=10000))
7.2 记忆化优化
对于计算密集型的高阶函数,可以使用记忆化(memoization)来优化:
python复制from functools import lru_cache
def expensive_computation(x):
print(f"Computing for {x}...")
return x * x
@lru_cache(maxsize=128)
def memoized_computation(x):
return expensive_computation(x)
print(memoized_computation(5)) # 计算
print(memoized_computation(5)) # 从缓存读取
8. 高阶函数常见问题与解决方案
8.1 变量作用域问题
在使用高阶函数时,变量作用域常常会带来困惑:
python复制def create_multipliers():
return [lambda x: i * x for i in range(5)]
for multiplier in create_multipliers():
print(multiplier(2)) # 全部输出8,不是预期的0,2,4,6,8
解决方案是使用默认参数捕获当前值:
python复制def create_multipliers_correct():
return [lambda x, i=i: i * x for i in range(5)]
8.2 调试困难
高阶函数可能导致调用栈难以追踪。一个实用的调试技巧是使用functools.wraps:
python复制from functools import wraps
def debug(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args}, {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result}")
return result
return wrapper
@debug
def add(a, b):
return a + b
8.3 过度抽象问题
虽然高阶函数很强大,但过度使用会导致代码难以理解。我的经验法则是:
- 当相同模式出现三次以上时,考虑使用高阶函数抽象
- 保持高阶函数的职责单一
- 为高阶函数编写详细的文档字符串
9. 高阶函数与其他Python特性的结合
9.1 与装饰器的结合
装饰器本身就是高阶函数的应用,我们可以创建更强大的装饰器:
python复制def retry(max_attempts=3, delay=1):
import time
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
attempts = 0
while attempts < max_attempts:
try:
return func(*args, **kwargs)
except Exception as e:
attempts += 1
if attempts == max_attempts:
raise
time.sleep(delay)
return wrapper
return decorator
@retry(max_attempts=5, delay=2)
def unreliable_api_call():
import random
if random.random() < 0.7:
raise ValueError("API failed")
return "Success"
9.2 与生成器的结合
高阶函数可以与生成器结合创建强大的数据处理管道:
python复制def pipeline(iterable, *funcs):
for func in funcs:
iterable = map(func, iterable)
return iterable
data = range(10)
result = pipeline(
data,
lambda x: x * 2,
lambda x: x + 1,
lambda x: x ** 2
)
print(list(result)) # [1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
9.3 与类的结合
高阶函数可以与类方法结合,实现更灵活的接口:
python复制class DataProcessor:
def __init__(self, data):
self.data = data
def apply(self, *funcs):
for func in funcs:
self.data = list(map(func, self.data))
return self
def filter(self, predicate):
self.data = list(filter(predicate, self.data))
return self
processor = DataProcessor(range(10))
result = processor.apply(
lambda x: x * 2,
lambda x: x + 1
).filter(
lambda x: x % 3 == 0
).data
print(result) # [3, 9, 15]
10. 高阶函数的最佳实践
10.1 命名约定
对于接收函数参数的参数,我习惯使用以下命名约定:
func或f用于主要的函数参数predicate用于返回布尔值的函数key用于提取比较键的函数callback用于回调函数
10.2 文档字符串
高阶函数的文档字符串应该特别详细:
python复制def apply_operation(data, operation, validator=None):
"""
Apply an operation to data with optional validation.
Args:
data: Input data to process
operation: Callable that processes the data
validator: Optional callable that validates the data before operation.
Should raise ValueError if validation fails.
Returns:
Result of operation applied to data
Raises:
ValueError: If validator fails
TypeError: If operation is not callable
"""
if not callable(operation):
raise TypeError("operation must be callable")
if validator is not None:
validator(data)
return operation(data)
10.3 测试策略
高阶函数的测试应该覆盖各种边界情况:
python复制import unittest
class TestApplyOperation(unittest.TestCase):
def test_basic_operation(self):
result = apply_operation(5, lambda x: x * 2)
self.assertEqual(result, 10)
def test_with_validator(self):
def validate_positive(x):
if x <= 0:
raise ValueError("Must be positive")
result = apply_operation(5, lambda x: x * 2, validate_positive)
self.assertEqual(result, 10)
with self.assertRaises(ValueError):
apply_operation(-1, lambda x: x * 2, validate_positive)
def test_non_callable_operation(self):
with self.assertRaises(TypeError):
apply_operation(5, "not a function")
11. 高阶函数在流行框架中的应用
11.1 Django中的高阶函数
Django的视图装饰器是典型的高阶函数应用:
python复制from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
@login_required
def protected_view(request):
return HttpResponse("This is a protected view")
11.2 Flask的路由系统
Flask的路由系统也大量使用高阶函数:
python复制from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "Welcome to the homepage!"
11.3 Pandas的apply方法
Pandas库中的apply方法是高阶函数在数据分析中的典型应用:
python复制import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
result = df.apply(lambda row: row['A'] + row['B'], axis=1)
print(result)
12. 高阶函数与并发编程
12.1 多线程中的高阶函数
threading模块的Thread类接收target函数:
python复制import threading
def worker(num):
print(f"Worker {num} is running")
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()
12.2 多进程中的高阶函数
multiprocessing模块同样使用高阶函数:
python复制from multiprocessing import Pool
def square(x):
return x * x
with Pool(4) as p:
results = p.map(square, range(10))
print(results)
12.3 异步编程中的应用
asyncio也大量使用高阶函数:
python复制import asyncio
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
await asyncio.gather(
say_after(1, 'hello'),
say_after(2, 'world')
)
asyncio.run(main())
13. 高阶函数的设计模式
13.1 装饰器模式
装饰器是Python中最常见的高阶函数设计模式:
python复制def bold(func):
@wraps(func)
def wrapper(*args, **kwargs):
return f"<b>{func(*args, **kwargs)}</b>"
return wrapper
@bold
def greet(name):
return f"Hello, {name}!"
print(greet("Alice")) # <b>Hello, Alice!</b>
13.2 策略模式
高阶函数可以简化策略模式的实现:
python复制def strategy_add(a, b):
return a + b
def strategy_multiply(a, b):
return a * b
def execute(strategy, a, b):
return strategy(a, b)
print(execute(strategy_add, 3, 5)) # 8
print(execute(strategy_multiply, 3, 5)) # 15
13.3 模板方法模式
高阶函数可以实现模板方法模式:
python复制def template_method(core_operation):
def wrapper():
print("Pre-processing")
result = core_operation()
print("Post-processing")
return result
return wrapper
@template_method
def business_logic():
print("Core business logic")
return "Result"
business_logic()
14. 高阶函数的函数式编程技巧
14.1 函数组合
将多个函数组合成一个新函数:
python复制def compose(*funcs):
def composed(arg):
for f in reversed(funcs):
arg = f(arg)
return arg
return composed
add_one = lambda x: x + 1
square = lambda x: x * x
composed_func = compose(add_one, square)
print(composed_func(3)) # (3^2) + 1 = 10
14.2 柯里化
将多参数函数转换为一系列单参数函数:
python复制def curry(func):
@wraps(func)
def curried(*args, **kwargs):
if len(args) + len(kwargs) >= func.__code__.co_argcount:
return func(*args, **kwargs)
return lambda *more_args, **more_kwargs: curried(
*(args + more_args),
**{**kwargs, **more_kwargs}
)
return curried
@curry
def add_three_numbers(a, b, c):
return a + b + c
print(add_three_numbers(1)(2)(3)) # 6
14.3 惰性求值
使用高阶函数实现惰性求值:
python复制def lazy_eval(func):
def wrapper():
return func()
return wrapper
def expensive_computation():
print("Computing...")
return 42
lazy_value = lazy_eval(expensive_computation)
print("Value not computed yet")
print(lazy_value()) # Now it computes
15. 高阶函数在算法中的应用
15.1 排序算法
高阶函数可以抽象排序算法的比较逻辑:
python复制def bubble_sort(arr, compare):
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if compare(arr[j], arr[j+1]) > 0:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
numbers = [5, 3, 8, 6, 2]
sorted_numbers = bubble_sort(numbers, lambda a, b: a - b)
print(sorted_numbers) # [2, 3, 5, 6, 8]
15.2 搜索算法
高阶函数可以自定义搜索条件:
python复制def linear_search(arr, predicate):
for i, item in enumerate(arr):
if predicate(item):
return i
return -1
data = [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]
index = linear_search(data, lambda x: x['name'] == 'Bob')
print(index) # 1
15.3 图算法
高阶函数可以抽象图遍历的行为:
python复制def dfs(graph, start, visit_func):
visited = set()
stack = [start]
while stack:
vertex = stack.pop()
if vertex not in visited:
visit_func(vertex)
visited.add(vertex)
stack.extend(reversed(graph[vertex]))
return visited
graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': []
}
dfs(graph, 'A', print) # Prints A, B, D, E, F, C
16. 高阶函数与元编程
16.1 动态函数生成
高阶函数可以用于运行时生成函数:
python复制def create_arithmetic_function(operator):
if operator == '+':
return lambda a, b: a + b
elif operator == '-':
return lambda a, b: a - b
elif operator == '*':
return lambda a, b: a * b
elif operator == '/':
return lambda a, b: a / b
else:
raise ValueError("Unknown operator")
add = create_arithmetic_function('+')
print(add(3, 5)) # 8
16.2 函数注册表
高阶函数可以实现插件系统:
python复制class FunctionRegistry:
def __init__(self):
self._functions = {}
def register(self, name):
def decorator(func):
self._functions[name] = func
return func
return decorator
def get(self, name):
return self._functions.get(name)
registry = FunctionRegistry()
@registry.register('greet')
def greet(name):
return f"Hello, {name}!"
print(registry.get('greet')('Alice')) # Hello, Alice!
16.3 函数元数据操作
高阶函数可以操作函数的元数据:
python复制def add_metadata(**kwargs):
def decorator(func):
for key, value in kwargs.items():
setattr(func, key, value)
return func
return decorator
@add_metadata(author='Alice', created='2023-01-01')
def some_function():
pass
print(some_function.author) # Alice
17. 高阶函数与测试
17.1 参数化测试
高阶函数可以实现参数化测试:
python复制import unittest
def parameterized_test(params):
def decorator(test_func):
def wrapper(self):
for param in params:
with self.subTest(**param):
test_func(self, **param)
return wrapper
return decorator
class TestMath(unittest.TestCase):
@parameterized_test([
{'a': 1, 'b': 2, 'expected': 3},
{'a': 5, 'b': -3, 'expected': 2}
])
def test_add(self, a, b, expected):
self.assertEqual(a + b, expected)
17.2 测试夹具
高阶函数可以创建灵活的测试夹具:
python复制def with_temp_file(content):
def decorator(test_func):
@wraps(test_func)
def wrapper(*args, **kwargs):
import tempfile
with tempfile.NamedTemporaryFile(mode='w+') as f:
f.write(content)
f.flush()
return test_func(*args, file_path=f.name, **kwargs)
return wrapper
return decorator
@with_temp_file("test content")
def test_file_operations(file_path):
with open(file_path) as f:
content = f.read()
assert content == "test content"
17.3 Mock和Patch
高阶函数在测试mock中也很常见:
python复制from unittest.mock import patch
def test_with_mock():
with patch('builtins.print') as mock_print:
print("Hello")
mock_print.assert_called_with("Hello")
18. 高阶函数与设计原则
18.1 开闭原则
高阶函数帮助实现开闭原则 - 对扩展开放,对修改关闭:
python复制def process_data(data, processors):
for processor in processors:
data = processor(data)
return data
def double(x):
return x * 2
def increment(x):
return x + 1
# 可以轻松添加新的处理器而不修改process_data函数
result = process_data(5, [double, increment])
print(result) # 11
18.2 单一职责原则
高阶函数帮助保持函数单一职责:
python复制# 不好的做法:函数做太多事情
def process_and_save(data):
# 处理数据
data = [x * 2 for x in data]
# 保存数据
with open('output.txt', 'w') as f:
f.write(str(data))
# 好的做法:分离关注点
def process(data, processor):
return processor(data)
def save(data, saver):
saver(data)
def double_values(data):
return [x * 2 for x in data]
def save_to_file(data):
with open('output.txt', 'w') as f:
f.write(str(data))
data = [1, 2, 3]
processed = process(data, double_values)
save(processed, save_to_file)
18.3 依赖倒置原则
高阶函数实现依赖倒置 - 依赖抽象而非具体实现:
python复制def data_pipeline(data, *, extractor, transformer, loader):
raw_data = extractor(data)
transformed = transformer(raw_data)
return loader(transformed)
# 可以注入不同的实现
result = data_pipeline(
"some input",
extractor=lambda x: x.upper(),
transformer=lambda x: x + "!",
loader=lambda x: print(f"Result: {x}")
)
19. 高阶函数与性能优化
19.1 函数缓存
高阶函数可以实现智能缓存:
python复制from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_call(x):
print(f"Computing for {x}...")
return x * x
print(expensive_call(5)) # 计算
print(expensive_call(5)) # 从缓存读取
19.2 惰性计算
高阶函数可以实现惰性计算模式:
python复制def lazy(f):
class Lazy:
def __init__(self, func):
self.func = func
self.computed = False
self.value = None
def __call__(self):
if not self.computed:
self.value = self.func()
self.computed = True
return self.value
return Lazy(f)
@lazy
def expensive_computation():
print("Computing...")
return 42
result = expensive_computation()
print("Not computed yet")
print(result()) # Now it computes
19.3 批量处理
高阶函数可以优化批量操作:
python复制def batch_processor(batch_size):
def decorator(func):
def wrapper(items):
results = []
for i in range(0, len(items), batch_size):
batch = items[i:i+batch_size]
results.extend(func(batch))
return results
return wrapper
return decorator
@batch_processor(batch_size=3)
def process_items(items):
print(f"Processing batch: {items}")
return [item * 2 for item in items]
print(process_items([1, 2, 3, 4, 5, 6, 7]))
20. 高阶函数与错误处理
20.1 重试机制
高阶函数可以实现优雅的重试逻辑:
python复制import time
from functools import wraps
def retry(max_attempts=3, delay=1, exceptions=(Exception,)):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
attempts = 0
while attempts < max_attempts:
try:
return func(*args, **kwargs)
except exceptions as e:
attempts += 1
if attempts == max_attempts:
raise
time.sleep(delay)
return wrapper
return decorator
@retry(max_attempts=5, delay=2, exceptions=(ValueError,))
def unreliable_call():
import random
if random.random() < 0.7:
raise ValueError("Temporary failure")
return "Success"
20.2 错误转换
高阶函数可以统一错误处理:
python复制def error_translator(from_exception, to_exception, message=None):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except from_exception as e:
raise to_exception(message or str(e)) from e
return wrapper
return decorator
@error_translator(ValueError, RuntimeError, "Invalid input")
def parse_number(s):
return int(s)
try:
parse_number("abc")
except RuntimeError as e:
print(f"Caught: {e}")
20.3 防御性编程
高阶函数可以添加防御性检查:
python复制def validate_input(*validators):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for i, arg in enumerate(args):
if i < len(validators) and validators[i] is not None:
validators[i](arg)
for param, validator in validators[len(args):].items():
if param in kwargs and validator is not None:
validator(kwargs[param])
return func(*args, **kwargs)
return wrapper
return decorator
def is_positive(x):
if x <= 0:
raise ValueError("Must be positive")
@validate_input(is_positive, is_positive)
def divide(a, b):
return a / b
try:
divide(5, -1)
except ValueError as e:
print(f"Validation failed: {e}")
