pythonjson库dumps方法仅将单个列表的空列表显示为空数组

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

我正在使用json.dumps转储我创建的类。有两个列表数据成员,一个从不使用,但一个用于管理另一个数据成员列表的构建。生成的JSON中不存在从未使用过的列表,但即使我从这些对象列表中的每个对象实例中清除了已使用的列表,也会添加已使用的列表。我不希望JSON中出现这个空列表

在返回要传递给转储的列表之前,我要执行以下操作

 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中看到的。