Переопределить функцию без оператора if - PullRequest
0 голосов
/ 13 октября 2019

Три модели имеют ImageField, что относится к одной функции, с if. Есть какие-нибудь предложения, как выполнить эту функцию без if?

def upload_location(instance, filename):
    _, extension = os.path.splitext(filename)

    if isinstance(instance, (Story,)):
        return f'stories/{instance.id}/cover{extension}'
    elif isinstance(instance, (Episode,)):
        return f'stories/{instance.story.id}/{instance.index}/cover{extension}'
    elif isinstance(instance, (EpisodeSlide,)):
        return f'stories/{instance.episode.story.id}/{instance.episode.index}/{instance.id}{extension}

1 Ответ

1 голос
/ 13 октября 2019

Я согласен с @Dennis: если заявления делают код очень читабельным. Ниже приведена моя попытка решения без использования if. Возможно, есть более эффективные способы, например, использование оператора format вместо «f-строк» ​​и, как предполагает @Dennis, возможно использование типа в качестве ключа.

def upload_location(instance, filename):
    lookup = dict([
        (Story.__name__, lambda instance: f'stories/{instance.id}/cover{extension}'),
        (Episode.__name__, lambda instance: f'stories/{instance.story.id}/{instance.index}/cover{extension}'),
        (EpisodeSlide.__name__, lambda instance: f'stories/{instance.episode.story.id}/{instance.episode.index}/{instance.id}{extension}')
    ])

    _, extension = os.path.splitext(filename)
    loc = lookup[instance.__class__.__name__](instance)
    return loc
print(upload_location(e, "hello.txt"))
print(upload_location(es, "hello.txt"))
print(upload_location(s, "hello.txt"))

stories/1/10/cover.txt
stories/1/10/100.txt
stories/1/cover.txt

Повторить, если-последовательности намного лучше, чем вышеупомянутая функция !!

Надеюсь, это поможет.

С уважением,

Прасант

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...