如何将电信套餐计费Python程序中的全局变量改为局部变量?
如何将电信套餐计费代码中的全局变量改为局部变量?
我正在开发一款基于通话记录计算电信套餐价格的程序,核心代码如下:
from math import ceil prev_date = None expen_minutes_used = 0 def calculate_call_cost(row): global prev_date, expen_minutes_used if prev_date is None or row['data of call'].date() != prev_date: prev_date = row['data of call'].date() expen_minutes_used = 0 expen_minutes = 0 if expen_minutes_used < 5: expen_minutes = min(5 - expen_minutes_used, ceil(row['Duration in second'] / 60)) expen_minutes_used += expen_minutes cheap_minutes = ceil(row['Duration in second'] / 60) - expen_minutes cost = cheap_minutes * 0.40 + expen_minutes * 3.95 return cost calls_data_sorted['Cost of tariff'] = calls_data_sorted.apply(calculate_call_cost, axis = 1) total_cost2 = calls_data_sorted['Cost of tariff'].sum() calls_data_sorted
请问是否有办法将代码中的全局变量修改为局部变量?
当然可以,有两种常用方案可以替代全局变量,将状态封装在局部作用域中:
方案一:使用闭包封装状态
通过外层函数创建局部状态变量,返回一个内层函数来处理每条通话记录,状态会被闭包保留,避免全局变量的副作用。
from math import ceil def create_cost_calculator(): # 状态变量被封装在闭包的局部作用域中 prev_date = None expen_minutes_used = 0 def calculate_call_cost(row): # 使用nonlocal关键字声明要修改外层函数的变量 nonlocal prev_date, expen_minutes_used if prev_date is None or row['data of call'].date() != prev_date: prev_date = row['data of call'].date() expen_minutes_used = 0 expen_minutes = 0 if expen_minutes_used < 5: expen_minutes = min(5 - expen_minutes_used, ceil(row['Duration in second'] / 60)) expen_minutes_used += expen_minutes cheap_minutes = ceil(row['Duration in second'] / 60) - expen_minutes cost = cheap_minutes * 0.40 + expen_minutes * 3.95 return cost return calculate_call_cost # 初始化计算器,获取绑定了状态的函数 calculate_call_cost = create_cost_calculator() calls_data_sorted['Cost of tariff'] = calls_data_sorted.apply(calculate_call_cost, axis=1) total_cost2 = calls_data_sorted['Cost of tariff'].sum()
方案二:使用类封装状态
将状态变量作为类的实例属性,计算逻辑作为实例方法,这种方式更适合后续需要扩展计费规则或添加更多状态的场景。
from math import ceil class CallCostCalculator: def __init__(self): # 状态变量作为实例属性 self.prev_date = None self.expen_minutes_used = 0 def calculate_call_cost(self, row): if self.prev_date is None or row['data of call'].date() != self.prev_date: self.prev_date = row['data of call'].date() self.expen_minutes_used = 0 expen_minutes = 0 if self.expen_minutes_used < 5: expen_minutes = min(5 - self.expen_minutes_used, ceil(row['Duration in second'] / 60)) self.expen_minutes_used += expen_minutes cheap_minutes = ceil(row['Duration in second'] / 60) - expen_minutes cost = cheap_minutes * 0.40 + expen_minutes * 3.95 return cost # 创建计算器实例 calculator = CallCostCalculator() calls_data_sorted['Cost of tariff'] = calls_data_sorted.apply(calculator.calculate_call_cost, axis=1) total_cost2 = calls_data_sorted['Cost of tariff'].sum()
两种方案都能有效避免全局变量的问题,闭包方案更简洁轻量,适合简单场景;类方案结构更清晰,扩展性更强。
内容的提问来源于stack exchange,提问作者lelelel
相关产品推荐
相关产品推荐

