编辑:为清楚起见,我需要一个class
来接受许多参数,我知道将提供所有参数,但有些参数可能以None
的形式传递,在这种情况下,我的{ {1}}必须提供默认值。
我想用一些默认值来设置一个简单的class
:
dataclass
我希望能够获得第二个字段的默认值,但仍要为第三个字段设置一个值。我无法使用None来完成此操作,因为它很乐意被接受为我的字符串的值:
@dataclass
class Specs1:
a: str
b: str = 'Bravo'
c: str = 'Charlie'
我想出了以下解决方案:
r1 = Specs1('Apple', None, 'Cherry') # Specs1(a='Apple', b=None, c='Cherry')
似乎表现出预期的行为:
@dataclass
class Specs2:
def_b: ClassVar = 'Bravo'
def_c: ClassVar = 'Charlie'
a: str
b: str = def_b
c: str = def_c
def __post_init__(self):
self.b = self.def_b if self.b is None else self.b
self.c = self.def_c if self.c is None else self.c
但是,我觉得这很丑陋,也许我在这里错过了一些东西。我的实际班级会有更多字段,因此只会变得更难看。
编辑:我应该补充一点,传递给该类的参数不包含任何内容,并且我对此方面没有控制权。
答案 0 :(得分:2)
这是另一种解决方案。
定义DefaultVal
和NoneRefersDefault
类型:
from dataclasses import dataclass, fields
@dataclass
class DefaultVal:
val: Any
@dataclass
class NoneRefersDefault:
def __post_init__(self):
for field in fields(self):
# if a field of this data class defines a default value of type
# `DefaultVal`, then use its value in case the field after
# initialization has either not changed or is None.
if isinstance(field.default, DefaultVal):
field_val = getattr(self, field.name)
if isinstance(field_val, DefaultVal) or field_val is None:
setattr(self, field.name, field.default.val)
用法:
@dataclass
class Specs3(NoneRefersDefault):
a: str
b: str = DefaultVal('Bravo')
c: str = DefaultVal('Charlie')
r3 = Specs3('Apple', None, 'Cherry') # Specs3(a='Apple', b='Bravo', c='Cherry')
编辑:重写NoneRefersDefault
使得以下操作也可以实现:
@dataclass
r3 = Specs3('Apple', None) # Specs3(a='Apple', b='Bravo', c='Charlie')
答案 1 :(得分:1)
我了解您只需要位置参数。这可以通过在线条件(出于代码可读性)来实现。
class Specs():
def __init__(self, a=None,b=None,c=None):
self.a = a if a is not None else 'Apple'
sefl.b = b if b is not None else 'Bravo'
self.c = c if c is not None else 'Cherry'
example = Specs('Apple', None, 'Cherry')
如果您愿意的话,可以不用 init 方法来完成此方法。
但是,您可以考虑使用具有命名参数的 __ init __()方法。
class Specs():
def __init__(self, a = 'Apple', b = 'Bravo', c = 'Cherry'):
self.a = a
self.b = b
self.c = c
example = Specs('Apple', c = 'Cherry')
答案 2 :(得分:1)
简单的解决方案是仅在 __post_init__()
中实现默认参数!
@dataclass
class Specs2:
a: str
b: str
c: str
def __post_init__(self):
if self.b is None:
self.b = 'Bravo'
if self.c is None:
self.c = 'Charlie'
(代码没有经过测试。如果我有一些细节错误,那不是第一次)
答案 3 :(得分:0)
使用基于键的参数。您可以只做r2 = Specs1('Apple', c='Cherry')
。您不必使用无。请参阅here。
输出:
Specs1(a='Apple', b='Bravo', c='Cherry')
答案 4 :(得分:0)
不太清楚您要对班级做什么。这些默认值应该不是属性吗?
也许您需要类使用的定义具有默认参数,例如:
def printMessage(name, msg = "My name is "):
print("Hello! ",msg + name)
printMessage("Jack")
同样的情况适用于类。
关于“无”的类似辩论可以在这里找到:Call function without optional arguments if they are None
答案 5 :(得分:0)
在数据类中,您可以访问类属性的默认值:Specs.b 如果需要,您可以检查 None 并传递默认值
代码:
dataclasses.dataclass()
class Specs1:
a: str
b: str = 'Bravo'
c: str = 'Charlie'
a = 'Apple'
b = None
c = 'Potato'
specs = Specs1(a=a, b=b or Specs1.b, c=c or Specs1.c)
>>> specs
Specs1(a='Apple', b='Bravo', c='Potato')