跳到主要内容Python 内置函数:enumerate()、eval()和 exec() | 极客日志Python
Python 内置函数:enumerate()、eval()和 exec()
系统介绍了 Python 内置函数 enumerate()、eval() 和 exec() 的基础用法与实际应用。enumerate() 用于遍历获取索引与值;eval() 执行字符串表达式并返回值;exec() 执行代码块语句。文章提供了数据处理、配置解析、动态模块加载等场景的代码示例,并重点强调了 eval() 和 exec() 的安全风险,建议使用受限命名空间、白名单函数或 ast.literal_eval 等替代方案以确保安全。
数字游民12K 浏览 一、enumerate():迭代计数的"索引器"
1.1 基础用法:为迭代对象添加计数
enumerate() 函数用于将一个可迭代对象(如列表、元组等)组合为一个索引序列,同时返回索引和对应的元素值。默认计数从 0 开始,但可通过 start 参数自定义起始值。
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
print(list(enumerate(seasons)))
print(list(enumerate(seasons, start=1)))
def enumerate(iterable, start=0):
n = start
for elem in iterable:
yield n, elem
n += 1
1.2 实际应用:遍历时获取索引和值
class DataProcessor:
@staticmethod
def process_with_index(data_list):
"""带索引处理数据"""
processed = []
for index, value in enumerate(data_list, start=1):
processed.append(f"{index}: {value.upper()}")
return processed
@staticmethod
def find_element_positions(data, target):
"""查找元素所有出现的位置"""
positions = [index for index, value in enumerate(data) if value == target]
return positions
@staticmethod
def batch_processing(items, batch_size=3):
"""分批次处理数据并标记批次号"""
batches = []
for batch_num, i in enumerate(range(0, len(items), batch_size)):
batch = items[i:i + batch_size]
batches.append((batch_num + 1, batch))
return batches
processor = DataProcessor()
data = ['apple', 'banana', 'cherry']
result = processor.process_with_index(data)
print(f"带索引处理:{result}")
positions = processor.find_element_positions(['a', 'b', 'a', 'c'], 'a')
print(f"元素位置:{positions}")
items = list(range(10))
batches = processor.batch_processing(items, batch_size=3)
print(f"分批次:{batches}")
二、eval():动态表达式求值的"计算器"
2.1 基础用法:执行字符串表达式
eval() 函数用于执行一个字符串表达式,并返回表达式的值。可以指定全局和局部命名空间来控制执行环境。
x = 1
result = eval('x + 1')
print(f"eval('x + 1') = {result}")
globals_dict = {'x': 10, 'y': 20}
locals_dict = {'z': 30}
result = eval('x + y + z', globals_dict, locals_dict)
print(f"自定义命名空间:{result}")
2.2 实际应用:配置解析和动态计算
class ExpressionEvaluator:
def __init__(self):
self.safe_globals = {'__builtins__': {}, 'abs': abs, 'max': max, 'min': min, 'sum': sum}
def safe_eval(self, expression, variables=None):
"""安全求值,限制可用函数"""
if variables:
env = self.safe_globals.copy()
env.update(variables)
else:
env = self.safe_globals
try:
return eval(expression, env)
except Exception as e:
return f"错误:{e}"
def calculate_from_config(self, config_str, values):
"""从配置字符串计算值"""
try:
return eval(config_str, {'values': values})
except:
return None
evaluator = ExpressionEvaluator()
print(f"安全计算:{evaluator.safe_eval('2 * 3 + 4')}")
print(f"带变量计算:{evaluator.safe_eval('a + b', {'a': 5, 'b': 3})}")
config = "sum(values) / len(values)"
result = evaluator.calculate_from_config(config, [1, 2, 3, 4, 5])
print(f"配置计算结果:{result}")
三、exec():动态代码执行的"解释器"
3.1 基础用法:执行 Python 代码块
exec() 函数用于动态执行 Python 代码(字符串或代码对象),适合执行语句而非表达式。返回值始终为 None。
exec('x = 10; y = 20; z = x + y')
print(f"执行后 z = {z}")
my_globals = {}
my_locals = {}
exec('''
def greet(name):
return f"Hello, {name}!"
result = greet("World")
''', my_globals, my_locals)
print(f"函数执行:{my_locals['result']}")
3.2 实际应用:动态模块加载和插件系统
class DynamicCodeManager:
def __init__(self):
self.environment = {'__builtins__': {}}
def execute_safely(self, code_string, allowed_globals=None):
"""安全执行代码,限制访问"""
env = self.environment.copy()
if allowed_globals:
env.update(allowed_globals)
try:
exec(code_string, env)
return env
except Exception as e:
print(f"执行错误:{e}")
return None
def create_dynamic_class(self, class_code):
"""动态创建类"""
env = {}
exec(class_code, env)
for obj in env.values():
if isinstance(obj, type) and obj.__module__ == '__main__':
return obj
return None
manager = DynamicCodeManager()
code = '''
def calculate_area(radius):
return 3.14159 * radius ** 2
area = calculate_area(5)
'''
result_env = manager.execute_safely(code)
if result_env:
print(f"动态函数结果:{result_env.get('area')}")
class_code = '''
class DynamicCalculator:
def add(self, a, b):
return a + b
def multiply(self, a, b):
return a * b
'''
dynamic_class = manager.create_dynamic_class(class_code)
if dynamic_class:
calc = dynamic_class()
print(f"动态类方法:{calc.add(2, 3)}")
四、高级技巧与最佳实践
4.1 安全使用 eval() 和 exec()
class SecureEvaluator:
def __init__(self):
self.allowed_functions = {'abs': abs, 'len': len, 'max': max, 'min': min, 'round': round, 'sum': sum}
self.safe_globals = {'__builtins__': None, **self.allowed_functions}
def ultra_safe_eval(self, expression, variables=None):
"""超安全求值,仅允许白名单函数"""
env = self.safe_globals.copy()
if variables:
env.update(variables)
try:
return eval(expression, env)
except Exception as e:
return f"安全错误:{e}"
def validate_code(self, code_string):
"""简单代码验证"""
forbidden = ['import', 'os.', 'sys.', '__', 'open(']
return not any(keyword in code_string for keyword in forbidden)
secure_eval = SecureEvaluator()
print(f"安全计算:{secure_eval.ultra_safe_eval('abs(-5)')}")
print(f"代码验证:{secure_eval.validate_code('import os')}")
4.2 组合使用枚举和求值
def analyze_data_structure(data):
"""综合分析数据结构"""
analysis = {}
if isinstance(data, (list, tuple)):
analysis['indexed_items'] = list(enumerate(data))
analysis['length'] = len(data)
safe_globals = {'data': data, 'len': len}
try:
analysis['size_info'] = eval('len(data)', safe_globals)
except:
analysis['size_info'] = '无法计算'
return analysis
sample_data = ['a', 'b', 'c']
result = analyze_data_structure(sample_data)
print(f"分析结果:{result}")
五、总结与实用建议
- enumerate() - 迭代计数的索引器
- eval() - 动态表达式求值的计算器
- exec() - 动态代码执行的解释器
enumerate(iterable, start=0) 返回 (索引,元素) 元组序列
eval(expression) 执行表达式并返回值,exec(code) 执行代码块返回 None
- 两者都支持全局和局部命名空间参数
- 绝对避免直接执行用户输入:eval() 和 exec() 可执行任意代码,存在安全风险
- 使用限制环境:通过自定义 globals 参数控制可访问的函数和变量
- 优先考虑替代方案:如 ast.literal_eval() 用于安全求值字面量
- 明确需求区别:表达式求值用 eval(),代码块执行用 exec()
- enumerate():遍历需要索引的场景(如日志记录、批量处理)
- eval():数学表达式计算、简单配置解析
- exec():插件系统、动态代码生成
- 深入学习 Python 的 ast 模块进行代码分析
- 研究命名空间和作用域的工作原理
- 了解代码对象(code object)和编译过程
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online