标签: python-dataclasses

为什么Python 3.7数据类不支持<> <=和> =,或者它们呢?

对于Transcrypt Python到JavaScript编译器的 3.7.1版本,我目前正在使用新的@dataclass装饰器.根据PEP的摘要,我原本预计==, !=, <, >, >=, <=会得到支持,但似乎并非如此:

from dataclasses import dataclass

@dataclass
class C:
    x: int = 10
Run Code Online (Sandbox Code Playgroud)

有些比较不起作用:

>>> c1 = C(1)
>>> c2 = C(2)
>>> c1 == c2  # ok
False
>>> c1 < c2  # crash
TypeError: '<' not supported between instances of 'C' and 'C'
Run Code Online (Sandbox Code Playgroud)

为什么不支持比较运算符,除了==!=?或者我忽略了什么?

python transcrypt python-3.7 python-dataclasses

10
推荐指数
1
解决办法
292
查看次数

使用仅在运行时已知的字段名称更新数据类中的字段

我想更新数据类中的字段,但我仅在运行时而不是在开发期间知道字段名称。

#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-

from dataclasses import dataclass # I use the backport to 3.6

@dataclass
class Template:
    number: int = 0
    name: str = "^NAME^"


oneInstance = Template()
print(oneInstance) # Template(number=0, name='^NAME^')
# If I know the variable name during development, I can do this:
oneInstance.number=77
# I get this from a file during runtime:
para = {'name': 'Jones'}
mykey = 'name'
# Therefore, I used exec:
ExpToEval = "oneInstance." + mykey + ' = …
Run Code Online (Sandbox Code Playgroud)

python python-dataclasses

10
推荐指数
2
解决办法
2万
查看次数

数据类中的类属性和元类

我有一些带有类属性和元类的 Python 类:

from abc import ABCMeta

class OldProduct(metaclass=ABCMeta):
    c_type: str
    c_brand: str

    def __init__(self, name:str):
        self.name = name

class OldLegoBox(OldProduct):
    c_type = "Toy"
    c_brand = "Lego"

    def __init__(self, name:str, price:float):
        self.name = name
        self.price = price

oldbox1 = OldLegoBox("Princess", 12.3)
print(oldbox1.c_brand)
oldbox2 = OldLegoBox("Knight", 42.3)
print(oldbox2.c_brand)
Run Code Online (Sandbox Code Playgroud)

我想dataclasses用来改进代码:如何处理类属性c_typec_brand

我正在考虑以下似乎可以满足我的需求:

from abc import ABCMeta
from dataclasses import dataclass, field


@dataclass
class Product(metaclass=ABCMeta):
    c_type: str
    c_brand: str
    name: str


@dataclass
class LegoBox(Product):
    name: str
    price: float …
Run Code Online (Sandbox Code Playgroud)

python python-dataclasses

10
推荐指数
1
解决办法
2923
查看次数

在数据类中创建类变量的正确方法

我刚刚开始使用 Python 的数据类,我想确认我正在以正确的方式声明类变量。

使用常规的 Python 类

class Employee:

    raise_amount = .05

    def __init__(self, fname, lname, pay):
        self.fname = fname
        self.lname = lname
        self.pay = pay
Run Code Online (Sandbox Code Playgroud)

使用 python 数据类

@dataclass
class Employee:
    fname: str
    lname: str
    pay: int
    raise_amount = .05
Run Code Online (Sandbox Code Playgroud)

我所指的类变量是raise_amount. 这是使用数据类正确声明的类变量吗?或者有更好的方法吗?

我已经测试了数据类实现,它提供了预期的功能,但我主要想知道我的实现是否遵循最佳实践。

python python-3.x python-dataclasses

10
推荐指数
2
解决办法
3345
查看次数

使用类或静态方法作为数据类中的default_factory

我想使用该方法填充数据类的属性default_factory。但是,由于工厂方法仅在该特定类的上下文中有意义,因此我想将其保留在类内部(例如作为静态或类方法)。例如:

from dataclasses import dataclass, field
from typing import List

@dataclass
class Deck:
    cards: List[str] = field(default_factory=self.create_cards)

    @staticmethod
    def create_cards():
        return ['King', 'Queen']
Run Code Online (Sandbox Code Playgroud)

但是,我在第 6 行收到此错误(如预期):

NameError:名称“self”未定义

