Python 循环中某些函数的全局变量改变但其他函数不改变
Python global variable changing for some functions but not others in loop
我敢肯定之前有人回答过类似的问题,但这些帖子似乎已在有关全局变量和循环的更热门问题中丢失了。
我想做的是编写一个循环来单步执行 Google 分析 API,一次提取一天的数据。我敢肯定已经有一些软件包可以做到这一点,但这对我来说是一种学习经验。
我卡住的地方是我的循环似乎进行了正确的天数,但是发送到 GA 报告 API (V4) 的实际请求没有使用全局变量更新,即使一个简单的 print() 似乎表明它确实更新了。
这是我的代码:
# Reporting API V4
from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
# Import JSON
import json
# Open JSON config file
jsonConfig = open("config.json", "r")
# Parse the JSON file
configRead = json.loads(jsonConfig.read())
# Define global vars
SCOPES = ['https://www.googleapis.com/auth/analytics.readonly']
KEY_FILE_LOCATION = configRead['keyFileLocation']
VIEW_ID = 12345678 # made up for this exercise
startDate = 732
endDate = 732
# Define report #1
request1 = {
'reportRequests':
[
{
'viewId': VIEW_ID,
'dateRanges':
[
{
'startDate': f'{startDate}daysAgo',
'endDate': f'{endDate}daysAgo'
}
],
'metrics':
[
{
'expression': 'ga:sessions'
}
],
'dimensions':
[
{
'name': 'ga:date'
}
],
'pageSize': 1
}
]
}
def initialize_analyticsreporting():
# Initializes an Analytics Reporting API V4 service object.
# Returns: An authorized Analytics Reporting API V4 service object.
credentials = ServiceAccountCredentials.from_json_keyfile_name(
KEY_FILE_LOCATION, SCOPES)
# Build the service object
analytics = build('analyticsreporting', 'v4', credentials=credentials)
return analytics
def get_report(analytics):
# Queries the Analytics Reporting API V4.
# Args: _ analytics _ : An authorized Analytics Reporting API V4 service object.
# Returns: The Analytics Reporting API V4 response.
global startDate
global endDate
global request1
return analytics.reports().batchGet(
body=request1
).execute()
def print_response(response):
# Parses and prints the Analytics Reporting API V4 response.
# Args: _ response _ : An Analytics Reporting API V4 response.
for report in response.get('reports', []):
columnHeader = report.get('columnHeader', {})
dimensionHeaders = columnHeader.get('dimensions', [])
metricHeaders = columnHeader.get('metricHeader', {}).get('metricHeaderEntries', [])
for row in report.get('data', {}).get('rows', []):
dimensions = row.get('dimensions', [])
dateRangeValues = row.get('metrics', [])
for header, dimension in zip(dimensionHeaders, dimensions):
print(header + ': ', dimension)
for i, values in enumerate(dateRangeValues):
for metricHeader, value in zip(metricHeaders, values.get('values')):
print(metricHeader.get('name') + ':', value)
def main():
global startDate
global endDate
analytics = initialize_analyticsreporting()
while startDate >= 725:
response = get_report(analytics)
print(f'{startDate}daysAgo')
print_response(response)
startDate -= 1
endDate -= 1
print("Done now, cheers")
if __name__ == '__main__':
main()
在那个具体的例子中,它在循环时获取 startDate 和 endDate 在 request1 内更新。
目前的输出:
732daysAgo
ga:date: 20181123
ga:sessions: 2887
731daysAgo
ga:date: 20181123
ga:sessions: 2887
730daysAgo
ga:date: 20181123
ga:sessions: 2887
729daysAgo
ga:date: 20181123
ga:sessions: 2887
728daysAgo
ga:date: 20181123
ga:sessions: 2887
727daysAgo
ga:date: 20181123
ga:sessions: 2887
726daysAgo
ga:date: 20181123
ga:sessions: 2887
725daysAgo
ga:date: 20181123
ga:sessions: 2887
Done now, cheers
知道可能是什么问题吗?
问题是您希望根据 startDate
和 endDate
的值动态生成 request1
,但您目前只在程序的开头,因此它永远不会根据这些变量中的任何一个更改其定义。
要 request1
是动态的,您可以创建一个 returns 请求的函数:
startDate = 732
endDate = 732
VIEW_ID = 12345678
def get_request1():
global startDate
global endDate
global VIEW_ID
return {
'reportRequests':
[
{
'viewId': VIEW_ID,
'dateRanges':
[
{
'startDate': f'{startDate}daysAgo',
'endDate': f'{endDate}daysAgo'
}
],
'metrics':
[
{
'expression': 'ga:sessions'
}
],
'dimensions':
[
{
'name': 'ga:date'
}
],
'pageSize': 1
}
]
}
因此,每次调用get_request1()
,其返回值将始终包含当前的开始日期和结束日期值。
我敢肯定之前有人回答过类似的问题,但这些帖子似乎已在有关全局变量和循环的更热门问题中丢失了。
我想做的是编写一个循环来单步执行 Google 分析 API,一次提取一天的数据。我敢肯定已经有一些软件包可以做到这一点,但这对我来说是一种学习经验。
我卡住的地方是我的循环似乎进行了正确的天数,但是发送到 GA 报告 API (V4) 的实际请求没有使用全局变量更新,即使一个简单的 print() 似乎表明它确实更新了。
这是我的代码:
# Reporting API V4
from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
# Import JSON
import json
# Open JSON config file
jsonConfig = open("config.json", "r")
# Parse the JSON file
configRead = json.loads(jsonConfig.read())
# Define global vars
SCOPES = ['https://www.googleapis.com/auth/analytics.readonly']
KEY_FILE_LOCATION = configRead['keyFileLocation']
VIEW_ID = 12345678 # made up for this exercise
startDate = 732
endDate = 732
# Define report #1
request1 = {
'reportRequests':
[
{
'viewId': VIEW_ID,
'dateRanges':
[
{
'startDate': f'{startDate}daysAgo',
'endDate': f'{endDate}daysAgo'
}
],
'metrics':
[
{
'expression': 'ga:sessions'
}
],
'dimensions':
[
{
'name': 'ga:date'
}
],
'pageSize': 1
}
]
}
def initialize_analyticsreporting():
# Initializes an Analytics Reporting API V4 service object.
# Returns: An authorized Analytics Reporting API V4 service object.
credentials = ServiceAccountCredentials.from_json_keyfile_name(
KEY_FILE_LOCATION, SCOPES)
# Build the service object
analytics = build('analyticsreporting', 'v4', credentials=credentials)
return analytics
def get_report(analytics):
# Queries the Analytics Reporting API V4.
# Args: _ analytics _ : An authorized Analytics Reporting API V4 service object.
# Returns: The Analytics Reporting API V4 response.
global startDate
global endDate
global request1
return analytics.reports().batchGet(
body=request1
).execute()
def print_response(response):
# Parses and prints the Analytics Reporting API V4 response.
# Args: _ response _ : An Analytics Reporting API V4 response.
for report in response.get('reports', []):
columnHeader = report.get('columnHeader', {})
dimensionHeaders = columnHeader.get('dimensions', [])
metricHeaders = columnHeader.get('metricHeader', {}).get('metricHeaderEntries', [])
for row in report.get('data', {}).get('rows', []):
dimensions = row.get('dimensions', [])
dateRangeValues = row.get('metrics', [])
for header, dimension in zip(dimensionHeaders, dimensions):
print(header + ': ', dimension)
for i, values in enumerate(dateRangeValues):
for metricHeader, value in zip(metricHeaders, values.get('values')):
print(metricHeader.get('name') + ':', value)
def main():
global startDate
global endDate
analytics = initialize_analyticsreporting()
while startDate >= 725:
response = get_report(analytics)
print(f'{startDate}daysAgo')
print_response(response)
startDate -= 1
endDate -= 1
print("Done now, cheers")
if __name__ == '__main__':
main()
在那个具体的例子中,它在循环时获取 startDate 和 endDate 在 request1 内更新。
目前的输出:
732daysAgo
ga:date: 20181123
ga:sessions: 2887
731daysAgo
ga:date: 20181123
ga:sessions: 2887
730daysAgo
ga:date: 20181123
ga:sessions: 2887
729daysAgo
ga:date: 20181123
ga:sessions: 2887
728daysAgo
ga:date: 20181123
ga:sessions: 2887
727daysAgo
ga:date: 20181123
ga:sessions: 2887
726daysAgo
ga:date: 20181123
ga:sessions: 2887
725daysAgo
ga:date: 20181123
ga:sessions: 2887
Done now, cheers
知道可能是什么问题吗?
问题是您希望根据 startDate
和 endDate
的值动态生成 request1
,但您目前只在程序的开头,因此它永远不会根据这些变量中的任何一个更改其定义。
要 request1
是动态的,您可以创建一个 returns 请求的函数:
startDate = 732
endDate = 732
VIEW_ID = 12345678
def get_request1():
global startDate
global endDate
global VIEW_ID
return {
'reportRequests':
[
{
'viewId': VIEW_ID,
'dateRanges':
[
{
'startDate': f'{startDate}daysAgo',
'endDate': f'{endDate}daysAgo'
}
],
'metrics':
[
{
'expression': 'ga:sessions'
}
],
'dimensions':
[
{
'name': 'ga:date'
}
],
'pageSize': 1
}
]
}
因此,每次调用get_request1()
,其返回值将始终包含当前的开始日期和结束日期值。