自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python 深度探討 *args

開發(fā) 前端
在本文中,我們深入探討了 Python 中最具標(biāo)志性的語法之一 — *args。它在開發(fā)函數(shù)和后續(xù)使用函數(shù)的用戶方面提供了很大的靈活性。

作為Python中最獨(dú)特的語法之一,*args 在編程過程中給我們帶來了很多靈活性和便利性。我認(rèn)為它們反映了“Pythonic”和“Python之禪”。然而,我發(fā)現(xiàn)它們對于學(xué)習(xí)者(尤其是初學(xué)者)來說很難理解。在本文中,我將盡力解釋Python中這個標(biāo)志性的概念,并基于我的知識提供實(shí)際用例。我希望這能幫助更好地理解它。

一、 “*args” 究竟是什么?

*args 代表“參數(shù)”。它允許我們向函數(shù)傳遞任意數(shù)量的位置參數(shù)(稍后會解釋)。在函數(shù)內(nèi)部,我們可以獲得所有位置參數(shù)的元組。因此,我們可以在函數(shù)中對參數(shù)元組進(jìn)行任何操作。下面是一個 *args 的簡單示例。

def add_up(*numbers):
    result = 0
    for num in numbers:
        result += num
    return result
print(add_up(1, 2, 3))

當(dāng)我們調(diào)用這個 add_up() 函數(shù)時,我們向它傳遞了三個位置參數(shù)。在Python中,如果我們不指定參數(shù)的名稱,它們將被視為位置參數(shù)。這些參數(shù)根據(jù)它們的位置確定,因此稱為位置參數(shù)。

在上面的示例中,所有位置參數(shù) 1、2、3 都傳遞到了函數(shù)中,并被 *numbers 參數(shù)“捕獲”。然后,我們可以從這個參數(shù) numbers 中訪問所有這些參數(shù)。星號 * 告訴Python這是一個 *args 類型的參數(shù)。之后,一個簡單的 for 循環(huán)將所有參數(shù)相加并打印結(jié)果。

正如上面提到的,*args 的美妙之處在于它可以接受任意數(shù)量的位置參數(shù)。因此,如果需要,我們可以傳遞更多的參數(shù)。、

print(add_up(1, 2, 3, 4))

在這里,我們可以通過向原始函數(shù)添加一行來驗(yàn)證變量 numbers 是否是一個元組。

def add_up(*numbers):
    print(type(numbers))
    result = 0
    for num in numbers:
        result += num
    return result
print(add_up(1, 2, 3))

Python使用元組來包含這些參數(shù)的原因主要是因?yàn)樗鼈兪遣豢勺兊?。因此,在?chuàng)建后它們不能被修改。

二、 *args 的實(shí)際用例

現(xiàn)在,讓我們看看 *args 的實(shí)際用例。由于它允許傳遞任意數(shù)量的參數(shù),在許多情況下我們不知道需要向函數(shù)傳遞多少個參數(shù),這將是它最好的使用場景。

1.生成動態(tài)SQL查詢

其中一個常見用例是生成SQL查詢。假設(shè)我們需要編寫一個函數(shù)來生成帶有未知數(shù)量過濾條件的SELECT語句。在大多數(shù)其他編程語言中有兩個痛點(diǎn)。

  • 我們需要構(gòu)建一個集合類型的變量,比如數(shù)組,來打包所有的條件。然后,我們需要在函數(shù)內(nèi)部解包所有的條件。
  • 我們不知道條件的數(shù)量。它可能是零。我們還需要處理?xiàng)l件是否應(yīng)該從“WHERE”或“AND”開始。一些開發(fā)人員喜歡在查詢中添加“WHERE 1=1”,這樣所有條件都可以從AND開始。

這兩個痛點(diǎn)在Python中都可以優(yōu)雅地解決??匆幌孪旅娴拇a。


# Generating Dynamic SQL Queries
def create_query(table, *conditions):
    sql = f"SELECT * \nFROM {table}"
    if conditions:
        return sql + "\nWHERE " + "\nAND ".join(conditions)
    return sql

*conditions 是一個 *args 參數(shù),可以接受零個或多個條件。該函數(shù)首先構(gòu)建 SELECT 查詢,然后檢查 conditions 中是否有任何參數(shù)。如果有,就使用 .join() 函數(shù)構(gòu)建條件子句。讓我們看一些結(jié)果。從零條件開始。

