我将构建一个程序(在Scala或Python中 - 尚未决定),这是一个强大的数据操作。我看到两个市长的方法:
我不确定,但第一种方法可能是更多的功能性编程,第二种方法是OOP,是吗?顺便说一句,我喜欢功能编程和OOP(有人说他们彼此相反,但是Odersky尽力反驳Scala)。
我更喜欢第二种方法,因为
然而,我担心如果我有很多数据(而且我这样做),我将消耗大量内存,因为该方法可能需要多次实例化。
引导我:我应该选择哪种方法?
这是一个粗糙的DataObject类:
class DataObject {
List datavalues
def mymethod(){
...
}
}
答案 0 :(得分:1)
哪种方法最好完全取决于您的问题。如果只有很少的操作,功能就更简单了。如果您有许多操作依赖于数据的类型/特征,则类是有效的。
就个人而言,我更喜欢使用相同类型数据的类来改进抽象和模块化。基本上,使用类需要您考虑数据是什么样的,允许的数据以及适当的数据。它强制您分离,划分和了解您正在做的事情。完成后,您可以将它们视为可以正常工作的黑盒子。
我看到很多数据分析程序都失败了,因为它们只有处理任意数据的函数。起初,这是简单的计算。然后需要保存/缓存状态,因此直接附加或修改数据。然后有人意识到,如果你在之前不做之前做了x,那么各种各样的旗帜,领域和其他东西都会被加上,只有a,b和d才能被理解。然后有人添加了功能f,扩展了它,而有人添加了功能k,扩展它的方式不同。这会创建一个在创建结果时无法理解,维护或信任的集群foo。
所以如果你不确定,那就上课吧。最后你会更开心。
关于你的第二个问题,我只能回答python的问题。但是,许多语言也是这样做的。
python中的常规方法在类上定义并使用它创建。这意味着方法表示的实际函数由所有实例共享,没有内存开销。基本上,裸实例只是对类的包装引用,从中提取方法。只有独占的实例(如数据)才能显着增加内存。
调用方法会增加一些开销,因为该方法被绑定到实例 - 基本上,该函数是从类中获取的,并且第一个参数self
被绑定。这在技术上会产生一些开销。
# Method Call
$ python -m timeit -s 'class Foo():' -s ' def p(self):' -s ' pass' -s 'foo = Foo()' 'foo.p()'
10000000 loops, best of 3: 0.158 usec per loop
# Method Call of cached method
$ python -m timeit -s 'class Foo():' -s ' def p(self):' -s ' pass' -s 'foo = Foo()' -s 'p=foo.p' 'p()'
10000000 loops, best of 3: 0.0984 usec per loop
# Function Call
$ python -m timeit -s 'def p():' -s ' pass' 'p()'
10000000 loops, best of 3: 0.0846 usec per loop
然而,实际上任何操作都是这样做的;如果您的应用程序除了调用您的方法之外什么都不做,那么您只会注意到增加的开销,并且该方法也没有做任何事情。
我也看到人们编写具有如此多抽象级别的数据分析应用程序,实际上他们大多只是调用方法/函数。这是一般编写代码的气味,而不是使用方法或函数。
所以如果你不确定,那就上课吧。最后你会更开心。