在Python

时间:2016-01-25 23:52:17

标签: python python-2.7 class memory properties

我正在编写一个简单的类来检索以恒定采样率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()装饰器没有提供所需的功能(即最小的内存开销,根据需要易于使用),我应该使用什么?只是一种类方法?或者是否有不同的,更优化的解决方案?谢谢!

3 个答案:

答案 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 装饰器时,通常会有一个用于检索和存储值的基础变量。有帮助的希望