如何在python数据类的默认参数中访问另一个参数?

时间:2018-10-16 14:20:52

标签: python python-3.7 python-dataclasses

我正在尝试从id_导出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

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

3 个答案:

答案 0 :(得分:1)

您可以使用编写__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)

答案 1 :(得分: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是不够的。

答案 2 :(得分:0)

您需要使用constructor( injector: Injector, private _http: Http, private _workItemsServiceProxy: WorkItemsServiceProxy, private params: ActivatedRoute ) { super(injector); this.params.params.subscribe(() => { var paramId = params.snapshot.params["id"]; if (paramId) { this.initiativeFilter = paramId; this.nameFilter = 'strategy.id=' + this.initiativeFilter; } }); } 的{​​{1}}功能。

例如,

__init__

不过,在这里,用户必须为两者传递一个值。您可以简单地提供classclass 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 或一些虚假的值,以便将其传递并且不会引发ValueError。