You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将电信套餐计费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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:27:40