在下面的代码中,该astuple函数正在执行数据类的类属性的深层复制。为什么它产生的结果与函数不同my_tuple?
import copy
import dataclasses
@dataclasses.dataclass
class Demo:
a_number: int
a_bool: bool
classy: 'YOhY'
def my_tuple(self):
return self.a_number, self.a_bool, self.classy
class YOhY:
def __repr__(self):
return (self.__class__.__qualname__ + f" id={id(self)}")
why = YOhY()
print(why) # YOhY id=4369078368
demo = Demo(1, True, why)
print(demo) # Demo(a_number=1, a_bool=True, classy=YOhY id=4369078368)
untrupled = demo.my_tuple()
print(untrupled) # YOhY id=4369078368
trupled = dataclasses.astuple(demo)
print(trupled) # YOhY id=4374460064
trupled2 = trupled
print(trupled2) # YOhY id=4374460064
trupled3 = copy.copy(trupled)
print(trupled3) # YOhY id=4374460064
trupled4 …Run Code Online (Sandbox Code Playgroud) 我正在使用 cython 进行代码混淆,因此目前性能不是问题。问题在于使用数据类。
cythonize 包含数据类定义的代码时,在编译期间没有错误。但是在运行代码时,我得到一个TypeError: <field> is a field but has no type annotation.
这是我试图 cythonize 的代码:
from dataclasses import dataclass, field
from typing import Dict, Any, List
@dataclass
class dataclass_test:
ddict: Dict[str, Any]
sstr: str
bbool: bool
llist: List[str]
ffloat: float
llist1: List[str] = field(default_factory=list)
Run Code Online (Sandbox Code Playgroud)
在没有 cythonization 的情况下运行代码工作正常。但是在 cythonization 之后,我收到以下错误消息:
File "dataclass_.py", line 4, in init dataclass_
@dataclass File "/home/aryskin/miniconda3/envs/tf113_gpu_conda/lib/python3.7/dataclasses.py", line 991, in dataclass
return wrap(_cls) File "/home/aryskin/miniconda3/envs/tf113_gpu_conda/lib/python3.7/dataclasses.py", line 983, in wrap
return _process_class(cls, init, repr, eq, order, …Run Code Online (Sandbox Code Playgroud) 我在处理 ETL 管道时偶然发现了一个问题。我正在使用数据类dataclass来解析 JSON 对象。JSON 对象的关键字之一是保留关键字。有没有解决的办法:
from dataclasses import dataclass
import jsons
out = {"yield": 0.21}
@dataclass
class PriceObj:
asOfDate: str
price: float
yield: float
jsons.load(out, PriceObj)
Run Code Online (Sandbox Code Playgroud)
这显然会失败,因为yield是保留的。查看数据类field定义,似乎没有任何可以提供帮助的内容。
Go,允许定义JSON字段的名称,不知道里面有没有这样的功能dataclass?
我想比较两个全局数据类的相等性。我更改了其中一个数据类中的字段,但 python 仍然坚持告诉我,这些对象是相等的。我不知道数据类内部如何工作,但是当我打印时,asdict我得到一个空字典...我做错了什么以及如何通过检查其成员的相等性来比较数据类?
我正在使用Python 3.9.4
from dataclasses import dataclass, asdict
@dataclass
class TestClass:
field1 = None
field2 = False
test1 = TestClass()
test2 = TestClass()
def main():
global test1
global test2
test2.field2 = True
print('Test1: ', id(test1), asdict(test1), test1.field1, test1.field2)
print('Test2: ', id(test2), asdict(test2), test2.field1, test2.field2)
print('Are equal? ', test1 == test2)
print('Are not equal?', test1 != test2)
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
输出:
Test1: 2017289121504 {} None False
Test2: 2017289119296 {} None True
Are equal? True
Are …Run Code Online (Sandbox Code Playgroud) 当处理 Python 数据类时,我遇到了这个很容易重现的奇怪错误。
from __future__ import annotations
import dataclasses as dc
import typing
@dc.dataclass
class Test:
foo: dc.InitVar[int]
print(typing.get_type_hints(Test))
Run Code Online (Sandbox Code Playgroud)
运行它会得到以下结果:
Traceback (most recent call last):
File "test.py", line 11, in <module>
print(typing.get_type_hints(Test))
File "C:\Program Files\Python310\lib\typing.py", line 1804, in get_type_hints
value = _eval_type(value, base_globals, base_locals)
File "C:\Program Files\Python310\lib\typing.py", line 324, in _eval_type
return t._evaluate(globalns, localns, recursive_guard)
File "C:\Program Files\Python310\lib\typing.py", line 687, in _evaluate
type_ =_type_check(
File "C:\Program Files\Python310\lib\typing.py", line 173, in _type_check
raise TypeError(f"{msg} Got {arg!r:.100}.")
TypeError: Forward references must evaluate …Run Code Online (Sandbox Code Playgroud) python python-3.x python-dataclasses python-typing python-3.10
我有一组固定的三个传感器,我想将其建模为枚举。每个传感器都通过一些不同的属性进行参数化。因此,我想将传感器本身建模为数据类。
我天真的尝试看起来像这样:
@dataclass
class SensorLocation:
address: int
pins: int
other_details: ...
class Sensors(SensorLocation, Enum):
TOP_SENSOR = SensorLocation(address=0x10, pins=0xf, other_details=...)
BOTTOM_SENSOR = SensorLocation(address=0x10, pins=0xf0, other_details=...)
SIDE_SENSOR = SensorLocation(address=0x15, pins=0xf, other_details=...)
Run Code Online (Sandbox Code Playgroud)
我的期望是,这本质上应该创建一个枚举,其中该枚举的实例的行为类似于SensorLocation. 这使得类型更加清晰,并将方法放在我期望的位置。
但是,在创建枚举时失败,并出现错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/to/python/3.7.10/lib/python3.7/enum.py", line 232, in __new__
enum_member.__init__(*args)
File "<string>", line 3, in __init__
File "/path/to/python/3.7.10/lib/python3.7/types.py", line 175, in __set__
raise AttributeError("can't set attribute")
AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)
我能做的是删除SensorLocation枚举声明中的子类化,但这意味着当使用 MyPy 或类似工具时,我失去了键入提示正确值的能力。它还使访问实际值变得更加复杂,但该枚举的主要目的是提供对这些值的访问。
有没有办法解决我缺少的这个错误,或者我现在看不到的其他解决方案?
是否可以从 中受益dataclasses.field,特别是对于默认值,但使用自定义构造函数?我知道@dataclass注释在生成的中设置默认值__init__,如果我替换它,就不会再这样做了。那么,是否可以替换生成的__init__,并仍然在内部调用它?
@dataclass
class A:
l: list[int] = field(default_factory=list)
i: int = field(default=0)
def __init__(self, a: Optional[int]): # completely different args than instance attributes
self.call_dataclass_generated_init() # call generated init to set defaults
if a is not None: # custom settings of attributes
i = 2*a
Run Code Online (Sandbox Code Playgroud)
解决方法是定义__new__而不是覆盖__init__,但我更愿意避免这种情况。
这个问题非常接近,但答案仅解决作为代码示例给出的特定用例。另外,我不想使用,__post_init__因为我需要使用__setattr__这是静态类型检查的问题,并且它无助于调整__init__无论如何都会采用的参数。
我也不想使用类方法,我真的希望调用者使用自定义构造函数。
这一个也很接近,但它只是解释为什么新的构造函数替换生成的构造函数,而不是关于如何仍然调用后者(还有一个回复建议使用 Pydantic,但我不想子类化BaseModel,因为这会弄乱我的继承权)。
因此,简而言之,我希望受益于dataclass …
我想初始化 python 数据类对象,即使没有实例变量传递给它并且我们没有向参数添加默认值
@dataclass
class TestClass:
paramA: str
paramB: float
paramC: str
obj1 = TestClass(paramA="something", paramB=12.3)
Run Code Online (Sandbox Code Playgroud)
这里它不允许我创建对象并且它会抛出
TypeError: __init__() missing 1 required positional argument: 'paramC'
Run Code Online (Sandbox Code Playgroud)
我可以使用默认值来解决此错误。
paramC: str = None
# OR
paramC: str = ""
Run Code Online (Sandbox Code Playgroud)
但我不想使用 paramC 的默认值,因为我想要一个场景,如果我们传递 paramC 那么只有它应该存在于对象中,否则它不应该存在。因此,如果我们在这里使用默认值,paramC 将始终存在于对象中,其值为None或空字符串。
如果在初始化期间未传递参数,我想跳过参数的初始化。
我有一个 Node 类,以十六进制和 HSV 形式保存 RGB 数据。我将使用它以各种方式对颜色进行排序,并且希望 HSV 元组保持浮点形式进行比较,而不是每次使用时都从字符串进行转换。有没有一种方法可以指定数据类字段应该以类似于默认值的特定方式格式化值default_factory,即 a repr_factory?
def RGB2HSV(r, g, b):
'''Returns HSV values in the range H = [0, 360], S = [0, 100], V = [0, 100]'''
r, g, b = r / 255, g / 255, b / 255
maxRGB = max(r, g, b)
minRGB = min(r, g, b)
delta = maxRGB - minRGB
V = maxRGB
if V == 0:
return 0, 0, V
S = delta / V …Run Code Online (Sandbox Code Playgroud) 我有一个数据类,比方说:
from dataclasses import dataclass
@dataclass
class Foo:
bar: int
baz: int
Run Code Online (Sandbox Code Playgroud)
我有一个从接收 json 并将其作为字典加载的 API 调用的函数:
def handler(foo) -> Foo:
return Foo(**foo)
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以输入 foo 而无需实际创建TypedDict数据类的镜像?
例如:
from typing_extensions import TypedDict
class SerializedFoo(TypedDict):
bar: int
baz: int
Run Code Online (Sandbox Code Playgroud)
我觉得必须定义两者很奇怪。
python ×10
python-3.x ×5
cython ×1
enums ×1
json ×1
mypy ×1
python-3.10 ×1
repr ×1
typeddict ×1