从3.0开始,只支持创建一个参数关键字:
class S3Obj:
def __init__(self, bucket, key, *, storage_class='Standard'):
self.bucket = bucket
self.key = key
self.storage_class = storage_class
Run Code Online (Sandbox Code Playgroud)
如何使用数据类获得这种签名?像这样的东西,但最好没有SyntaxError:
@dataclass
class S3Obj:
bucket: str
key: str
*
storage_class: str = 'Standard'
Run Code Online (Sandbox Code Playgroud)
理想情况下是声明性的,但是使用__post_init__钩子和/或替换类装饰器也很好 - 只要代码是可重用的.
编辑:可能是这样的语法,使用省略号文字
@mydataclass
class S3Obj:
bucket: str
key: str
...
storage_class: str = 'Standard'
Run Code Online (Sandbox Code Playgroud) 给定以下 Python 数据类层次结构:
@dataclass
class A:
a: str
aa: str
@dataclass
class B(A):
b: str
@dataclass
class C(A):
c: str
@dataclass
class D(B, C):
d: str
Run Code Online (Sandbox Code Playgroud)
是否有任何通用方法允许您在此继承层次结构中插入具有默认值的属性?例如,以下内容会产生Non-default argument(s) follows default argument(s) defined in 'B'class 错误D。
@dataclass
class A:
a: str
aa: str
@dataclass
class B(A):
b: str = 'b' # <-- default value
@dataclass
class C(A):
c: str
@dataclass
class D(B, C):
d: str
Run Code Online (Sandbox Code Playgroud)
我想一种解决方案可能是为层次结构中的所有属性提供默认值None,并添加一个__post_init__()验证,如果任何属性为 ,则会引发一些异常None,但这似乎不正确,并且您在层次结构中的每个数据类中都需要它。
Python 3.7 数据类中的类继承提出了一种解决方案,您可以在继承层次结构中创建两个独立的分支;一种用于默认值,另一种不使用。这里的缺点是层次结构很快就会被很多类弄乱,但如果没有更好的选择,我想这已经是最好的了。 …
from typing import Optional
@dataclass
class Event:
id: str
created_at: datetime
updated_at: Optional[datetime]
#updated_at: datetime = field(default_factory=datetime.now) CASE 1
#updated_at: Optional[datetime] = None CASE 2
@dataclass
class NamedEvent(Event):
name: str
Run Code Online (Sandbox Code Playgroud)
创建事件实例时,我通常不会有updated_at字段。current time在数据库中进行插入时,我可以传递作为默认值或添加一个值,并在对象的后续使用中获取它。哪种方法更好?根据我的理解,我无法在不通过case1 和 case2 中的 updated_at字段的NamedEvent情况下创建实例,因为我在 name 字段中没有默认值。
Mypy 会因该数据类继承而产生错误:
import dataclasses
import datetime
import typing
@dataclasses.dataclass
class Crud:
creation_datetime: typing.Optional[datetime.datetime] = dataclasses.field(init=False)
def __post_init__(self) -> None:
self.creation_datetime = getattr(self, "creation_datetime", datetime.datetime.utcnow())
@dataclasses.dataclass
class MyFoo(Crud):
name: str
Run Code Online (Sandbox Code Playgroud)
t.py:17: error: Attributes without a default cannot follow attributes with one
Run Code Online (Sandbox Code Playgroud)
是否存在抑制此错误或以不同方式设计代码以避免 mypy 错误的方法?
我创建了两个数据类来处理表元数据。TableMetadata适用于任何类型的表,同时RestTableMetadata包含与从 REST api 提取的数据相关的信息
@dataclass
class TableMetadata:
"""
- entity: business entity represented by the table
- origin: path / query / url from which data withdrawn
- id: field to be used as ID (unique)
- historicity: full, delta
- upload: should the table be uploaded
"""
entity: str
origin: str
view: str
id: str = None
historicity: str = "full"
upload: bool = True
columns: list = field(default_factory=list)
@dataclass
class RestTableMetadata(TableMetadata):
"""
- …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个由继承的数据类组成的 Python 3.7 数据类:
from dataclasses import dataclass
@dataclass
class A:
title: str
synopsis: str = "A book"
@dataclass
class B:
id: str
description: str = "A short book about something"
@dataclass()
class C(A, B):
provider: str
c = C(title="Trainspotting")
Run Code Online (Sandbox Code Playgroud)
这将引发以下异常:
Traceback (most recent call last):
File "tests/test.py", line 14, in <module>
class C(A, B):
File "lib/python3.7/dataclasses.py", line 958, in wrap
return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
File "lib/python3.7/dataclasses.py", line 879, in _process_class
else 'self',
File "lib/python3.7/dataclasses.py", line …Run Code Online (Sandbox Code Playgroud) 我遇到一种情况,我希望能够将冻结的dataclass实例视为始终拥有最新数据。或者换句话说,我希望能够检测数据类实例是否已replace调用它并抛出异常。它还应该仅适用于该特定实例,以便相同类型的其他数据类实例的创建/替换不会相互影响。
这是一些示例代码:
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class AlwaysFreshData:
fresh_data: str
def attempt_to_read_stale_data():
original = AlwaysFreshData(fresh_data="fresh")
unaffected = AlwaysFreshData(fresh_data="not affected")
print(original.fresh_data)
new = replace(original, fresh_data="even fresher")
print(original.fresh_data) # I want this to trigger an exception now
print(new.fresh_data)
Run Code Online (Sandbox Code Playgroud)
这里的想法是防止意外突变和从我们的数据类对象中读取过时的内容,以防止错误。
可以这样做吗?通过基类还是其他方法?
编辑:这里的目的是有一种强制/验证数据类的“所有权”语义的方法,即使它只是在运行时。
这是常规数据类有问题的情况的具体示例。
@dataclass
class MutableData:
my_string: str
def sneaky_modify_data(data: MutableData) -> None:
some_side_effect(data)
data.my_string = "something else" # Sneaky string modification
x = MutableData(my_string="hello")
sneaky_modify_data(x)
assert x.my_string == "hello" # as a caller of …Run Code Online (Sandbox Code Playgroud)