Получение ** kwargs и распаковка аргументов в теле функции вместо простых аргументов - почему? - PullRequest
3 голосов
/ 21 апреля 2020

Я смотрел на scikit-learn реализацию sklearn.model_selection.train_test_split. У Sklearn обычно есть код высокого качества, поэтому я время от времени читаю его, чтобы изучить хорошие практики. Но недавно я нашел такие вещи:

def train_test_split(*arrays, **options):
    """
    ...
    """
    n_arrays = len(arrays)
    if n_arrays == 0:
        raise ValueError("At least one array required as input")
    test_size = options.pop('test_size', None)
    train_size = options.pop('train_size', None)
    random_state = options.pop('random_state', None)
    stratify = options.pop('stratify', None)
    shuffle = options.pop('shuffle', True)

    if options:
        raise TypeError("Invalid parameters passed: %s" % str(options))

    # ...

Мне было интересно, почему был выбран такой подход? Мне это кажется антипаттерном, но я предполагаю, что разработчики sklearn знали, что они делают, поэтому я, вероятно, упускаю некоторые моменты. Почему бы просто:

def train_test_split(*arrays, test_size=None, train_size=None, ...): 
    # ...

Есть ли преимущества распаковки в функции?

Ответы [ 3 ]

2 голосов
/ 21 апреля 2020

Чтобы сжать все ответы:

1) Заголовки функций менее сложны и требуют меньше аргументов.

2) Позволяет легко расширять код без необходимости переопределять каждый вызов функции .

3) Как предложило johnashu , это позволяет лучше контролировать ошибки, так как их можно настраивать на основе конкретной записи **kwargs, которая отсутствует или неправильно отформатирована.

2 голосов
/ 21 апреля 2020

Это должно управлять ошибкой TypeError, чтобы дать более понятную ошибку. Я думаю!

При предложенном вами подходе ошибка будет:

TypeError: train_test_split() got an unexpected keyword argument 'not_a_valid_kw'

1 голос
/ 21 апреля 2020

Я не могу ответить от их имени, но я верю, что такая форма реализации позволяет более гибко изменять код. Библиотека находится в процессе разработки, и новые версии выпускаются регулярно. Некоторые из этих версий включают изменения в существующие методы. Эта реализация позволяет поддерживать несколько версий без изменения сигнатуры метода или взрыва его с огромным количеством необязательных параметров.

Возможно, есть другие соображения, о которых я не знаю, но это мое предположение. Надеюсь, это поможет.

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