简体   繁体   English

如何在Python中将字典列表转换为自定义对象

[英]How to convert dictionary list to custom objects in Python

I have a list which has some dictionaries to be bulk uploaded. 我有一个列表,其中包含一些要批量上传的字典。 I need to check if elements of list can be cast to a custom object(as below). 我需要检查list的元素是否可以强制转换为自定义对象(如下所示)。 Is there any elegant way to do it like type comparison? 有没有像类型比较这样的优雅方法呢?

This is my model 这是我的模特

class CheckModel(object):

    def __init__(self,SerialNumber,UID, Guid = None,Date = None):
        self.SerialNumber = SerialNumber
        self.UID = UID
        self.Guid = str(uuid.uuid4()) if Guid is None else Guid
        self.Date = datetime.now().isoformat() if Date is None else Date

And this is my test data. 这是我的测试数据。 How can I cast only first element(because first element is the only correct one.) of this list into CheckModel object? 我如何只能将此列表的第一个元素(因为第一个元素是唯一正确的元素)转换为CheckModel对象?

test = [{
        "Guid":"d0c035a7-0e01-4a37-8fe9-251fb5633fc9",
        "SerialNumber":"1716154A",
        "UID":"F13BDB3B",
        "Date":"2019-12-03T13:50:19.882Z"

    },
    {
        "Guid":"d0585-0e01-4a47-8fe9-251245f33fc9",
        "SerialNumber":"1716154A",
        "Date":"2019-12-03T13:50:19.882Z"
    },
    {
        "Guid":"12414a7-0e01-4a47-8fe9-251245f33fc9",
        "SerialNumber":"1716154A",
        "UID":"F13BDB3B",
        "Date":"2019-12-03"
    }]

You can create a custom cleanup function and then use filter 您可以创建一个自定义清除功能,然后使用filter

Ex: 例如:

import datetime
import uuid

class CheckModel(object):

    def __init__(self,SerialNumber,UID, Guid = None,Date = None):
        self.SerialNumber = SerialNumber
        self.UID = UID
        self.Guid = str(uuid.uuid4()) if Guid is None else Guid
        self.Date = datetime.datetime.now().isoformat() if Date is None else Date

#Clean Up Function.             
def clean_data(data):
    if all(key in data for key in ("Guid", "SerialNumber", "UID", "Date")):
        try:
            datetime.datetime.strptime(data["Date"], "%Y-%m-%dT%H:%M:%S.%fZ")
            return True
        except:
            pass
    return False 


test = [{
        "Guid":"d0c035a7-0e01-4a37-8fe9-251fb5633fc9",
        "SerialNumber":"1716154A",
        "UID":"F13BDB3B",
        "Date":"2019-12-03T13:50:19.882Z"

    },
    {
        "Guid":"d0585-0e01-4a47-8fe9-251245f33fc9",
        "SerialNumber":"1716154A",
        "Date":"2019-12-03T13:50:19.882Z"
    },
    {
        "Guid":"12414a7-0e01-4a47-8fe9-251245f33fc9",
        "SerialNumber":"1716154A",
        "UID":"F13BDB3B",
        "Date":"2019-12-03"
    }]

model_data = [CheckModel(**data) for data in filter(clean_data, test)]
print(model_data)

Output: 输出:

[<__main__.CheckModel object at 0x0000000002F0AFD0>]

由于您已经拥有CheckModel类的初始化程序,因此您应该能够将dict中的值传递给此函数:

check_model = CheckModel(test[0]['SerialNumber'], test[0]['UID'], test[0]['Guid'], test[0]['Date'])

If you just want the first one, you can use **kwargs to unpack a dictionary as a mapping into your __init__ 如果只想要第一个字典,则可以使用**kwargs将字典解压缩为__init__的映射

some_object = CheckModel(**test[0])

However, this will only work if all of the keys are available as arguments of the function. 但是,这仅在所有键都可用作函数的参数时才有效。 This will raise an exception if you try this with test[1] , since the UID arg will be missing 如果您使用test[1]尝试此操作,则会引发异常,因为UID arg将丢失

Use **kwargs to pass the dictionary as an argument to the constructor, which will unpack the dictionary as a list of argument 使用**kwargs将字典作为参数传递给构造函数,该函数会将字典解压缩为参数列表

In addition, I would suggest making UID=None since UID was missing in one of the dictionaries of the list. 另外,我建议做UID=None ,因为UID是在失踪名单的字典之一。 Below will parse all elements of list into the Class 下面将把列表的所有元素解析到Class中

import datetime as datetime

class CheckModel(object):

    #Made UID None since it is not present in one of the dictionaries
    def __init__(self,SerialNumber,UID=None, Guid = None,Date = None):
        self.SerialNumber = SerialNumber
        self.UID = UID
        self.Guid = str(uuid.uuid4()) if Guid is None else Guid
        self.Date = datetime.now().isoformat() if Date is None else Date

test = [{
        "Guid":"d0c035a7-0e01-4a37-8fe9-251fb5633fc9",
        "SerialNumber":"1716154A",
        "UID":"F13BDB3B",
        "Date":"2019-12-03T13:50:19.882Z"

    },
    {
        "Guid":"d0585-0e01-4a47-8fe9-251245f33fc9",
        "SerialNumber":"1716154A",
        "Date":"2019-12-03T13:50:19.882Z"
    },
    {
        "Guid":"12414a7-0e01-4a47-8fe9-251245f33fc9",
        "SerialNumber":"1716154A",
        "UID":"F13BDB3B",
        "Date":"2019-12-03"
    }]

models = []

for item in test:
    #Use **kwargs to pass dictionary as arguments to constructor
    models.append(CheckModel(**item))
print(models)

To just create the object of first item in the list, do 要仅创建列表中第一项的对象,请执行

CheckModel(**test[0])

This should give you access to the first element of the list and then you can parse out the dictionary as necessary. 这应该使您可以访问列表的第一个元素,然后可以根据需要解析字典。

elem = check_model[0]

# Use the get() function on a dictionary to get the value of key without 
# breaking the code if the key doesn't exist
guid = elem.get('Guid')
serial_number = elem.get('SerialNumber')
uid = elem.get('UID')
date = elem.get('Date')

instance = CheckModel(serial_number, uid, Guid=guid, Date=date)

# Do something with it
instance.do_something()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM