为了账号安全,请及时绑定邮箱和手机立即绑定

如何删除数据类属性

如何删除数据类属性

慕森卡 2022-06-07 19:23:18
我有一个这样的数据类:@dataclassclass 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:    ...@dataclassclass 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之后可以使用的方式从数据类对象中动态删除属性?
查看完整描述

2 回答

?
守着星空守着你

TA贡献1799条经验 获得超8个赞

这不是您关于从数据类中删除属性的问题的答案,但它提供了一种机制来获取以asdict您想要的方式运行的自定义:


from dataclasses import dataclass

from typing import Optional, Dict, cast


SENTINEL = cast(None, object())  # have a sentinel that pretends to be 'None'



@dataclass

class Bla:

    arg1: Optional[int] = SENTINEL

    arg2: Optional[str] = SENTINEL

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


    def asdict(self):

        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>


查看完整回答
反对 回复 2022-06-07
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

我的问题是关于如何以dataclasses.dataclass我可以使用该函数dataclasses.asdict生成字典的方式从对象中删除属性。


我的用例是很多模型,我想以易于序列化和类型提示的方式存储它们,但有可能省略元素(没有任何默认值)。我的第一种方法是找出一种方法来删除我没有在dataclass构造函数中明确传递的任何项目。


然而,正如Patrick 和 Arne 明智地指出的那样,尝试使用dataclasses.


我发现解决我的用例的最佳方法是TypedDict从typing_extensions模块中使用,它与PEP 589一起成为Python 3.8typing模块中标准库的一部分。


在 Python 3.8 中:


from typing import TypedDict, Dict


class Bla(TypedDict):

    arg1: int

    arg2: str

    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还不支持默认值。有一个公关,我希望他们能做点什么。


查看完整回答
反对 回复 2022-06-07
  • 2 回答
  • 0 关注
  • 170 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信