我有一个名为get_next_train的函数:
def get_next_train(params):
res =requests.get(base, params=params)
parsed_json = res.json()
#Zeiten aus parsed_json extrahieren
time_strings = [d["from"]["prognosis"]["departure"]
for d in parsed_json["connections"]]
#String, um Zeiten in time_strings nach ISO 8601 zu parsen
iso_format = "%Y-%m-%dT%H:%M:%S%z"
# Time Strings zu datetime Objekten konvertieren
times = [datetime.strptime(ts, iso_format)
for ts in time_strings if ts is not None]
# Checken, ob times leer sind
if not times:
return None # CHANGE: return None if no times found
#Zeitzone der ersten zeit in Times speichern
tz = times[0].tzinfo
#jetztige Zeit mit Zeitzone tz, Mikrosekunden löschen
nowtime = datetime.now(tz).replace(microsecond=0)
time = min(t for t in times[0:3] if t > nowtime) # CHANGE: use min
return time, time - nowtime
我希望它执行两次:第一次像现在这样。但是第二次,time_strings应该是这样:
time_strings = [d["from"]["departure"]
for d in parsed_json["connections"]]
我尝试了无数种方法,但是每次都失败了。最常见的错误是:
未定义名称“ parsed_json”。
我当然可以复制粘贴整个代码并更改我需要的位,但是还有更好的方法吗?
答案 0 :(得分:2)
分解的一般原理是保持通用代码相同,并将差异转换为函数参数。
函数的两个版本之间的区别是列表理解中提取了哪个子元素。我们可以将差异抽象为一个函数:
-O2
现在您可以打电话
def get_next_train(params, select_element):
res = requests.get(base, params=params)
parsed_json = res.json()
# extract times from parsed_json
time_strings = [select_element(d)
for d in parsed_json["connections"]]
...
或者我们可以使用
get_next_train(params, lambda d: d["from"]["prognosis"]["departure"])
get_next_train(params, lambda d: d["from"]["departure"])
在功能和
中 time_strings = [select_element(d["from"])["departure"]
for d in parsed_json["connections"]]
在通话中,它消除了所有冗余,但更难以理解和概括恕我直言。
答案 1 :(得分:1)
封装保持不变的内容。封装各种内容。
您可以定义两个不同的函数来获取时间字符串。获得预后的一种:
def time_strings_from_prognosis(json):
return [d["from"]["prognosis"]["departure"]
for d in json["connections"]]
另一个获取其他:
def time_strings_other(json):
return [d["from"]["departure"]
for d in json["connections"]]
然后将函数传递给原始函数以获取时间字符串:
def get_next_train(params, get_time_strings):
...
time_strings = get_time_strings(parsed_json)
并将其称为:
get_next_train(params, time_strings_from_prognosis)
或:
get_next_train(params, time_strings_other)
答案 2 :(得分:0)
您可以在调用函数时尝试添加第二个参数:
def get_next_train(params, flag):
res =requests.get(base, params=params)
parsed_json = res.json()
#Zeiten aus parsed_json extrahieren
if (flag):
time_strings = [d["from"]["prognosis"]["departure"]
for d in parsed_json["connections"]]
else:
time_strings = [d["from"]["departure"]
for d in parsed_json["connections"]]
#String, um Zeiten in time_strings nach ISO 8601 zu parsen
iso_format = "%Y-%m-%dT%H:%M:%S%z"
# Time Strings zu datetime Objekten konvertieren
times = [datetime.strptime(ts, iso_format)
for ts in time_strings if ts is not None]
# Checken, ob times leer sind
if not times:
return None # CHANGE: return None if no times found
#Zeitzone der ersten zeit in Times speichern
tz = times[0].tzinfo
#jetztige Zeit mit Zeitzone tz, Mikrosekunden löschen
nowtime = datetime.now(tz).replace(microsecond=0)
time = min(t for t in times[0:3] if t > nowtime) # CHANGE: use min
return time, time - nowtime
这里的'flag'参数只是一个布尔值,但可以是您想要的任何值...