pythonjson库dumps方法仅将单个列表的空列表显示为空数组
我正在使用json.dumps转储我创建的类。有两个列表数据成员,一个从不使用,但一个用于管理另一个数据成员列表的构建。生成的JSON中不存在从未使用过的列表,但即使我从这些对象列表中的每个对象实例中清除了已使用的列表,也会添加已使用的列表。我不希望JSON中出现这个空列表 在返回要传递给转储的列表之前,我要执行以下操作pythonjson库dumps方法仅将单个列表的空列表显示为空数组,python,json,python-3.x,Python,Json,Python 3.x,我正在使用json.dumps转储我创建的类。有两个列表数据成员,一个从不使用,但一个用于管理另一个数据成员列表的构建。生成的JSON中不存在从未使用过的列表,但即使我从这些对象列表中的每个对象实例中清除了已使用的列表,也会添加已使用的列表。我不希望JSON中出现这个空列表 在返回要传递给转储的列表之前,我要执行以下操作 for entry in self.endpointList: entry.attributeNameList.clear() 我也试着用我自己的JSONECOD
for entry in self.endpointList:
entry.attributeNameList.clear()
我也试着用我自己的JSONECODER清理。当我在调试器中查看attributeNameList成员时,它们会被清除,但它们是由转储以空数组的形式发出的。其他未触及的空列表从未显示
另一个区别是,不显示的空列表以相同的方式声明,但attributeNameList在我的类的\uuuu init\uuuu
方法中初始化
class ProvisioningEndpoint:
attributeList = []
attributeNameList = []
def __init__(self, record):
self.attributeNameList = list()
有没有办法防止将此特定的空列表转换为
"attributeNameList": []
attributeList从未添加到JSON输出中
从不使用的列表和清除的列表在调试器中看起来完全相同——为空。Python可能在列表中有一个脏的部分,并使用它来决定何时作为JSON发出。
谢谢
这是编码器代码(根据要求)
您的类有两个属性,它们是列表-attributeList
和AttributeNameList
类的实例将attributeNameList
作为一个属性,因为它是在_uuu_u_u_u_u方法中初始化的。此实例属性覆盖class属性
编码器正在序列化实例的_uuuuuuuuuuuuuuuuu中的所有内容,其中包括attributeNameList
。如果当self.attributeNameList为空时不想序列化,则需要在编码器中添加一些逻辑来处理此问题:例如:
class ServiceRegistryEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (ProvisioningEndpoint,endpointAttribute)):
obj = obj.__dict__.copy()
if not obj.get('attributeNameList):
try:
del obj['attributeNameList']
except KeyError:
pass
编辑:有关类属性的详细信息
当您试图访问实例上的属性foo
时,Python首先会查看实例的_uuu; dict。如果在那里找不到该属性,Python将查找实例的类的_u; dict _;。如果在那里找到属性,它将返回该属性。这意味着类属性在类的所有实例中共享。请参阅以了解更多关于此的信息
由于类属性在实例之间共享,对类属性的更改将对所有实例可见。这可能会导致意外或不良行为:
>>> class Emailer(object):
... recipients = ['default@example']
... def send_secret_email(self):
... # send secret email
... pass
...
>>> e1 = Emailer()
>>> e2 = Emailer()
>>> e1.recipients.append('alice@example.com')
>>> print(e1.recipients)
['default@example', 'alice@example.com']
>>> e2.recipients.append('bob@example.com')
>>> print(e2.recipients)
['default@example', 'alice@example.com', 'bob@example.com']
>>> print(e1.recipients)
['default@example', 'alice@example.com', 'bob@example.com']
在类似上述示例的情况下,您可以在_uu_u_u_u_u_u方法中复制该属性,以缓解这种情况
>>> class Emailer(object):
... recipients = ['default@example']
... def __init__(self):
... self.recipients = self.recipients.copy()
... def send_secret_email(self):
... # send secret email
... pass
...
>>> e1 = Emailer()
>>> e2 = Emailer()
>>> e1.recipients.append('alice@example.com')
>>> print(e1.recipients)
['default@example', 'alice@example.com']
>>> e2.recipients.append('bob@example.com')
>>> print(e2.recipients)
['default@example', 'bob@example.com']
>>> print(e1.recipients)
['default@example', 'alice@example.com']
正如@blackjack所观察到的,可变类属性通常是一种代码气味,但它们确实有一些用途:例如,如果一个类想要跟踪其实例。您的类有两个属性,它们是列表-attributeList
和AttributeNameList
类的实例将attributeNameList
作为一个属性,因为它是在_uuu_u_u_u_u方法中初始化的。此实例属性覆盖class属性
编码器正在序列化实例的_uuuuuuuuuuuuuuuuu中的所有内容,其中包括attributeNameList
。如果当self.attributeNameList为空时不想序列化,则需要在编码器中添加一些逻辑来处理此问题:例如:
class ServiceRegistryEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (ProvisioningEndpoint,endpointAttribute)):
obj = obj.__dict__.copy()
if not obj.get('attributeNameList):
try:
del obj['attributeNameList']
except KeyError:
pass
编辑:有关类属性的详细信息
当您试图访问实例上的属性foo
时,Python首先会查看实例的_uuu; dict。如果在那里找不到该属性,Python将查找实例的类的_u; dict _;。如果在那里找到属性,它将返回该属性。这意味着类属性在类的所有实例中共享。请参阅以了解更多关于此的信息
由于类属性在实例之间共享,对类属性的更改将对所有实例可见。这可能会导致意外或不良行为:
>>> class Emailer(object):
... recipients = ['default@example']
... def send_secret_email(self):
... # send secret email
... pass
...
>>> e1 = Emailer()
>>> e2 = Emailer()
>>> e1.recipients.append('alice@example.com')
>>> print(e1.recipients)
['default@example', 'alice@example.com']
>>> e2.recipients.append('bob@example.com')
>>> print(e2.recipients)
['default@example', 'alice@example.com', 'bob@example.com']
>>> print(e1.recipients)
['default@example', 'alice@example.com', 'bob@example.com']
在类似上述示例的情况下,您可以在_uu_u_u_u_u_u方法中复制该属性,以缓解这种情况
>>> class Emailer(object):
... recipients = ['default@example']
... def __init__(self):
... self.recipients = self.recipients.copy()
... def send_secret_email(self):
... # send secret email
... pass
...
>>> e1 = Emailer()
>>> e2 = Emailer()
>>> e1.recipients.append('alice@example.com')
>>> print(e1.recipients)
['default@example', 'alice@example.com']
>>> e2.recipients.append('bob@example.com')
>>> print(e2.recipients)
['default@example', 'bob@example.com']
>>> print(e1.recipients)
['default@example', 'alice@example.com']
正如@blackjack所观察到的,可变类属性通常是一种代码味道,但它们确实有一些用途:例如,如果一个类想要跟踪其实例。您能在编码器中显示处理实例属性的代码吗?您能在编码器中显示处理实例属性的代码吗?谢谢。因此,类属性,如果不在_uuu _uuu方法中设置,则不存在于实例中?@ThomasBentley类属性从不存在于实例中。如果在
\uuuu init\uuuu
中设置了具有相同名称的属性,则类中有一个class属性,实例中有一个具有相同名称的实例属性。不是常量的类属性通常是代码味道。谢谢Blackjack。它们类属性和实例属性将以相同的方式显示在调试器中,对吗?这就是我在pydev中看到的。谢谢。因此,类属性,如果不在_uuu _uuu方法中设置,则不存在于实例中?@ThomasBentley类属性从不存在于实例中。如果在\uuuu init\uuuu
中设置了具有相同名称的属性,则类中有一个class属性,实例中有一个具有相同名称的实例属性。不是常量的类属性通常是代码味道。谢谢Blackjack。它们类属性和实例属性将以相同的方式显示在调试器中,对吗?这就是我在pydev中看到的。