Che*_*hen 2 python python-dataclasses
如果我执行以下命令:
@dataclass
class Test:
hi: Optional[str] = field(
default_factory=lambda: str(uuid.uuid1()))
@dataclass
class Test2:
hi: Optional[str] = str(uuid.uuid1())
if __name__ == "__main__":
a = Test() # Test(hi='115a865c-33be-11eb-94a1-34c93db23648')
b = Test() # Test(hi='115a865d-33be-11eb-8c6f-34c93db23648')
c = Test2() # Test2(hi='10e44300-33be-11eb-85eb-34c93db23648')
d = Test2() # Test2(hi='10e44300-33be-11eb-85eb-34c93db23648')
Run Code Online (Sandbox Code Playgroud)
为什么Test会为每个实例返回不同的 uuid,而Test2每次都会返回相同的 uuid?
另外,为什么default factory需要而不需要default?
正如文档中所述
default_factory:如果提供,它必须是一个零参数可调用,当该字段需要默认值时将调用该可调用。除其他目的外,这可用于指定具有可变默认值的字段,如下所述。同时指定default 和default_factory 是错误的。
在你的第一个例子中
@dataclass
class Test:
hi: Optional[str] = field(
default_factory=lambda: str(uuid.uuid1()))
Run Code Online (Sandbox Code Playgroud)
您将匿名函数传递给默认工厂。
为了让事情变得更容易,让我们创建一个非匿名函数。
def get_new_uuid() -> str:
return str(uuid.uuid1())
@dataclass
class Test:
hi: Optional[uuid.UUID] = field(default_factory=get_new_uuid)
Run Code Online (Sandbox Code Playgroud)
因此,初始化时,每个实例都会Test调用get_new_uuid函数来获取新的 uuid。
您的第二个示例分配一个默认值。
@dataclass
class Test2:
hi: Optional[str] = str(uuid.uuid1())
Run Code Online (Sandbox Code Playgroud)
这相当于这个
@dataclass
class Test2:
hi: Optional[str] = field(default=str(uuid.uuid1()))
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这里default使用了参数,而以前是default_factory。在这里,您传递的不是函数,而是值。这是一次性的事情。
如果不实例化它就Test无法访问hi。但Test2在导入时分配了默认值,因此您无需实例化即可访问它。它类似于 中定义的类属性和实例属性__init__。