如何删除数据类属性

我有一个这样的数据类:


@dataclass

class Bla:

    arg1: Optional[int] = None

    arg2: Optional[str] = None

    arg3: Optional[Dict[str, str]] = None

我想要这种行为:


>>> bla = Bla(arg1=None, arg2=None, arg3=None)

>>> asdict(bla)

{'arg1': None, 'arg2': None, 'arg3': None}


>>> bla = Bla()

{}

在这种特定情况下,我可以使用 a dict,但我会失去拥有类型提示的可能性(并使用 mypy)


所以我尝试了这个:


class none:

    ...


@dataclass

class Bla:

    arg1: Union[none, int] = none()

    arg2: Union[none, str] = none()

    arg3: Union[none, Dict[str, str]] = none()


    def __post_init__(self) -> None:

        for k, v in self.__dict__.copy().items():

            if isinstance(v, none):

                delattr(self, k)

但结果是:


>>> asdict(Bla())

{'arg1': <__main__.none object at 0x7f71bc0159b0>, 'arg2': <__main__.none object at 0x7f71bc015a90>, 'arg3': <__main__.none object at 0x7f71bc015ac8>}

我期待一个空的dict


如果尝试:


>>> a = Bla(None, None, None)

>>> del a.__dict__["arg1"]

>>> asdict(a)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "/home/(....)/venv/lib/python3.6/site-packages/dataclasses.py", line 1011, in asdict

    return _asdict_inner(obj, dict_factory)

  File "/home/(...)/venv/lib/python3.6/site-packages/dataclasses.py", line 1018, in _asdict_inner

    value = _asdict_inner(getattr(obj, f.name), dict_factory)

AttributeError: 'Bla' object has no attribute 'arg1'

如何以asdict之后可以使用的方式从数据类对象中动态删除属性?


慕森卡
浏览 171回答 2
2回答

守着星空守着你

这不是您关于从数据类中删除属性的问题的答案,但它提供了一种机制来获取以asdict您想要的方式运行的自定义:from dataclasses import dataclassfrom typing import Optional, Dict, castSENTINEL = cast(None, object())&nbsp; # have a sentinel that pretends to be 'None'@dataclassclass Bla:&nbsp; &nbsp; arg1: Optional[int] = SENTINEL&nbsp; &nbsp; arg2: Optional[str] = SENTINEL&nbsp; &nbsp; arg3: Optional[Dict[str, str]] = SENTINEL&nbsp; &nbsp; def asdict(self):&nbsp; &nbsp; &nbsp; &nbsp; return {k: v for k, v in self.__dict__.items() if v is not SENTINEL}一些测试:>>> Bla().asdict(){}>>> Bla(None, None).asdict(){'arg1': None, 'arg2': None}>>> Bla(1, 'foo', None).asdict(){'arg1': 1, 'arg2': 'foo', 'arg3': None}但请记住,这一切都是谎言,当显式调用时,这些属性仍然存在:>>> print(Bla().arg1)<object object at 0x7fc89ed84250>

哆啦的时光机

我的问题是关于如何以dataclasses.dataclass我可以使用该函数dataclasses.asdict生成字典的方式从对象中删除属性。我的用例是很多模型,我想以易于序列化和类型提示的方式存储它们,但有可能省略元素(没有任何默认值)。我的第一种方法是找出一种方法来删除我没有在dataclass构造函数中明确传递的任何项目。然而,正如Patrick 和 Arne 明智地指出的那样,尝试使用dataclasses.我发现解决我的用例的最佳方法是TypedDict从typing_extensions模块中使用,它与PEP 589一起成为Python 3.8typing模块中标准库的一部分。在 Python 3.8 中:from typing import TypedDict, Dictclass Bla(TypedDict):&nbsp; &nbsp; arg1: int&nbsp; &nbsp; arg2: str&nbsp; &nbsp; arg3: Dict[str, str]在其他版本中,您必须安装typing_extensions模块:pip install typing-extensions然后:from typing_extensions import TypedDict我们试试看:>>> Bla(arg1=1, arg2="bla", arg3={"bla":"bla"}){'arg1': 1, 'arg2': 'bla', 'arg3': {'bla': 'bla'}}>>> Bla(arg1=1, arg2="bla"){'arg1': 1, 'arg2': 'bla'}>>> Bla(arg1=1){'arg1': 1}非常优雅,非常适合我的用例。唯一的缺点是TypedDict还不支持默认值。有一个公关,我希望他们能做点什么。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python