当前位置: 代码迷 >> python >> 第二次调用函数时只需稍微更改
  详细解决方案

第二次调用函数时只需稍微更改

热度:50   发布时间:2023-06-19 09:25:48.0

我有一个名为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'未定义。

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

因子分解的一般原则是保持公共代码相同并将差异转化为函数参数。

函数的两个版本之间的区别在于列表推导中提取了哪个子元素。 我们可以将差异抽象为函数:

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"]]

在功能和

get_next_train(params, lambda x: x["prognosis"])
get_next_train(params, lambda x: x)

在通话中,它消除了所有冗余,但更难以理解和推广恕我直言。

封装保持不变的内容。 封装各种不同的东西。

您可以定义两个不同的函数来获取时间字符串。 一个得到预后:

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)

您可以在调用函数时尝试添加第二个参数:

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

  相关解决方案