Установить параметры функции на основе значения другого параметра - PullRequest
0 голосов
/ 30 ноября 2018

Прошу прощения, если название расплывчато.Позвольте мне объяснить ситуацию.

Скажем, я хочу сгенерировать какое-то случайное число на основе некоторого распределения, оно может быть равномерным, нормальным, пуассоновским, биномиальным и т. Д. Каждое распределение имеет свои собственные параметры / ключевые аргументы для определения,Например, у Normal есть среднее и стандартное значение, у Пуассона есть лямбда, у равномерное есть upper_bound и lower_bound и так далее.Как определить сигнатуру этой функции, которая должна принимать тип распределения в виде строки в качестве одного аргумента, и, в зависимости от значения, функция должна иметь обязательные (ключевые слова) аргументы, такие как параметры распределения, такие как mean и std?

def generate(distribution, params):
    """
    Args:
        distribution (str): can take values 'uniform', 'normal', 'poisson', etc.
        params (dict of str: float): based on the value of distribution, it should have the required parameters for the distribution
    """
    if distribution == 'uniform':
        result = uniform(params['lower'], params['upper'])
    elif distribution == 'normal':
        result = normal(params['mean'], params['std'])
    elif distribution == 'poisson':
        result = poisson(params['lambda'])
    elif ...:
        ...

Один из вариантов, который я могу придумать, - это просто иметь ** kwargs в подписи, где я могу подключить ключевые аргументы означают, std, lambda и так далее.Но это довольно грязно и не отражает соответствующие обязательные аргументы, приведенные в распределении.Интересно, как Pythonic делает это?

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

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

1 Ответ

0 голосов
/ 01 декабря 2018

Вы можете использовать функцию, которая возвращает требуемый тип функции.Как это:

import random
def generate(dist):
    if dist == 'uniform':
        def uniformDist(lower=0, upper=1):
            return random.uniform(lower,upper)
        return uniformDist

    if dist == 'poisson':
        def poissonDist(lmbda=1,):
            return poisson(lmbda)
        return poissonDist

print(generate('poisson')(lmbda=3))
print(generate('uniform')(lower=34, upper=78))
...