modelx v0.4.0 (2020年3月15日)#
本次版本在计算追踪方面进行了重大改进,并修复了一些错误。计算速度也提升了15%到20%。
功能增强#
引用追踪
现在可以追踪引用了。 在此版本之前,当引用被重新分配或删除时, 由公式中引用这些引用的单元格计算得出的值 保持不变。 从这个版本开始,当公式中的引用发生变化时, 依赖的值将被清除:
SpaceA.bar = 3
@mx.defcells(SpaceA)
def foo():
return bar
foo() # ==> 3
SpaceA.bar = 4
foo() # ==> 4
与Cells追踪不同,所有依赖Cells的值都会被清除,
无论这些值是否实际参与了计算,
只要Cells的公式中引用了这些References。
在下面的示例中,foo(0)并不依赖于SpaceA.bar,
但当SpaceA.bar被重新赋值时,它的值仍会被清除:
SpaceA.bar = 3
@mx.defcells(SpaceA)
def foo(x):
if x > 0:
return bar
else:
return 0
foo(0) # ==> 0
foo(1) # ==> 3
dict(foo) # ==> {0: 0, 1: 3}
SpaceA.bar = 4
dict(foo) # ==> {} (Both foo(0) and foo(1) are cleared.)
属性引用追踪
当在公式中将References作为Spaces的属性引用时,它们也会被追踪,但与上述情况不同的是,依赖关系是根据这些属性是否在计算中被使用来确定的,这与Cells追踪的方式相同。在下面的示例中,foo(0)并不依赖于SpaceA.SpaceB.bar,因此在重新赋值给SpaceA.SpaceB.bar时它们不会被清除:
SpaceA.SpaceB.bar = 3
@mx.defcells(SpaceA)
def foo(x):
if x > 0:
return SpaceB.bar # bar is referenced as an attribute of SpaceB
else:
return 0
foo(0) # ==> 0
foo(1) # ==> 3
dict(foo) # ==> {0: 0, 1: 3}
SpaceA.SpaceB.bar = 4
dict(foo) # ==> {0: 0} (Only foo(1) is cleared)
空间公式追踪
空间公式中的单元格和引用现在也会被追踪。 当空间公式中的单元格或引用值更新时, 由该公式创建的所有ItemSpace都会被清空:
def formula(i):
return {"refs": {"foo0": bar(), "foo1": baz}}
SpaceA = mx.new_space("SpaceA", formula=formula)
@mx.defcells
def foo(x):
return 2 if x > 1 else foo1 if x > 0 else foo0
@mx.defcells
def bar():
return 0
SpaceA.baz = 1
SpaceA[1].foo(2) # ==> 2
SpaceA[1].foo(1) # ==> 1
SpaceA[1].foo(0) # ==> 0
dict(SpaceA[1].foo) # ==> {2: 2, 1: 1, 0: 0}
SpaceA.bar = 2
dict(SpaceA[1].foo) # ==> {}
SpaceA[1].foo(2) # ==> 2
SpaceA[1].foo(1) # ==> 1
SpaceA[1].foo(0) # ==> 2
dict(SpaceA[1].foo) # ==> {2: 2, 1: 1, 0: 2}
SpaceA.baz = 3
dict(SpaceA[1].foo) # ==> {}
SpaceA[1].foo(2) # ==> 2
SpaceA[1].foo(1) # ==> 3
SpaceA[1].foo(0) # ==> 2
dict(SpaceA[1].foo) # ==> {2: 2, 1: 3, 0: 2}
Bug修复#
Spyder modelx 插件中存在一个错误,导致 MxAnalyzer 未能正确追踪 ItemSpaces 中的 Cells。