在Python中,何时修改self,何时返回新实例?



我经常陷入一个很大的困境,什么时候类应该修改自己,什么时候返回一个新的修改过的实例。

假设我想编写一个简单的序列库。

class Seq:
def __init__(self, seq):
self.seq = seq

然后我想重命名序列中的元素,在Seq中有两个选项:

def rename(lookup):
self.seq = [lookup[e] for e in self.seq]

def rename(lookup):
return Seq([lookup[e] for e in self.seq])

我将处理更复杂的结构,例如,如果我正在创建一个图,我想把它变成唯一的规范化(唯一顶点枚举)形式,它应该把自己放在这种形式或返回一个新的实例。最常见的做法是什么?何时选择这两个选项?

我的想法是这样的:你必须参与用户最有用的东西。但这是

吗?
def rename(lookup, create_new_instance = False):
if create_new_instance:
return [lookup[e] for e in self.seq]
else:
self.seq = [lookup[e] for e in self.seq]

一个好的做法?

或者我应该实现两个不同的方法,一个作为静态的,返回新的对象,一个非静态的,修改自己?像list.sort()和sorted(list)?但是如果我有很多修改对象的方法,就会有很多开销。

通常,对于内置的规则是:

  1. 如果类实例在逻辑上是可变的,并且方法作为一个突变方法是有意义的,只有使突变方法(并且它们总是返回None,因此对于它们返回的是自己的突变还是一个突变的副本没有混淆)

  2. 如果类实例在逻辑上是不可变的,那么你别无选择,所有这些"突变"都是不可变的。方法返回新对象(注意:通常为该类型的新对象;rename返回一个不相关的list而不是一个新的Seq会很奇怪)

是否有方法根据参数的不同在返回中变化,这是毫无意义的混淆,特别是如果人们传递它的位置;快速,obj.rename(xyz, True)相对于obj.rename(xyz, False)是什么意思?你要做的事更多,他们也要做的事更多,还是别做吧。

因为你的类在逻辑上是可变的,所以遵循第一条的规则。不过,不要创建一堆变体方法,只需定义切片(因此它们可以为浅拷贝执行myseq[:])和/或copy方法(list提供了这两种方法,您也可以)。如果用户想保留原始内容,他们首先复制,然后改变结果。使它在使用时更加清晰,并避免大量的代码重复。

这主要取决于你希望用户在你的结构中意识到什么。

一方面,修改self.seq确保了您对结构的完全控制,因为您可以控制如何访问该字段(例如通过属性)

另一方面,直接返回集合允许用户对其进行任何转换,因此您将无法控制附加到seq的内容。如果没有做正确的检查,它可以完全破坏你的类逻辑。

相关内容

  • 没有找到相关文章

最新更新