首页 > 解决方案 > 开箱**kwargs

问题描述

我正在做一个涉及大量使用 Pandas 进行数据库过滤的项目。所以我写了以下函数:

def filterList(df, dropL, col, criteria, reason="", strCont=False, isIN=False,
                   notEq=False, isEq=False, isNAN=False, isDup=False, useDropL=True, 
                   dropCol=False, dropColDropList=False, useDropReason=True):

    # make a mask
    if strCont:
        mask = df[col].str.contains(criteria)
    elif notEq:
        mask = df[col] != criteria
    elif isEq:
        mask = df[col] == criteria
    elif isNAN:
        mask = np.isnan(df[col])
    elif isIN:
        mask = df[col].isin(criteria)
    elif isDup:
        mask = df.duplicated(col, keep=False)
    else:
        print("you must specify how to make the mask")
        sys.exit()

    # fill the droplist
    if useDropL:
        dropL = dropL.append(df[mask]).fillna("")
        dropL.reset_index(drop=True, inplace=True)
        if useDropReason:
            dropL.loc[dropL["Reason Dropped"] == '', 'Reason Dropped'] = reason
        if dropColDropList:
            dropL.drop(col, axis='columns', inplace=True)

    # filter the list
    df_Filtered = df.drop(df[mask].index)
    df_Filtered.reset_index(drop=True, inplace=True)

    # special instructions
    if dropCol:
        df_Filtered.drop(col, axis='columns', inplace=True)

    return df_Filtered, dropL

它的设置使得我必须将布尔变量之一作为 true 传递,以便指定应如何将匹配条件与特定列进行比较。它还跟踪丢弃的项目并填写该项目被丢弃的原因(用于稍后的错误手动错误检查)。

我不想有这么长的声明声明。我的意思是,它有效,我只是觉得它看起来很丑。

所以我想我可以用它**kwargs来捕获所有的布尔值,然后只在其中查找变量名,但是我到处寻找如何做到这一点的地方都在说这是世界上最糟糕的主意。

给定的原因似乎围绕着不知道将传递哪些变量以及可能的变量名冲突。但我是唯一将编写或运行此代码的人,所以在这种情况下我不担心变量名冲突。

所以

  1. 我的情况是否可以接受直接将 kwarg 键转换为变量名?

  1. 如果是/不是,我将如何(否则)进行此操作?(我对kwargs一点都不熟悉,对字典也只是稍微熟悉,我理解kwargs就是)

标签: pythonpython-3.xpandaskeyword-argument

解决方案


没有解决您的特定用例,但有时需要有一个可以接受大量参数的函数,并且这些参数必须是具体的。使用kwargs并不是世界上最糟糕的想法,但它会产生两个你必须解决的问题:

  1. 将使用该函数的程序员/用户不会有任何关于该函数期望获得什么、可以传递什么值等的指示/文档。
  2. 如果对象中不存在默认参数,您必须自己设置默认参数kwargs,并且您还必须处理哪些项目是可选的,哪些是必需的。

话虽如此,可读性也是一个因素,您对大型声明的“丑陋”感到担忧是正确的。为了解决这个问题,我认为只是改变 decletation 的格式会更聪明。写这样的东西是完全可以接受的,而且更具可读性:

def filterList(df,
               dropL,
               col,
               criteria,
               reason="",
               strCont=False,
               isIN=False,
               notEq=False, 
               isEq=False, 
               isNAN=False,
               isDup=False,
               useDropL=True, 
               dropCol=False, 
               dropColDropList=False,
               useDropReason=True):

如果需要,这种格式甚至可以更容易地为每个变量添加注释或类型提示


推荐阅读