【问题标题】:Is there a more efficient way of storing keyword arguments?有没有更有效的存储关键字参数的方法?
【发布时间】:2021-05-07 02:51:06
【问题描述】:

这是我的代码:

def formateUserData(FirstName = None, MiddleName = None, LastName = None, DOB = None, Gender = None):
    formatedUserData = {}
    dataFieldKeys = ['First Name', 'Middle Name', 'Last Name', 'DOB', 'Gender']
    dataFieldValues = [FirstName, MiddleName, LastName, DOB, Gender]

    for key, value in zip(dataFieldKeys, dataFieldValues):
        if value: formatedUserData[key] = value

    return formatedUserData

如您所见,关键字参数必须重复 3 次(第 1 行第一次,第 3 行第二次,第 4 行第三次)。有没有办法只存储一次关键字参数就可以做同样的事情?如果可能的话,也许通过使用某种方式遍历关键字参数?顺便说一句,我不想​​使用 **kwargs。

【问题讨论】:

  • 查看locals() 或此处提到的其他答案:stackoverflow.com/questions/582056/…
  • 您可以传递一个包含多个参数的对象,然后对其属性进行迭代
  • 这里通常的方法是升级抽象,创建一个具有这些字段属性的模型类。然后,当您调用此函数时,您只需传递一个实例 user

标签: python python-3.x performance functional-programming dry


【解决方案1】:

也许这个草稿会激发您考虑我觉得非常方便的数据类

from dataclasses import dataclass, fields
from datetime import date
from typing import Literal, Optional

@dataclass
class User:
    first_name: Optional[str] = None
    middle_name: Optional[str] = None
    last_name: Optional[str] = None
    dob: Optional[date] = None
    gender: Optional[Literal['male', 'female']] = None


def not_none_dict(user: User) -> dict:
    not_none = {}
    for field in fields(user):
        value = getattr(user, field.name)
        if value:
            not_none[field.name] = value
    return not_none

print(
    not_none_dict(User(
        first_name='Joe',
        last_name='Doe'
    ))
)
>>> {'first_name': 'Joe', 'last_name': 'Doe'}

【讨论】:

    【解决方案2】:

    在我看来,最短的解决方案是使用 locals():

    def formateUserData2(FirstName = None, MiddleName = None, LastName = None, DOB = None, Gender = None):
        return {k:v for k,v in locals().items() if v}
    

    但是这个方案没有考虑标签的变化,所以需要绑定

    def formateUserData(FirstName = None, MiddleName = None, LastName = None, DOB = None, Gender = None):
        binding = {'First Name':FirstName, 
                   'Middle Name':MiddleName,
                   'Last Name':LastName,
                   'DOB':DOB,
                   'Gender':Gender}
        return {k:v for k,v in binding.items() if v}
    

    使用显式绑定是一种很好的做法,因为它阐明了您的期望。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      相关资源
      最近更新 更多