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

如何将函数内创建的pandas DataFrame转为全局可访问变量?

如何将函数内创建的Pandas DataFrame提取为全局可访问变量

嘿,作为Pandas和Python的初学者,我完全理解你想在函数外部拿到生成的DataFrame的需求!这里有几个不同的方案,从直接满足你需求的全局变量方法,到更符合Python最佳实践的实现方式,你可以根据自己的场景选择:

方案1:使用全局变量(直接满足需求)

你可以在全局作用域先声明df变量,然后在print_response函数里通过global关键字指定要使用全局变量,最后把生成的DataFrame赋值给它:

import pandas as pd
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build

# 全局作用域初始化df
df = None
KEY_FILE_LOCATION = "your-key-file.json"
SCOPES = ['https://www.googleapis.com/auth/analytics.readonly']
VIEW_ID = "your-view-id"

def initialize_analyticsreporting():
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        KEY_FILE_LOCATION, SCOPES)
    analytics = build('analyticsreporting', 'v4', credentials=credentials)
    return analytics

def get_report(analytics):
    return analytics.reports().batchGet(
        body={
            'reportRequests': [
                {
                    'viewId': VIEW_ID,
                    'pageSize': 100000,
                    'dateRanges': [{'startDate': '7daysAgo', 'endDate': 'yesterday'}],
                    'metrics': [{'expression': 'ga:sessions'}],
                    'dimensions': [{'name': 'ga:country'}, {'name': 'ga:hostname'}, {'name': 'ga:pagePathLevel1'}, {'name': 'ga:pagePathLevel2'}, {'name': 'ga:keyword'}, {'name': 'ga:adMatchedQuery'}, {'name': 'ga:operatingSystem'}, {'name': 'ga:hour'}, {'name': 'ga:exitPagePath'}]
                }
            ]
        }
    ).execute()

def print_response(response):
    global df  # 声明要使用全局变量df
    data_list = []  # 避免用list作为变量名,它是Python内置类型
    for report in response.get('reports', []):
        columnHeader = report.get('columnHeader', {})
        dimensionHeaders = columnHeader.get('dimensions', [])
        metricHeaders = columnHeader.get(
            'metricHeader', {}).get('metricHeaderEntries', [])
        rows = report.get('data', {}).get('rows', [])
        for row in rows:
            row_dict = {}  # 同样避免用dict作为变量名
            dimensions = row.get('dimensions', [])
            dateRangeValues = row.get('metrics', [])
            for header, dimension in zip(dimensionHeaders, dimensions):
                row_dict[header] = dimension
            for i, values in enumerate(dateRangeValues):
                for metric, value in zip(metricHeaders, values.get('values')):
                    if ',' in value or '.' in value:
                        row_dict[metric.get('name')] = float(value)
                    else:
                        row_dict[metric.get('name')] = int(value)
            data_list.append(row_dict)
    df = pd.DataFrame(data_list)
    return df

def main():
    analytics = initialize_analyticsreporting()
    response = get_report(analytics)
    print_response(response)

if __name__ == '__main__':
    main()
    # 现在可以在函数外部直接访问df了
    print(df.head())

⚠️ 注意:全局变量虽然简单,但在大型项目中容易导致代码逻辑混乱,难以追踪变量的修改,所以仅推荐在小型脚本中临时使用。

方案2:让main函数返回DataFrame(推荐的规范方式)

这是更符合Python设计理念的做法:让main函数返回生成的DataFrame,然后在主程序中赋值给变量,这样既避免了全局变量的副作用,又能在外部访问数据:

# 导入和常量定义部分与方案1一致

# initialize_analyticsreporting、get_report、print_response函数保持不变(去掉global相关代码)

def main():
    analytics = initialize_analyticsreporting()
    response = get_report(analytics)
    return print_response(response)  # 返回生成的DataFrame

if __name__ == '__main__':
    df = main()  # 将返回的DataFrame赋值给全局可用的df
    # 后续可以直接使用df
    print(df.describe())

这种方式逻辑清晰,函数职责明确(生成数据的函数返回数据,主程序负责接收和使用),代码更易维护。

方案3:封装成类(适合长期扩展的项目)

如果你的后续需求会不断扩展(比如添加数据清洗、分析功能),可以把所有相关逻辑封装成类,将DataFrame作为类的实例属性,方便后续方法调用:

import pandas as pd
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build

KEY_FILE_LOCATION = "your-key-file.json"
SCOPES = ['https://www.googleapis.com/auth/analytics.readonly']
VIEW_ID = "your-view-id"

class AnalyticsReportProcessor:
    def __init__(self):
        self.df = None  # 初始化DataFrame属性
        self.analytics = self._initialize_analyticsreporting()
    
    def _initialize_analyticsreporting(self):
        credentials = ServiceAccountCredentials.from_json_keyfile_name(
            KEY_FILE_LOCATION, SCOPES)
        return build('analyticsreporting', 'v4', credentials=credentials)
    
    def _get_report(self):
        return self.analytics.reports().batchGet(
            body={
                'reportRequests': [
                    {
                        'viewId': VIEW_ID,
                        'pageSize': 100000,
                        'dateRanges': [{'startDate': '7daysAgo', 'endDate': 'yesterday'}],
                        'metrics': [{'expression': 'ga:sessions'}],
                        'dimensions': [{'name': 'ga:country'}, {'name': 'ga:hostname'}, {'name': 'ga:pagePathLevel1'}, {'name': 'ga:pagePathLevel2'}, {'name': 'ga:keyword'}, {'name': 'ga:adMatchedQuery'}, {'name': 'ga:operatingSystem'}, {'name': 'ga:hour'}, {'name': 'ga:exitPagePath'}]
                    }
                ]
            }
        ).execute()
    
    def _process_response(self, response):
        data_list = []
        for report in response.get('reports', []):
            columnHeader = report.get('columnHeader', {})
            dimensionHeaders = columnHeader.get('dimensions', [])
            metricHeaders = columnHeader.get(
                'metricHeader', {}).get('metricHeaderEntries', [])
            rows = report.get('data', {}).get('rows', [])
            for row in rows:
                row_dict = {}
                dimensions = row.get('dimensions', [])
                dateRangeValues = row.get('metrics', [])
                for header, dimension in zip(dimensionHeaders, dimensions):
                    row_dict[header] = dimension
                for i, values in enumerate(dateRangeValues):
                    for metric, value in zip(metricHeaders, values.get('values')):
                        if ',' in value or '.' in value:
                            row_dict[metric.get('name')] = float(value)
                        else:
                            row_dict[metric.get('name')] = int(value)
                data_list.append(row_dict)
        self.df = pd.DataFrame(data_list)
    
    def run(self):
        response = self._get_report()
        self._process_response(response)

if __name__ == '__main__':
    processor = AnalyticsReportProcessor()
    processor.run()
    # 通过实例属性访问DataFrame
    print(processor.df.head())

这种方式把所有相关逻辑聚合在一起,代码结构更清晰,后续添加新功能(比如数据过滤、可视化)时可以直接在类中新增方法,非常适合需要长期维护的项目。

内容的提问来源于stack exchange,提问作者Jonas Palačionis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:11:00