我怎样才能克服这个问题?我不想将该create_cards()方法移出类。

python python-dataclasses

10
推荐指数
1
解决办法
9979
查看次数

如何冻结非冻结数据类的单个字段?

是否可以指定在非冻结数据类中冻结单个字段?像这样的东西:

@dataclass
class Data:
    fixed: int = field(frozen=True)
    mutable: int = field(frozen=False)

d = Data(2, 3)
d.mutable = 5   # fine
d.fixed = 7     # raises exception
Run Code Online (Sandbox Code Playgroud)

我意识到这可以通过访问私有数据字段的属性和设置器手动完成,但是这样我们就失去了数据类的一些优点:首先,私有数据字段需要不同的名称,这意味着自动生成的构造函数令人烦恼地具有不同的名称参数名称比字段更重要。

python python-dataclasses

10
推荐指数
1
解决办法
2572
查看次数

如何在数据类中使用field()?

我经常看到这样的代码:

@dataclass
class ClassName:
    list_name: list[int] = field(default_factory=list)
Run Code Online (Sandbox Code Playgroud)

但我不明白为什么我需要输入field(default_factory=list). 还不够吗list_name: list[int]

您能解释一下何时、为什么以及如何在数据类中使用 field() 吗?

python python-dataclasses

10
推荐指数
1
解决办法
5295
查看次数

如何将类实例添加到数据类表示法中的类变量?

我想将所有类实例添加到类变量

我想做这个:

class Circle:
    all_circles = []
    def __init__(self, rad):
        self.rad = rad
        self.__class__.all_circles.append(self)
Run Code Online (Sandbox Code Playgroud)

所以当我创建一个新的圆实例时,它会被添加到all_circle类变量中。

如何在dataclass符号中做到这一点?

我想复制顶部的代码,@dataclass但我无法在任何地方找到如何执行此操作,因为我无法访问 self.

就像是:

from dataclasses import dataclass
from typing import ClassVar


@dataclass
class Circle:
    rad: int = 1
    all_circles = ClassVar[list] = [] # after this I don't know how to get the self because it is not available
    
Run Code Online (Sandbox Code Playgroud)

但我找不到怎么做。

python python-dataclasses

10
推荐指数
1
解决办法
139
查看次数

如何初始化Python数据类二维列表?

可以为初始化 2D 数组的 python 数据类创建默认初始化程序,即结果与

from dataclasses import dataclass, field
from typing import List
MAX = 5
@dataclass
class AlgoData:
    list2D: List[List[int]]  # = ???
    list1D: List[int] = field(default_factory=list)

b = [[] for m in range(MAX)]
a = AlgoData(b)
Run Code Online (Sandbox Code Playgroud)

但没有b争论。结果:

AlgoData(list2D=[[], [], [], [], []], list1D=[])
Run Code Online (Sandbox Code Playgroud)

python-3.x python-3.7 python-dataclasses

9
推荐指数
1
解决办法
8007
查看次数

如何在 Python 数据类中使用 __post_init__ 方法

我正在尝试使用Python中的数据类,我想做的是在我的类中拥有一个计算字段,并将 sort_index 字段添加到调用中,但也希望将其冻结,以便我无法修改任何属性定义后的此类。下面是我的代码:

from dataclasses import dataclass, field

def _get_year_of_birth(age: int, current_year: int=2019):
    return current_year - age

@dataclass(order=True, frozen=True)
class Person():
    sort_index: int = field(init=False, repr=False)
    name: str
    lastname: str
    age: int
    birthyear: int = field(init=False)


    def __post_init__(self):
        self.sort_index = self.age
        self.birthyear = _get_year_of_birth(self.age)



if __name__ == "__main__":
    persons = [
    Person(name="Jack", lastname="Ryan", age=35),
    Person(name="Jason", lastname="Bourne", age=45),
    Person(name="James", lastname="Bond", age=60)
    ]

    sorted_persons = sorted(persons)
    for person in sorted_persons:
        print(f"{person.name} and {person.age} and year of birth is : {person.birthyear}")
Run Code Online (Sandbox Code Playgroud)

看来我无法在类中设置自定义排序字段,也无法创建从其他属性计算得出的任何属性,因为我使用的是 freeze …

python-3.7 python-dataclasses

9
推荐指数
1
解决办法
2万
查看次数