Python-使用可选的键/值参数从JSON创建对象

Python-使用可选的键/值参数从JSON创建对象,python,json,Python,Json,尝试基于JSON格式中获得的名称/值对创建对象 e、 g 但是,名称/值可以是可选的。所以它也可以是这样的形式 json = {'name': 'saph', 'size': {'height': '4'} #'type' and 'height' have been omitted } 我试图 class Gem(object): def __init__(self, **params): self.name = para

尝试基于JSON格式中获得的名称/值对创建对象

e、 g

但是,名称/值可以是可选的。所以它也可以是这样的形式

json = {'name': 'saph',
        'size': {'height': '4'}
        #'type' and 'height' have been omitted
       }
我试图

class Gem(object):
    def __init__(self, **params):
        self.name = params['name']
        self.type = params['type']
        self.size = params['size']

gem = Gem(**json)
但它希望所有参数都可用

我希望最终能够访问对象的属性,例如

print(gem.name) #prints 'ruby'
print(gem.type) #prints 'rare'
使用带有默认值的
get()

self.type = params.get('type', '')
更新 实现这一点的一个更优雅的方法是使用包
attrs
cattrs
的组合。使用
pip
(CATTR的最低版本是重要的):

然后将类定义为
attrs
数据类(
cattrs
还不支持Python 3.7的标准数据类,这就是为什么我们使用
attrs
):

最后,要从字典构造一个实例(可能是从JSON解析的):


执行此操作时,您正试图访问未定义的键
type

这将抛出
KeyError

您可能需要使用:

self.type = params.get('type', '') #sets self.type to '' empty string
self.type = params.get('type') #sets self.type to None

我会首先检查键是否存在,如果没有将其保留为
None

如果
json
没有
name
条目,是否希望定义
gem.name
?如果是,默认值是多少?
pip install attrs
pip install 'cattrs>=1.0.0rc0'
In [1]: import attr

In [2]: import cattr

In [3]: @attr.s(auto_attribs=True) 
   ...: class Gem: 
   ...:     name: str = None 
   ...:     type: str = None  # Not a good name since it's a keyword, but I'm building upon the structure in the question
   ...:     size: str = None     
In [4]: cattr.structure({'name': 'saph', 
   ...:         'size': {'height': '4'} 
   ...:         #'type' and 'height' have been omitted 
   ...:        }, Gem)
Out[4]: Gem(name='saph', type=None, size="{'height': '4'}")
self.type = params.get('type', '') #sets self.type to '' empty string
self.type = params.get('type') #sets self.type to None
class Gem(object):
    def __init__(self, **params):
        self.name = params['name'] if 'name' in params else None
        self.type = params['type'] if 'type' in params else None
        self.size = params['size'] if 'size' in params else None

gem = Gem(**json)