只需稍作更改即可第二次调用函数

时间:2018-09-15 21:28:12

标签: python function variables

我有一个名为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”。

我当然可以复制粘贴整个代码并更改我需要的位,但是还有更好的方法吗?

3 个答案:

答案 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'参数只是一个布尔值,但可以是您想要的任何值...