在下面的代码中,该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) 考虑以下数据类。我想阻止使用直接方法创建对象__init__。
from __future__ import annotations
from dataclasses import dataclass, field
@dataclass
class C:
a: int
@classmethod
def create_from_f1(cls, a: int) -> C:
# do something
return cls(a)
@classmethod
def create_from_f2(cls, a: int, b: int) -> C:
# do something
return cls(a+b)
# more constructors follow
c0 = C.create_from_f1(1) # ok
c1 = C() # should raise an exception
c2 = C(1) # should raise an exception
Run Code Online (Sandbox Code Playgroud)
例如,我想强制使用我定义的附加构造函数,如果直接将对象创建为c = C(..).
到目前为止我所尝试的如下。
@dataclass
class C:
a : int …Run Code Online (Sandbox Code Playgroud) 我正在使用dataclasses从 Python 3.7 向后移植的Python模块。我偶然发现了这种行为,其中数据类子类不继承__repr__:
from dataclasses import dataclass
@dataclass
class Person:
name: str
def __repr__(self):
return f'{self.__class__.__qualname__}({self.name})'
def print_something(self):
return self.name
@dataclass
class Employee(Person):
title: str
Run Code Online (Sandbox Code Playgroud)
这是输出
In [21]: e = Employee(name='Dmitry', title='Systems Engineer')
In [22]: p = Person(name='Dmitry')
In [23]: repr(e)
Out[23]: "Employee(name='Dmitry', title='Systems Engineer')"
In [24]: p = Person(name='Dmitry')
In [25]: repr(p)
Out[25]: 'Person(Dmitry)'
In [26]: p.print_something()
Out[26]: 'Dmitry'
In [27]: e = Employee(name='Dmitry', title='Systems Engineer')
In [28]: repr(e)
Out[28]: "Employee(name='Dmitry', title='Systems Engineer')"
In …Run Code Online (Sandbox Code Playgroud) 我想知道一种使数据类bar冻结的简单方法。
@dataclass
class Bar:
foo: int
bar = Bar(foo=1)
Run Code Online (Sandbox Code Playgroud)
换句话说,我想要一个如下所示的函数some_fn_to_freeze
frozen_bar = some_fn_to_freeze(bar)
frozen_bar.foo = 2 # Error
Run Code Online (Sandbox Code Playgroud)
并且,反函数some_fn_to_unfreeze
bar = som_fn_to_unfrozen(frozen_bar)
bar.foo = 3 # not Error
Run Code Online (Sandbox Code Playgroud) 我想创建一个数据类基类,其中子类中的所有字段自动为可选且默认为“无”(如果未提供默认值)。
下面的代码......似乎几乎达到了我想要的效果,但又不完全是。它的错误方式就像我从未编写过一样__init_subclass__(即抱怨未填充的参数)...也许是因为我的代码在数据类魔法发生后运行?
@dataclass(order=True, frozen=True)
class BaseDictKey:
def __init_subclass__(cls, *args, **kwargs):
super().__init_subclass__(*args, **kwargs)
# noinspection PyUnresolvedReferences
for field in cls.__dataclass_fields__.values():
field.default = None if field.default is None else field.default
field.type = typing.Union[field.type, NoneType]
@dataclass(order=True, frozen=True)
class ScoreDictKey(BaseDictKey):
catalog: str # magically becomes catalog: Optional[str] = None
dataset: str = 'foo' # magically becomes dataset: Optional[str] = 'foo'
Run Code Online (Sandbox Code Playgroud)
(如果您想知道为什么我想要这个,我有另一个使用这些 BaseDictKeys 的基类,它期望子类中的任何和所有字段都是可选的。我想如果我检测到某些内容不是可选的,我可以改为引发异常,但这看起来更丑陋。)
这在 Python 3.7+ 中可能吗?
我所拥有的:
我正在创建一个数据类,并说明其元素的类型:
class Task():
n_items: int
max_weight: int
max_size: int
items: numpy.array(Item) # incorrect way of doing it
Run Code Online (Sandbox Code Playgroud)
我想做的事情是
我想声明,该items将是“Item”类的对象的 numpy 数组
所以,我在一个文件中有这两个数据类:
@dataclass
class A:
children: List[B]
@dataclass
class B:
parent: A
Run Code Online (Sandbox Code Playgroud)
,这可以通过使用该__future__.annotations功能来实现。
然后我有另外两个文件,每个文件都有一堆对于我的项目来说是静态的每种类型的对象。
文件objects_A:
import objects_B
obj_a1 = A(
children=[
objects_B.obj_b1,
objects_B.obj_b2
]
)
Run Code Online (Sandbox Code Playgroud)
文件objects_B:
import objects_A
obj_b1 = B(
parent=objects_A.obj_a1
)
obj_b2 = B(
parent=objects_A.obj_a1
)
Run Code Online (Sandbox Code Playgroud)
显然,文件之间存在循环依赖问题,但即使它们位于同一个文件中,它也不起作用,因为一种类型的变量依赖于另一种类型的变量才能成功。
初始化B内部对象obj_a1也不起作用,因为self这里没有概念。
目前,我设置parent为None(针对类型提示),然后循环进行设置obj_a1:
for obj_b in obj_a1.children:
obj_b.parent = obj_a1
Run Code Online (Sandbox Code Playgroud)
大家有什么好主意吗?
不知道它是否有帮助,但是这些对象是静态的(它们在这些声明之后不会改变)并且它们具有某种父子关系(正如您肯定已经注意到的那样)。
如果可能的话,我希望将每种类型的变量放在不同的文件中。
python forward-declaration circular-reference python-3.x python-dataclasses
我有这个数据类:
from dataclasses import dataclass, field
from typing import List
@dataclass
class Person:
name: str
dob: str
friends: List['Person'] = field(default_factory=list, init=False)
Run Code Online (Sandbox Code Playgroud)
name并且dob是不可变的并且friends是可变的。我想生成每个人对象的哈希值。我可以以某种方式指定要包含和排除哪个字段来生成__hash__ 方法吗?在这种情况下,name和dob应该包含在生成哈希中,但friends不应该包含。这是我的尝试,但没有成功
@dataclass
class Person:
name: str = field(hash=True)
dob: str = field(hash=True)
friends: List['Person'] = field(default_factory=list, init=False, hash=False)
Run Code Online (Sandbox Code Playgroud)
>>> hash(Person("Mike", "01/01/1900"))
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
hash(Person("Mike", "01/01/1900"))
TypeError: unhashable type: 'Person'
Run Code Online (Sandbox Code Playgroud)
我也找不到设置name和dob冻结的方法。仅仅从声音来看,我不会将其设置unsafe_hash为。 …
我创建了一个数据类Foo,它接受任何可以转换为的类型int:
import dataclasses
@dataclasses.dataclass
class Foo:
a: int
def __post_init__(self):
# Here `self.a` is converted to int, so this class accepts any type that can be converted to int
self.a = int(self.a)
# mypy error: Argument 1 to "Foo" has incompatible type "str"; expected "int",
foo = Foo("1")
print(foo)
print(foo.a + 2)
Run Code Online (Sandbox Code Playgroud)
输出:
Foo(a=1)
3
Run Code Online (Sandbox Code Playgroud)
但是,mypy 报告以下错误:
error: Argument 1 to "Foo" has incompatible type "str"; expected "int"
Run Code Online (Sandbox Code Playgroud)
Foo.a如果我修复to的类型Union[str, int],mypy 会报告另一个错误:
error: Unsupported …Run Code Online (Sandbox Code Playgroud) 我知道标题很混乱,所以让我以二叉搜索树为例:
# This code passed mypy test
from typing import Generic, TypeVar
T = TypeVar('T')
class BST(Generic[T]):
class Node:
def __init__(
self,
val: T,
left: 'BST.Node',
right: 'BST.Node'
) -> None:
self.val = val
self.left = left
self.right = right
Run Code Online (Sandbox Code Playgroud)
上面的代码通过了mypy测试。
dataclass但是,当我尝试使用dataclass来简化 的定义时Node,代码在 mypy 测试中失败了。
# This code failed to pass mypy test
from dataclasses import dataclass
from typing import Generic, TypeVar
T = TypeVar('T')
class BST(Generic[T]):
@dataclass
class Node:
val: …Run Code Online (Sandbox Code Playgroud)