# 沒有條件
print(create_query("Users"))

如果只有一個條件,“\nAND ”.join(conditions) 將是元組中唯一的條件。由于它只是一個連接器,所以“AND”不會出現(xiàn)。

# 有一個條件
print(
create_query("Users",
"age > 18"
))

如果有多個條件,也可以工作。在每兩個條件字符串之間,將使用“AND”作為連接器。

# 有多個條件
print(
create_query("Users",
"age > 18",
"status = 'active'",
"is_vip = 'true'"
))

順便說一句,如果您想要優(yōu)雅地構(gòu)建一些非常復(fù)雜的SQL查詢,可能有比玩弄字符串更好的做法。查看這篇文章,了解有關(guān)名為 sqlglot 的工具的更多信息。

2. 靈活的日志消息

假設(shè)我們正在開發(fā)一個需要記錄各種不同類型消息的軟件。問題在于,這些不同類型的消息具有不同的組件。例如,用戶登錄消息只需要告訴活動類型和用戶登錄了誰。另一方面,文件上傳日志消息具有更多的組件,如文件名、大小和經(jīng)過的時間。

當(dāng)然,我們可以在沒有 *args 的情況下實(shí)現(xiàn)這一點(diǎn)。但是,我們要么需要在將所有組件傳遞給 log_messages() 函數(shù)之前構(gòu)建一個列表,要么在將它們傳遞給函數(shù)之前將組件連接在一起作為單個字符串。有了 *args,log_messages() 函數(shù)實(shí)際上并不關(guān)心有多少個組件。

from datetime import datetime

def log_messages(*msg):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    full_message = " | ".join(msg)
    print(f"[{timestamp}] {full_message}")

# Usage examples
log_messages("User logged in", "Username: Chris")
log_messages("File uploading", "Filename: report.pdf", "/ctao/document/report.pdf")
log_messages("File uploaded", "Filename: report.pdf", "Size: 2MB", "Elapsed Time: 1.3s")

在上面的代碼中,我們實(shí)現(xiàn)了 log_messages() 函數(shù)。首先獲取當(dāng)前時間戳。然后,所有組件字符串都使用分隔符連接在一起,以提高可讀性。最后,打印日志。示例用法僅供演示目的。在實(shí)踐中,這些更可能是變量。結(jié)果看起來很棒:

3. 集合上的計(jì)算

有時,我們需要對一些集合類型(如列表和集合)進(jìn)行一些計(jì)算。在這種情況下,如果我們想將幾個列表放入單個列表中,這肯定可以工作,但在可讀性和靈活性方面并不理想。在這種情況下,*args 將會很有幫助。


def find_common_elements(*datasets):
    # Initialize the common elements set with the first dataset
    common_elements = datasets[0] if datasets else {}

    # Intersect with the remaining datasets
    for dataset in datasets[1:]:
        common_elements.intersection_update(dataset)

    return common_elements

# Usage examples:
dataset1 = {1, 2, 3, 4}
dataset2 = {2, 3, 4, 5}
dataset3 = {3, 4, 5, 6}

common_elements = find_common_elements(dataset1, dataset2, dataset3)
print(f"The common elements in the datasets are: {common_elements}")

在上面的代碼中,find_common_elements() 函數(shù)接受任意數(shù)量的集合,并獲取它們的交集。它使用第一個集合來初始化公共集合。然后,使用公共集合與其他集合進(jìn)行交集運(yùn)算。結(jié)果如下。

三、一些 *args 的 Python 原生用法

作為最獨(dú)特的語法之一,*args 不足為奇地在許多 Python 內(nèi)置模塊及其函數(shù)中使用。以下是一些示例。讓我們看看這些原生示例以及為什么在這些場景中使用 *args。這些是非常好的參考,可以用來指導(dǎo)我們的編碼。會不會得到比 Python 本身更好的 Python 教程。

1. 路徑拼接

我首先想到的是 os.path.join() 方法。當(dāng)我們處理文件系統(tǒng)時,這是最常用的函數(shù)之一。例如,如果我們想將所有這些組件連接在一起并構(gòu)建文件路徑,os.path.join() 將是最簡單的方法。

import os
# 接受任意數(shù)量的路徑組件
path = os.path.join("Users", "CTao", "Documents", "Work", "report.txt")
print(path)

