【问题标题】:How to assign Python Dict Keys to corresponding Python Object Attributes如何将 Python 字典键分配给相应的 Python 对象属性
【发布时间】:2020-12-21 15:46:04
【问题描述】:

假设我有一个类似的python类:

class User:
    name = None
    id = None
    dob = None
    
    def __init__(self, id):
        self.id = id

现在我正在做这样的事情:

userObj = User(id=12) # suppose I don't have values for name and dob yet
## some code here and this code gives me name and dob data in dictionary, suppose a function call
user = get_user_data() # this returns the dictionary like {'name': 'John', 'dob': '1992-07-12'}

现在,将数据分配给用户对象的方法是userObj.name = user['name']userObj.dob = user['dob']。假设,用户有 100 个属性。我将不得不明确分配这些属性。 Python中有没有一种有效的方法可以用来将字典中的值分配给对象中的相应属性?就像,字典中的name 键被分配给对象中的name 属性。

【问题讨论】:

  • 您只是想将字典键设置为类中已经存在的变量,还是尝试在类中创建变量?因为动态创建变量绝对是错误的做法。如果你只是想设置变量值,那我们可以讨论一下。
  • 我正在为已经存在的类变量设置值。

标签: python python-object


【解决方案1】:

1.修改类定义

类用户():
    def __init__(self, id):
        self.data = {"id":id}
userObj = User(id=12)

2. 更新dict()

user = {"name":"Frank", "dob":"Whatever"} # 从别处获取剩余数据
userObj.data.update(user) # 更新你的 userObj 中的字典
打印(userObj.data)
干得好 !

【讨论】:

    【解决方案2】:

    而不是将字典映射到变量键。您可以使用setattr 在对象中设置变量。

    class User:
        name = None
        id = None
        dob = None
    
        def __init__(self, id):
            self.id = id
    
        def map_dict(self, user_info):
            for k, v in user_info.items():
                setattr(self, k, v)
    
    

    然后让锅炉代码使用它。

    
    userObj = User(id=12)
    user_dict = {
        'name': 'Bob',
        'dob': '11-20-1993',
        'something': 'blah'
    }
    
    userObj.map_dict(user_dict)
    

    【讨论】:

      【解决方案3】:

      首先,python中不需要预先声明属性。

      class Foo:
         bar: int # This actually creates a class member, not an instance member
         ...
      

      如果您想向类实例添加值,只需使用 setattr()

      d = {
        'prop1': 'value1',
        'prop2': 'value2',
        'prop2': 'value2'
      }
      
      x = Foo()
      
      for prop in d.keys():
        setattr(x, prop, d[prop])
      

      【讨论】:

      • 这就像调用 init 方法。我不想。我想在创建用户实例后分配值(更新实例)
      【解决方案4】:
      class User(dict):
          def __init__(self, *args, **kwargs):
              super(User, self).__init__(*args, **kwargs)
              self.__dict__ = self
      

      然后拿起你的字典然后做:

      userObj  = User(dictionary)
      

      编辑: 然后使用函数setattr()

      [setattr(userObj, key, item) for key,item in dict.items()]
      

      【讨论】:

      • 就像调用__init__方法一样。我不想。我想在创建用户实例后分配值(更新实例)。
      【解决方案5】:

      如果你真的需要

      此解决方案适用于这种情况,其他解决方案不适合您,您无法更改班级。

      问题

      如果你不能以任何方式修改你的类并且你有一个字典,其中包含你想要放入你的对象的信息,你可以首先使用 inspect 获取你的类的自定义成员强> 模块:

      import inspect
      import numpy as np
      members = inspect.getmembers(User)
      

      通过以下方式从所有成员中提取您的自定义属性:

      allowed = ["__" not in a[0] for a in members]
      

      并为提取本身使用 numpy 列表理解:

      members = np.array(members)["__" not in a[0] for a in members]
      

      修改用户

      假设您有以下用户和字典,并且您想将用户属性更改为字典中的值(创建新用户的行为相同)

      user = User(1)
      dic = {"name":"test", "id": 2, "dob" : "any"}
      

      那么你只需使用setattr():

      for m in members:
      setattr(user, m[0], dic[m[0]])
      

      当然有更好的解决方案,但如果其他事情不适合你,这可能会派上用场

      更新

      此解决方案使用基于您使用的类的属性定义。因此,如果字典缺少值,此解决方案可能会有所帮助。其他 Rashids 解决方案也适用于您

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-15
        相关资源
        最近更新 更多