簡體   English   中英

Python3 中的可變長度參數 (*args)

[英]Variable Length Arguments (*args) in Python3

我對 Python3 相當陌生。 我對可變長度參數(*args)有疑問。 根據我的理解,我們使用可變長度參數列表(或元組)的原因是,當您需要一個可能具有不同數量參數的函數時,它們很有用。 像這樣的功能

def main():
    x = ('meow', 'grrr', 'purr')
    kitten(*x)

def kitten(*args):
    if len(args):
        for s in args:
            print(s)
    else: print('Empty')

if __name__ == '__main__': main()

給出相同的輸出

def main():
    x = ('meow', 'grrr', 'purr')
    kitten(x)

def kitten(args):
    if len(args):
        for s in args:
            print(s)
    else: print('Empty')

if __name__ == '__main__': main()

輸出

meow
grrr
purr

我看不出有什么區別,為什么使用可變長度參數(*args)更好。 有人可以向我解釋一下嗎?

而且,星號的真正作用是什么?

x = ('meow', 'grrr', 'purr')
print (*x)

輸出

meow grrr purr

看起來,它只是將元組內的變量取出。 如果我這樣做

print (len(*x))
print (type(*x))

它會給我錯誤

print (len(*x))
TypeError: len() takes exactly one argument (3 given)
print(type(*x))
TypeError: type.__new__() argument 2 must be tuple, not str

*在像listtuple這樣的iterable對象之前使用時,它會擴展(解包) iterable對象的內容。 所以,當你有:

x = ('meow', 'grrr', 'purr')
print(*x)

你的輸出是:

meow grrr purr

這里, x是一個tuple ,它是iterable的,所以*在打印之前擴展了x的內容。

當在functionmethodparameter前面使用*時,它允許我們傳遞可變數量的參數。

在你的例子中,

def main():
x = ('meow', 'grrr', 'purr')
kitten(*x)

def kitten(*args):

在將x中的值傳遞給函數kitten之前,您正在擴展存儲在行kitten(*x)中的值。 並且您的函數kitten(*args)被定義為接受可變數量的參數。 由於*args ,您可以向它傳遞 3 個參數, meow grrr purr

在第二個例子中:

def main():
    x = ('meow', 'grrr', 'purr')
    kitten(x)

def kitten(args):

您只將一個參數傳遞給函數kitten() ,即x ,其類型為tuple

使用*args的優勢

如果您選擇使用示例中的listtuple

首先,您需要在調用function之前創建一個listtuple

其次,如果你使用list ,你必須小心list是可變的,所以如果list在函數內部被修改,變化也可以在函數外部看到。

例子

def main():
    x = [1, 2, 3]
    >>> print(x)
    >>> [1, 2, 3]

    f(x)
    >>> print(x)
    >>> [9, 2, 3]

def f(x):
    x[0] = 9

main()

但是,如果你使用*args ,你就不必擔心這些東西。

在您的情況下,您使用了tuple ,它是immutable的,因此您不必擔心mutable問題。

是的,例如

def main():
    kitten(*('meow', 'grrr', 'purr'))

def kitten(*args):
    for i in args:
        print(i)

看起來毫無意義,因為等式兩邊都使用了* ,並且直接提供了值。 (我通過內聯x使它變得更加明顯毫無意義。)

但是,我們不必做這些事情。 例如,讓我們嘗試僅在定義端使用*

def main():
    kitten('meow', 'grrr', 'purr')

def kitten(*args):
    for i in args:
        print(i)

現在我們不必為調用匹配特定數量的參數,也不必在本地創建序列(元組、列表等)來將字符串包裝成單個參數。

或者,僅在調用方使用* ,並間接提供值:

def noises():
    return ('meow', 'grrr', 'purr')

def main():
    kitten(*noises())

def kitten(a, b, c):
    print(f'I am a kitten and I like to {a} and {b} and {c}.')

即使被調用函數的邏輯不涉及迭代,我們也可以將我們的參數視為結構化數據,可以在其他地方計算,存儲在變量中等,只要它們正確匹配調用。

暫無
暫無

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

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