以下是結(jié)果:

在這個函數(shù)中,利用 *args 提供了最大的靈活性,因?yàn)槲覀儾恍枰獡?dān)心路徑組件的數(shù)量。它還提高了代碼的可讀性,因?yàn)槲覀儾恍枰獙⑦@些組件放入任何集合類型的變量中。

2. 最大值和最小值

我想到的最簡單的示例就是 min() 和 max() 函數(shù)。

print(max(1, 2, 3, 4, 5))
print(min(1, 2, 3, 4, 5))

它們分別從 *args 中獲取最大值和最小值,我們不需要傳遞一個列表給它。順便說一句,我們可能會發(fā)現(xiàn) max() 和 min() 實(shí)際上也支持可迭代的參數(shù)??聪旅娴氖纠?/p>

max([1, 2, 3, 4, 5])

多么靈活!它考慮了兩種情況,并支持了使用該函數(shù)的兩種直觀方式。如果想在代碼中做類似的事情,一個簡單的想法是檢查 args[0]。如果它是一個列表,就使用該列表。否則,使用整個 args 并迭代它。

3. 打印函數(shù)

我相信大多數(shù)人都知道 print() 函數(shù)也支持 *args 模式。當(dāng)我們使用此模式時,字符串的默認(rèn)分隔符將是空格。

print("Towards", "Data", "Science")
print("Towards", "Data", "Science", sep=" | ")

在第二個示例中,sep=" | " 幫助我們自定義了分隔符。這表明我們可以將 *arg 與其他關(guān)鍵字參數(shù)一起使用。

四、不要為所有事情都使用 *args!

當(dāng)然,我寫這篇文章是為了鼓勵使用 *args。但是,請不要誤解我的意思。我并不是說應(yīng)該一直使用它?,F(xiàn)在,讓我們展示一個使用 *args 的不好的偽代碼示例。

def my_function(*args):
    result = args[1] + args[2]
    if result > 100:
        result += args[4]
    if args[5] != args[6]:
        return result + args[7]
    else:
        return result

在這個例子中,盡管總共有 8 個參數(shù),但它實(shí)際上通過使用 *args 損害了可讀性。在這種情況下,函數(shù)嚴(yán)格依賴于參數(shù)的位置。最好使用命名參數(shù)或帶有特定鍵的字典。這將在理解該函數(shù)的邏輯方面提高可讀性。

總結(jié)

在本文中,我們深入探討了 Python 中最具標(biāo)志性的語法之一 — *args。它在開發(fā)函數(shù)和后續(xù)使用函數(shù)的用戶方面提供了很大的靈活性。我希望現(xiàn)在我們對它有了更多的了解。

除此之外,我還提供了一些 *args 的實(shí)際和典型用法??赡軙懈喔玫膱鼍?,但本文中的示例來自我的日常使用。歡迎評論本文,為下一位讀者提供更多優(yōu)秀的示例。

最后,我還列出了一些使用 *args 技巧的 Python 原生示例。這些是很好地展示了實(shí)際用例的“官方”示例。

責(zé)任編輯:趙寧寧 來源: 小白玩轉(zhuǎn)Python
相關(guān)推薦

2023-12-22 08:46:15

useEffectVueMobx

2010-03-17 14:33:44

云計(jì)算

2010-03-19 09:12:05

JRuby

2010-01-27 16:10:32

C++靜態(tài)構(gòu)造函數(shù)

2010-05-24 17:13:34

Linux SNMP

2010-12-22 11:19:09

Java字節(jié)代碼

2016-08-12 22:47:17

互聯(lián)網(wǎng)計(jì)算廣告

2010-01-08 15:06:35

JSON功能

2012-12-26 10:46:07

2018-03-14 08:10:44

深度學(xué)習(xí)

2009-11-24 15:44:26

Visual Stud

2016-10-14 13:46:26

2017-06-09 15:58:23

人工智能AI深度學(xué)習(xí)

2010-03-01 15:08:36

2023-03-09 16:39:23

Python傳遞參數(shù)

2010-03-05 13:44:00

Python序列

2010-02-01 10:30:13

Python世界

2010-03-04 13:37:20

Python yiel

2021-09-27 09:55:52

深度學(xué)習(xí)編程人工智能

2024-03-15 09:00:00

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號