2

我正在尝试导出id_from的默认值,name反之亦然。

@dataclass
class Item:
    id_ = NAME_TO_ID[name]
    name = ID_TO_NAME[id_]

我应该能够像这样调用类:

Item(id_=123)
Item(name='foo')

id_如果可能的话,我还希望课程在同时提供和时引发错误name

Item(id_=123, name='foo')  # ValueError: id_ and name cannot be provided together

关于我应该如何去做的任何建议?

4

3 回答 3

2

您可以使用编写__post_init__方法来进行这些验证

from dataclasses import dataclass, field

@dataclass
class Item:
    id_: int = field(default=None)
    name: str = field(default=None)
    def __post_init__(self):
        if self.id_ is None and self.name is None:
            raise TypeError("You must provide exactly one of name or id_")
        if self.id_ is not None and self.name is not None:
            raise TypeError("You must provide exactly one of name or id_")
        if self.id_ is not None:
            self.name = id_to_name(self.id_)
        else:
            self.id_ = name_to_id(self.name)
于 2018-10-16T14:34:37.593 回答
0

像下面这样简单的东西对你有用吗?

在对象实例化时,检查是否提供了太多或太少的数据,然后定义一个在必要时将计算值的属性?

class Item ():
    def __init__(self, id: int =None, name:str= None):
        if all ([name, id]):
            raise ValueError ("id_ and name cannot be provided together")
        elif not any ([name, id]):
            raise ValueError ("name or id must be provided for Item instantiation")
        else:
            self._name = name
            self._id = id
    @property
    def name (self) -> str:
        if self._name is None:
            #Compute the value and return it
            pass #remove this once you figure out your algorithm
        else:
            return self._name
    @property
    def id (self) ->int:
        if self._id is None:
            #Compute the value and return it
            pass #remove this once you figure out your algorithm
       else:
           return self._id

请注意,您还必须考虑什么是有效值。0在我提供的示例案例中,如果您认为整数是有效的id,而空字符串""是有效的是不够的name

于 2018-10-16T14:34:30.897 回答
0

您需要__init__使用class.

例如,

class Item:
    # define __init__ such that it has a condition when both id_ and name are supplied
    # a ValueError is raised
    def __init__(self, id_, name=None):
        if (id_ and name):
            # raise error because both were supplied
            raise ValueError
        if (id_):
            # assign name and id
        elif (name):
            # assign name and id

但是,在这里,用户必须为两者传递一个值。您可以简单地提供FalseorNone或一些虚假值,以便传递它并且不会抛出 ValueError 。

于 2018-10-16T14:37:07.463 回答