我正在编写一个简单的类来检索以恒定采样率x
数字化的信号Fs
。数字化始于t0
。给定信号长度N = len(x)
,采样率和初始时间,信号的时基是唯一确定的。我很少需要访问时基,但我希望在需要时能够轻松实现这一目标。下面,我使用property()
装饰器实现了我所需的时基功能的最小工作示例:
import numpy as np
class Signal(object):
def __init__(self, x, Fs, t0):
self.x = x
self.Fs = Fs
self.t0 = t0
return
@property
def t(self):
return self.t0 + (np.arange(len(self.x)) / self.Fs)
我想了解创作和"持久性"时基属性Signal.t
。以下面的示例用例为例:
x = np.arange(10)
Fs = 1.
t0 = 0.
sig = Signal(x, Fs, t0)
print sig.t
什么时候生成时基阵列t
?在初始化期间或动态调用print sig.t
时?如果sig.t
属性是动态计算的,那么它持久会超出print
命令吗? (即已分配内存以将时基存储为对象属性?)。
虽然以上是一个简单的例子,但我的典型信号非常大,而我不想要为每个信号创建和存储时基的内存开销。但是,我想要一种根据需要动态生成时基的简单方法;时间基准不在其一次性使用后作为对象属性持久存在(例如,用于创建原始信号的图)。
如果property()
装饰器没有提供所需的功能(即最小的内存开销,根据需要易于使用),我应该使用什么?只是一种类方法?或者是否有不同的,更优化的解决方案?谢谢!
答案 0 :(得分:1)
每次访问sig.t
时,都会(重新)运行您使用t
修饰的@property
函数,并将结果用作sig.t
的值。这意味着数组是按需创建的,并且永远不会存储在t
对象上。
你似乎想要这个,但我对此很谨慎。通常预计物业通道便宜,而且这个属性不是。考虑改为使用普通方法。
答案 1 :(得分:1)
什么时候生成时基数组?
使用时。即当你写print sig.t
如果动态计算sig.t属性,它是否会超出print命令? (即已分配内存以将时基存储为对象属性?)。
不。下次代码引用sig.t
时,将创建一个新对象。
如果property()装饰器不提供所需的功能(即最小的内存开销,根据需要易用),我应该使用什么?只是一种类方法?或者是否有不同的,更优化的解决方案?谢谢!
我怀疑有不同的意见......你可以修改代码,以便缓存值并在每次调用时返回相同的内容:
class Signal(object):
def __init__(self, x, Fs, t0):
self.x = x
self.Fs = Fs
self.t0 = t0
self._t = None
return
@property
def t(self):
if self._t is not None:
return self._t
self._t = self.t0 + (np.arange(len(self.x)) / self.Fs)
return self._t
但是在这里你无法告诉班级t
应该重新计算,除非你做了一个制定者......
如果t
在初始化后不会改变,那为什么不把它变成公共财产呢?
class Signal(object):
def __init__(self, x, Fs, t0):
self.x = x
self.Fs = Fs
self.t0 = t0
self.t = self.t0 + (np.arange(len(self.x)) / self.Fs)
答案 2 :(得分:1)
在您的示例中,每次访问属性Signal.t
时都会动态生成t
值,因为您实际上是在调用Signal.t()来访问它。所以,您没有存储值得回报它。
每当在一个类周围使用 @property 装饰器时,该功能通常充当" getter"对于"私有"(不是真正的)变量,有时会有一个" setter"对于那个"私人"变量
当我的意思是"私人"我的意思是指为了反映不应直接访问这些属性的属性。但是,在python中你可以访问任何属性,所以没有任何私有变量,因为python对象可以很容易地改变。
如果您想存储您的值,那么您应该这样做。
import numpy as np
class Signal(object):
def __init__(self, x, Fs, t0):
self.x = x
self.Fs = Fs
self.t0 = t0
self._t = None
return
@property
def t(self):
if self._t is None:
self._t = self.t0 + (np.arange(len(self.x)) / self.Fs)
return self._t
@t.setter
def t(self,value):
self._t = value
上面的示例,只计算一次并将其存储在_t
内,但您明白了。当使用 @property 装饰器时,通常会有一个用于检索和存储值的基础变量。有帮助的希望