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

Python跨函数修改变量报错:AttributeError: 'function' object has no attribute 'day'

问题描述

自学Python制作日期追踪器,包含多个子项目。Date()函数可正常运行,但调用new_day()函数将日期加1(需切换月份/年份时)出现错误:

AttributeError: 'function' object has no attribute 'day'

已知函数内是独立局部变量,不想频繁用全局变量,想实现函数调用修改日期状态,后续要做日期加1或加7的按钮,求指导。相关代码如下:

# making a basic calendar
#list of months and their days
month_day = [[1,'January',31],[2,'February',28],
[3,'March',31],[4,'April',30],
[5,'May',31],[6,'June',30],
[7,'July',31],[8,'August',31],
[9,'September',30],[10,'October',31],
[11,'November',30],[12,'December',31]]
#checksum for new year
def isleapyear(year):
    if year%4 == 0:
        if year%100 == 0:
            if year%400 == 0:
                month_day[1][2] = 29
            else:
                month_day[1][2] = 28
        else :
            month_day[1][2] = 29
    else:
        month_day[1][2] = 28
#editable date (supposed to be
def Date():
    year = 1
    day = 31
    month = 1
    isleapyear(year)
    date = [day, month_day[month-1][1], year]
    return date
#function to increase day counter by 1
def new_day():
    #checksum for month or year rollover
    if Date.day == month_day[Date.month-1][2]:
        Date.day = 1
        if Date.month == 12:
            Date.month = 1
            Date.year = Date.year + 1
        else:
            Date.month = month + 1
    else:
        Date.day = Date.day + 1

new_day()
print (Date())
解决方案

核心问题是你试图直接访问函数的属性(Date.day),但函数本身没有这些属性——Date()里的year/month/day都是局部变量,函数执行完毕就会被销毁,无法被其他函数修改。

不用全局变量的话,最合理的方式是用类封装日期状态,把日期属性和操作方法整合在一起:

# 定义月份信息,字典格式更直观
MONTH_INFO = {
    1: ('January', 31),
    2: ('February', 28),
    3: ('March', 31),
    4: ('April', 30),
    5: ('May', 31),
    6: ('June', 30),
    7: ('July', 31),
    8: ('August', 31),
    9: ('September', 30),
    10: ('October', 31),
    11: ('November', 30),
    12: ('December', 31)
}

class DateTracker:
    def __init__(self, year=1, month=1, day=1):
        self.year = year
        self.month = month
        self.day = day
        self.update_leap_year()  # 初始化时检查闰年

    def update_leap_year(self):
        # 针对当前实例的年份更新二月天数,不修改全局变量
        if self.year % 4 == 0:
            if self.year % 100 == 0:
                MONTH_INFO[2] = ('February', 29) if self.year % 400 == 0 else ('February', 28)
            else:
                MONTH_INFO[2] = ('February', 29)
        else:
            MONTH_INFO[2] = ('February', 28)

    def get_current_date(self):
        # 返回格式化的日期信息
        month_name = MONTH_INFO[self.month][0]
        return [self.day, month_name, self.year]

    def add_days(self, days_to_add):
        # 通用加天数方法,支持加1天、7天等任意天数
        for _ in range(days_to_add):
            self.update_leap_year()
            max_day = MONTH_INFO[self.month][1]
            if self.day == max_day:
                self.day = 1
                if self.month == 12:
                    self.month = 1
                    self.year += 1
                else:
                    self.month += 1
            else:
                self.day += 1

# 使用示例
tracker = DateTracker(year=1, month=1, day=31)  # 初始化日期
tracker.add_days(1)  # 加1天
print(tracker.get_current_date())  # 输出 [1, 'February', 1]

tracker.add_days(7)  # 再加7天
print(tracker.get_current_date())  # 输出 [8, 'February', 1]

关键改进说明:

  • 用DateTracker类封装日期状态(year/month/day),这些属性属于类实例,可被类内方法直接修改
  • add_days是通用方法,后续做按钮时直接调用add_days(1)或add_days(7)即可实现对应功能
  • 闰年检查方法绑定到实例,只针对当前年份修改二月天数,避免全局变量的副作用
  • 用字典替代原列表存储月份信息,可读性和访问效率更高

内容的提问来源于stack exchange,提问作者Rulian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:56:34