簡體   English   中英

處理不同的,互斥的函數輸入的最Python方式是什么?

[英]What’s the most Pythonic way of handling different, mutually-exclusive function inputs?

我試圖找到一種處理不同的,互斥的函數輸入的干凈方法。 我的想法是,我有一個返回4個值的函數(這些值通過數學方程式鏈接),當您輸入4個值之一時,它將返回所有值。

當前該函數的工作方式如下:

#example relations are simply: b=1+a, c=0.5*a, d=sqrt(a)
def relations(v, vtype="a"):
    if vtype=="a":
        a = v
    elif vtype=="b":
        a = v - 1
    elif vtype=="c":
        a = 2 * v
    elif vtype=="d":
        a = v ** 2

    b = 1 + a
    c = 0.5 * a
    d = a ** 0.5

    return a,b,c,d

用戶通過字符串vtype指定輸入變量是什么,並返回所有值。 用戶不可能輸入一個以上的不同輸入值(這是多余的,因為所有未知數都可以從一個輸入值中確定)。

有沒有更干凈和pythonic的方法來做到這一點? 現在,用字符串指定輸入變量確實很臟。

提前致謝!

您可以使用可變關鍵字參數:

def relations(**kwargs):
    if 'a' in kwargs:
        a = kwargs['a']
    elif 'b' in kwargs:
        a = kwargs['b'] - 1
    elif 'c' in kwargs:
        a = kwargs['c'] * 2
    elif 'd' in kwargs:
        a = kwargs['d'] ** 2
    else:
        raise TypeError('missing an argument')

    b = 1 + a
    c = 0.5 * a
    d = a ** 0.5

    return a, b, c, d

然后使用命名參數:

relations(a=2)
relations(b=4)
relations(c=9)
relations(d=0)

避免許多if - elif的常見方法是構建函數字典:

def relations(v, vtype='a'):
    functions = {
        'a': lambda x: x, 'b': lambda x: x-1,
        'c': lambda x: x * 2, 'd': lambda x: x**2
    }

    a = functions[vtype](v)
    b = 1 + a
    c = 0.5 * a
    d = a ** 0.5
    return a,b,c,d

如果此功能不是瓶頸 ,則可以避免使用lambda ,只需執行以下操作:

values = {'a': v, 'b': v-1, 'c': v * 2, 'd': v**2}
a = values[vtype]

如果您不喜歡在函數簽名中使用vtype的想法,則可以使用單個**kwargs參數:

def relations(**kwargs):
    if len(kwargs) != 1 or not set('abcd').intersection(kwargs):
        raise ValueError('Invalid parameters')
    vtype, v = kwargs.popitem()
    functions = {
        'a': lambda x: x, 'b': lambda x: x-1,
        'c': lambda x: x * 2, 'd': lambda x: x**2
    }

    a = functions[vtype](v)
    b = 1 + a
    c = 0.5 * a
    d = a ** 0.5
    return a,b,c,d

然后將其稱為:

relations(a=...)
relations(b=...)

您可以將vtypes定義為函數,並將函數作為參數傳遞

def a(v):
    return v

def b(v):
    return v-1

def c(v):
    return 2*v

def d(v):
    return v**2

def relations(v, vtype=a):
    value_a = vtype(v)
    value_b = 1 + value_a
    value_c = 0.5 * value_a
    value_d = value_a ** 0.5
    return value_a,value_b,value_c,value_d

有了它,您也可以擺脫if / elif

您可以使用如下形式:

def relations(a=None, b=None, c=None, d=None):
    if a is not None:
        pass
    elif b is not None:
        a = b - 1
    elif c is not None:
        a = 2 * c
    elif d is not None:
        a = d ** 2
    else:
        raise TypeError('At least one argument needed')

    # your calculations

然后,您可以簡單地將函數與relations(c=10)relations(a=2) 因此,您不需要vtype參數。

第一傳遞的參數被用於計算a 如果您使用多個參數調用該函數,則僅會使用第一個參數,而其他參數將被忽略(例如, relations(b=2, c=5)僅會使用bc被忽略)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM