我對 pandas 中的資料框做了很多查詢。pandas.DataFrame.query獲取表示資料幀操作的人類可讀字串,然后使用pandas.eval(記錄在此處)對其進行評估。正如在這個問題中所討論的那樣,我想撰寫如下函式,以不產生 flake8 錯誤的方式編譯查詢字串。有人告訴我,即將被評估的格式化字串是“一個非常滑的斜坡”,但我不知道為什么。
以這種方式格式化查詢字串有什么問題?
import pandas as pd
def query_column_equality(df, a, b):
if a in df.columns:
return df.query('{} == @q'.format(a), local_dict={'q': b})
else:
raise KeyError(a)
def query_column_isin(df, a, b):
if a in df.columns:
return df.query('{}.isin(@q)'.format(a), local_dict={'q': b})
else:
raise KeyError(a)
df = pd.DataFrame({'a': [1, 2], 'b': [10, 20]})
query_value = 20
print(query_column_equality(df, 'b', query_value))
query_iterable = [20]
print(query_column_isin(df, 'b', query_iterable))
uj5u.com熱心網友回復:
有人告訴我,即將被評估的格式化字串是“一個非常滑的斜坡”,但我不知道為什么。
我認為這通常是個好建議。我認為有些問題只能用 eval() 解決,但 99% 的使用 eval() 的代碼可以用其他方法更容易、更安全地解決。
我會將其包括在 99% 中。
例如,這兩個都可以以更安全的方式重寫:
return df.query('{} == @q'.format(a), local_dict={'q': b})
...
return df.query('{}.isin(@q)'.format(a), local_dict={'q': b})
可以變成:
return df.loc[df[a] == b]
...
return df.loc[df[a].isin(b)]
我的問題是這里的代碼是否有風險——對列的檢查是否足以安全地運行查詢?
不,我不這么認為。想象一下,您在程式中的某處使用 read_csv 加載了一個不受信任的 CSV。CSV 可以合法地包含該列import os; os.system('rm -rf *')。如果您檢查您要查詢的列是否確實存在于資料框中,則該檢查將成功。
有一些方法可以阻止這種情況,并防止任何漏洞。但最終它們并不像使用不易被注射的替代方法那么簡單。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/527131.html
標籤:Python熊猫
