属性错误:'list'对象没有属性'get'?

5

这是脚本

def validate_record_schema(record):
        device = record.get('Payload', {})
        manual_added= device.get('ManualAdded', None)
        location = device.get('Location', None)
        if isinstance(manual_added, dict) and isinstance(location, dict):
            if 'Value' in manual_added and 'Value' in location:
                return False
        return isinstance(manual_added, bool) and isinstance(location, str)

    print([validate_record_schema(r) for r in data])

这是JSON数据

data = [{
        "Id": "12",
        "Type": "DevicePropertyChangedEvent",
        "Payload": [{
            "DeviceType": "producttype",
            "DeviceId": 2,
            "IsFast": false,
            "Payload": {
                "DeviceInstanceId": 2,
                "IsResetNeeded": false,
                "ProductType": "product",
                "Product": {
                    "Family": "home"
                },
                "Device": {
                    "DeviceFirmwareUpdate": {
                        "DeviceUpdateStatus": null,
                        "DeviceUpdateInProgress": null,
                        "DeviceUpdateProgress": null,
                        "LastDeviceUpdateId": null
                    },
                    "ManualAdded": {
                    "value":false
                    },
                    "Name": {
                        "Value": "Jigital60asew",
                        "IsUnique": true
                    },
                    "State": null,
                    "Location": {
                    "value":"bangalore"
                   },
                    "Serial": null,
                    "Version": "2.0.1.100"
                }
            }
        }]
    }]

对于这行代码:device = device.get('ManualAdded', None),我遇到了以下错误:AttributeError: 'list' object has no attribute 'get'. 请看一下并帮助我解决这个问题。
我错在哪里了...
如何修复这个错误?
请帮助我解决这个问题。

看数据结构,"Payload": [...] 这是一个字典列表。 - tdelaney
1
@tdelaney,我该怎么解决这个问题?请帮帮我。 - nrs
你已经有了解决问题的答案......我只是在补充为什么。这是一个列表,所以你需要处理列表中的项目。你可以像下面建议的那样获取第一个元素,或者将整个列表放入for循环中以处理所有字典。 - tdelaney
我是Python的新手...你能修改我的函数吗?拜托了...我不知道该怎么做。 - nrs
2个回答

3
您在遍历数据时跟踪类型时遇到了问题。一个技巧是添加调试打印,以查看发生了什么。例如,顶部的“Payload”对象是一个字典列表,而不是单个字典。列表意味着您可以拥有多个设备描述符,因此我编写了一个检查它们所有并在途中发现问题时返回False的示例。您可能需要根据验证规则更新此内容,但这将为您提供起点。
def validate_record_schema(record):
    """Validate that the 0 or more Payload dicts in record
    use proper types"""
    err_path = "root"
    try:
        for device in record.get('Payload', []):
            payload = device.get('Payload', None)
            if payload is None:
                # its okay to have device without payload?
                continue
            device = payload["Device"]
            if not isinstance(device["ManualAdded"]["value"], bool):
                return False
            if not isinstance(device["Location"]["value"], str):
                return False
    except KeyError as e:
        print("missing key")
        return False

    return True

1
非常感谢您的帮助,我已经卡了两天了。非常感谢! - nrs

2

正如错误提示所示,您不能在列表上使用.get()方法。要获取位置和手动添加字段,您可以使用以下方法:

manual_added = record.get('Payload')[0].get('Payload').get('Device').get('ManualAdded')
location = record.get('Payload')[0].get('Payload').get('Device').get('Location')

所以你的函数将变为:
def validate_record_schema(record):
    manual_added = record.get('Payload')[0].get('Payload').get('Device').get('ManualAdded')
    location = record.get('Payload')[0].get('Payload').get('Device').get('Location')

    if isinstance(manual_added, dict) and isinstance(location, dict):
        if 'Value' in manual_added and 'Value' in location:
        return False
    return isinstance(manual_added, bool) and isinstance(location, str)

请注意,这将设置位置为:
{
    "value":"bangalore"
}

并手动添加到

{
    "value":false
}

请问您能否在同一个函数中进行修改? - nrs
我已经扩展了答案,包括在您的函数中的上下文。 - Ollie
非常感谢您的宝贵帮助,我已经卡了两天了。非常感谢! - nrs
现在我得到了“str对象没有属性'get'” - AnonymousUser
@AnonymousUser 我建议您创建一个新问题,并提供更多详细信息。 - Ollie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接