如何干净地处理彼此非常相似的多个条件

时间:2019-06-27 17:10:34

标签: python-3.x if-statement branch

我正在尝试找到一种方法来最好地处理彼此非常相似的多个路径文件。当我的代码工作时,我觉得它很麻烦,更难维护且没有大量手工工作就很难扩展(例如,假设我需要继续添加越来越多略有不同的路径。

理想情况下,如果有更好的解决方案,我想尽可能地应用DRY原理,并且不要在各处使用if-else语句。

我认为使用字典或类可能会有所改进,但在字典中存储路径也很麻烦。我对课程没有经验,所以如果没有大量的解决方法,我将无法使它正常工作(我认为我没有正确地构建课程)

代码

def save_df(df, banner, year, month):
    base_path = r'common\path\{0}\for\all\banners\{1}'.format(banner.upper(), year)

    if banner in ('a', 'b'):
        if month < 10:
            # The zero is so I can have the file month in '01, 02, etc.' format
            default_path = os.path.join(base_path, '{0}-0{1}_TEST'.format(year, month))
        else:
            default_path = os.path.join(base_path, '{0}-{1}_TEST'.format(year, month))
    else:
        if month < 10:
            default_path = os.path.join(base_path, '{0}_{1}-0{2}_TEST'.format(banner.upper(), year, month))
        else:
            default_path = os.path.join(base_path, '{0}_{1}-{2}_TEST'.format(banner.upper(), year, month))

    saved_output = [df, default_path]
    return saved_output

该路径没有问题,按预期工作。我相信可以通过重构来改进代码,但是,我不确定处理重复性非常相似的条件的最佳方法。

2 个答案:

答案 0 :(得分:0)

您可以将字典与符合您条件的键一起使用:

import os

def save_df(df, banner, year, month):
    base_path = r'common\path\{0}\for\all\banner\{1}'.format(banner.upper(), year)

    # Each key is a tuple, left key is True if month is less than 10, 
    # right key is True if banner is equal to 'a' or 'b'
    formats = { # Key: (month_less_10, a_b_banner)
      (True, True): '{0}-0{1}_TEST'.format(year, month),
      (False, True): '{0}-{1}_TEST'.format(year, month),
      (True, False): '{0}_{1}-0{2}_TEST'.format(banner.upper(), year, month),
      (False, False): '{0}_{1}-{2}_TEST'.format(banner.upper(), year, month)
    }
    default_path = os.path.join(base_path, formats[(month < 10, banner in ('a', 'b'))]

    saved_output = [df, default_path]
    return saved_output

答案 1 :(得分:0)

通常,在这种情况下有时很难避免代码重复。您可以使用字典和棘手的类来生成特殊类型的条件,但是对于这种简单情况而言,通常不值得这样做。它会使代码的可读性降低,并且可读性很重要。

相反,请坚持使用更简单的技术。我可能会为您的代码推荐三种优化。

首先,您可以使用更高级的格式字符串替换内部条件。使用'{month:0>2}'.format(month=n)将用零填充任意一位月份。 (0说要填充零,>说要右对齐,而2说要填充至少2位数字。)

第二,您可以对外部条件做类似的事情:在一种情况下使用banner.upper() + '_'变量,在另一种情况下使用空字符串。

第三,您可以为分支的主体编写一个函数,但这在我提出另外两个建议之后并没有必要。

def format_path(fmt, year, month, banner=None):
    if banner is None:
        banner = ''
    else:
        banner = banner.upper() + '_'
    return os.path.join(base_path, '{}{}-{:0>2}'.format(banner, year, month))