假设我想存储一些关于会议日程的信息,包括演示时间和暂停时间。我可以在NamedTuple
中执行此操作。
from typing import NamedTuple
class BlockTime(NamedTuple):
t_present: float
t_pause: float
但是,如果我还想存储每个块需要多少,以便t_each=t_pauset_present
,我不能只是将其添加为属性:
class BlockTime(NamedTuple):
t_present: float
t_pause: float
# this causes an error
t_each = t_present + t_pause
在Python中这样做的正确方法是什么?如果我创建了一个< code>__init__(self)方法,并将它作为一个实例变量存储在那里,但是它将是可变的。
良好的..不能覆盖父级为NamedTuple的类的< code>__new__或< code>__init__。但是您可以重写一个类的< code>__new__,该类继承自另一个其父级为NamedTuple的类。
所以你可以这样做
from typing import NamedTuple
class BlockTimeParent(NamedTuple):
t_present: float
t_pause: float
t_each: float
class BlockTime(BlockTimeParent):
def __new__(cls, t_present, t_pause):
return super().__new__(cls, t_present, t_pause, t_present+ t_pause)
b = BlockTime(1,2)
print (b)
# BlockTime(t_present=1, t_pause=2, t_each=3)
您可以创建一个构建块时间
对象的类方法
class BlockTime(NamedTuple):
t_present: float
t_pause: float
t_each: float
@classmethod
def factory(cls, present, pause):
return cls(present, pause, present+pause)
print(BlockTime.factory(1.0, 2.0))
# BlockTime(t_present=1.0, t_pause=2.0, t_each=3.0)
编辑:
下面是使用新的Python 3.7数据类的解决方案
from dataclasses import dataclass, field
@dataclass(frozen=True)
class BlockTime:
t_present: float
t_pause: float
t_each: float = field(init=False)
def __post_init__(self):
object.__setattr__(self, 't_each', self.t_present + self.t_pause)
冻结的数据类
es不是完全不可变的,但它们非常接近,这让您可以自然地创建实例BlockTime(1.0,2.0)
如果它不是真正存储的,而是动态计算的,你可以为它使用一个简单的属性
。
from typing import NamedTuple
class BlockTime(NamedTuple):
t_present: float
t_pause: float
@property
def t_each(self):
return self.t_present + self.t_pause
>>> b = BlockTime(10, 20)
>>> b.t_each # only available as property, not in the representation nor by indexing or iterating
30
这样做的好处是,您永远不会(甚至不会意外)为它存储错误的值。然而,以根本没有实际存储为代价。因此,为了让它看起来像是存储的,您必须至少覆盖__getitem__
、__iter__
、__repr__
-这可能会带来太多麻烦。
例如,Patrick Haugh给出的NamedTuple
方法有一个缺点,即仍然可能创建不一致的BlockTime
或丢失部分namedtuple
便利性:
>>> b = BlockTime.factory(1.0, 2.0)
>>> b._replace(t_present=20)
BlockTime(t_present=20, t_pause=2.0, t_each=3.0)
>>> b._make([1, 2])
TypeError: Expected 3 arguments, got 2
事实上,您实际上有一个必须与其他字段同步的“计算”字段,这表明您可能根本不应该存储它以避免不一致的状态。
Proto3已被简化,不再支持“必需”和“可选”字段(请参见为什么在协议缓冲区3中删除“必需”和“可选”)。是否仍有办法将某个字段标记为必填字段?我研究了FieldOptions(字段选项),并尝试了以下方法: 在将其编译成Java代码之后,当我检查编译的Java代码时,我没有看到字段与proto中指定的元数据之间的任何链接。我错过什么了吗?
问题内容: 我有一个字段是,保持日期值,我从转换到。 有些记录有八个字符,有些记录有七个字符。我想通过将前导零添加到具有7的前导零来使它们具有相同的长度。 8个字符的示例:12162003 7个字符的示例:5072004(需要前导零) 查询: 问题答案: 可以在更多情况下使用的功能是REPLICATE。它将一个X值的次数连接到一个字符串。 这将花费您的生日的长度,将其减去8,然后在前面放置多个前导
问题内容: 我正在使用wtforms(和flask)生成动态表单。我想向正在生成的字段中添加一些自定义的CSS类,但是到目前为止,我一直无法这样做。使用在这里找到的答案,我尝试使用自定义小部件来添加此功能。它的实现方式与该问题的答案几乎完全相同: 在View中,我这样做是为了创建字段(ClassedTextField是从表单导入的,而f是基本表单的实例): 表单的其余部分均已正确创建,但此jinj
我想计算两个字段的总和,然后在文档中创建新的字段,比如:“total sum”。但我不知道怎么做。都在MongoDB中。这里有一个例子:
问题内容: 将字段添加到结构化numpy数组的最干净方法是什么?可以破坏性地完成它,还是必须创建一个新数组并在现有字段上进行复制?每个字段的内容是否连续存储在内存中,以便可以高效地进行复制? 问题答案: 如果您使用的是numpy 1.3,则还有numpy.lib.recfunctions.append_fields()。 对于许多安装,您将需要访问它。不允许一个人看到
我使用iText将数据填充到PDF中现有的AcroForm字段中。 我现在正在寻找将新的AcroForm字段添加到PDF的解决方案。iText是否可以做到这一点?如果是,我该如何做到这一点?