对于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)
为什么不支持比较运算符,除了==和!=?或者我忽略了什么?
我想更新数据类中的字段,但我仅在运行时而不是在开发期间知道字段名称。
#!/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 类:
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_type和c_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 类
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. 这是使用数据类正确声明的类变量吗?或者有更好的方法吗?
我已经测试了数据类实现,它提供了预期的功能,但我主要想知道我的实现是否遵循最佳实践。
我想使用该方法填充数据类的属性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()方法移出类。
是否可以指定在非冻结数据类中冻结单个字段?像这样的东西:
@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)
我意识到这可以通过访问私有数据字段的属性和设置器手动完成,但是这样我们就失去了数据类的一些优点:首先,私有数据字段需要不同的名称,这意味着自动生成的构造函数令人烦恼地具有不同的名称参数名称比字段更重要。
我经常看到这样的代码:
@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() 吗?
我想做这个:
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)
但我找不到怎么做。
可以为初始化 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中的数据类,我想做的是在我的类中拥有一个计算字段,并将 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 …