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

使用Google Sheets API后,跨Python文件调用变量遇AttributeError问题

解决Python模块间变量调用的AttributeError问题

问题背景

尝试通过Google Sheets API拉取表格数据,转换为逗号分隔字符串后传递给短信发送脚本,但调用存储字符串的变量时出现错误:AttributeError: module 'sheetsReader' has no attribute 'result_string'。首次使用Python多模块开发,不确定是否需要像Java那样定义类,或遗漏了关键步骤。

原代码展示

sheetsReader.py

import os
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]
value = []

global result_string
def main():
    
    credentials = None
    if os.path.exists("tocken.json"):
        credentials = Credentials.from_authorized_user_file("token.json", SCOPES)
    if not credentials or not credentials.valid:
        if credentials and credentials.expired and credentials.refresh_token:
            credentials.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
            credentials = flow.run_local_server(port=0)
        with open("token.json","w") as token:
            token.write(credentials.to_json())
    try:
        service = build("sheets", "v4", credentials=credentials)
        sheets = service.spreadsheets()
        
        result = sheets.values().get(spreadsheetId=SPREADSHEET_ID, range="Sheet1!A1:A9").execute()
        
        values = result.get("values", [])
        
        for row in values:
            value.append(row)
            
        result_string = ', '.join([inner_list[0] for inner_list in value])
    
    
    except HttpError as error:
        print(error)


if __name__ == "__main__":
    main()

短信发送脚本(示例命名为sms_sender.py)

from datetime import time, timedelta, datetime
import Alert
import time as tm
import sheetsReader

text = sheetsReader.result_string


def job():
    Alert.email_alert("todo","stop", "4807931338@vtext.com")
    
    
schedule.every().day("7:20").do(job)



while True:
    schedule.run_pending()
    tm.sleep(1)  

错误原因分析

  1. 全局变量声明错误:函数外部的global result_string写法无效,Python中需在函数内部声明global result_string才能修改全局作用域变量。原代码中result_string是main()函数的局部变量,无法被模块外部访问。
  2. 函数执行时机问题:main()函数仅在直接运行sheetsReader.py时(if __name__ == "__main__"分支)才会执行,当作为模块导入时,该分支代码不会运行,导致result_string从未被赋值。

解决方案

方案1:让函数返回结果(最简方式)

修改sheetsReader.py,让main()返回处理后的字符串:

import os
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]

def main():
    credentials = None
    # 修复拼写错误:tocken.json → token.json
    if os.path.exists("token.json"):
        credentials = Credentials.from_authorized_user_file("token.json", SCOPES)
    if not credentials or not credentials.valid:
        if credentials and credentials.expired and credentials.refresh_token:
            credentials.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
            credentials = flow.run_local_server(port=0)
        with open("token.json","w") as token:
            token.write(credentials.to_json())
    
    try:
        service = build("sheets", "v4", credentials=credentials)
        sheets = service.spreadsheets()
        
        # 替换SPREADSHEET_ID为实际表格ID
        result = sheets.values().get(spreadsheetId=SPREADSHEET_ID, range="Sheet1!A1:A9").execute()
        
        values = result.get("values", [])
        # 直接推导字符串,无需额外列表存储
        result_string = ', '.join([row[0] for row in values])
        return result_string
    
    except HttpError as error:
        print(error)
        return ""

if __name__ == "__main__":
    main()

修改短信发送脚本,调用main()获取结果:

from datetime import datetime
import Alert
import time as tm
import sheetsReader
import schedule  # 补充缺失的schedule导入

# 调用main函数获取字符串
text = sheetsReader.main()

def job():
    # 若需每日获取最新数据,建议在job内重新调用main()
    latest_text = sheetsReader.main()
    Alert.email_alert("todo", latest_text, "4807931338@vtext.com")

# 修复schedule语法错误:day("7:20") → day.at("7:20")
schedule.every().day.at("7:20").do(job)

while True:
    schedule.run_pending()
    tm.sleep(1)

方案2:使用类封装(类似Java的面向对象写法)

如果习惯Java的类结构,可以将逻辑封装为类:

修改sheetsReader.py

import os
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]

class SheetsReader:
    def __init__(self, spreadsheet_id):
        self.spreadsheet_id = spreadsheet_id
        self.credentials = self._get_credentials()
    
    def _get_credentials(self):
        credentials = None
        if os.path.exists("token.json"):
            credentials = Credentials.from_authorized_user_file("token.json", SCOPES)
        if not credentials or not credentials.valid:
            if credentials and credentials.expired and credentials.refresh_token:
                credentials.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
                credentials = flow.run_local_server(port=0)
            with open("token.json","w") as token:
                token.write(credentials.to_json())
        return credentials
    
    def get_result_string(self, range_str="Sheet1!A1:A9"):
        try:
            service = build("sheets", "v4", credentials=self.credentials)
            sheets = service.spreadsheets()
            result = sheets.values().get(spreadsheetId=self.spreadsheet_id, range=range_str).execute()
            values = result.get("values", [])
            return ', '.join([row[0] for row in values])
        except HttpError as error:
            print(error)
            return ""

if __name__ == "__main__":
    reader = SheetsReader(SPREADSHEET_ID)
    print(reader.get_result_string())

修改短信发送脚本

from datetime import datetime
import Alert
import time as tm
import sheetsReader
import schedule

# 初始化阅读器,传入实际表格ID
reader = sheetsReader.SheetsReader(SPREADSHEET_ID)

def job():
    latest_text = reader.get_result_string()
    Alert.email_alert("todo", latest_text, "4807931338@vtext.com")

schedule.every().day.at("7:20").do(job)

while True:
    schedule.run_pending()
    tm.sleep(1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:16:09