惯例:在编写方法时,我应该返回值还是直接更改数据?

时间:2014-11-28 23:32:34

标签: java python methods return conventions

我一直在编写Java和Python代码。我已经多次注意到,两种语言中的对象通常都有看似不一致的方法来调用它们的方法。以这些Python代码片段为例。 (语法并不重要,只需注意方法处理数据的方式)

class Foo(object):
    def __init__(self, num = 0):
        self.num = num

    def __str__(self):
        return str(self.num)

    def addOne(self):
        self.num += 1

if __name__ == "__main__":
    foo = Foo()
    print(foo) # Outputs 0

    foo.addOne()
    print(foo) # Outputs 1

对战:

class Bar(object):
    def __init__(self, num = 0):
        self.num = num

    def __str__(self):
        return str(num)

    def addOne(self):
        return Bar(num + 1)

if __name__ == "__main__":
    bar = Bar()
    print(bar) # Outputs 0

    bar.addOne()
    print(bar) # Still Outputs 0

    bar = bar.addOne()
    print(bar) # Now Outputs 1

这两个示例非常相似,但是当您调用Foo.addOne()时,Foo类会更改类中的num变量。但是,Bar类的addOne()方法返回一个更新了num变量的新对象。在什么时候哪种情况更可取,人们期望什么,这在语言之间有多大差异?

2 个答案:

答案 0 :(得分:1)

Java有一些不可变的类。您(作为Java开发人员)也可以创建此类。即使您想要,也无法从不可变类更改任何对象的内部状态(例如,如果不创建新的Integer对象,则无法将{1}添加到Integer对象,并且无法追加“a”到一个String对象,而不创建一个新的String对象,即使你想要)。

现在,如果一个类不是不可变的,那么您可以自由地采用这两种方法(更改现有实例的内部状态,或者创建一个新实例)。但无论您采取哪种方法,都应记录下来,以便您的来电者知道会发生什么。就我所知,至少它在Java世界中是如何工作的。

答案 1 :(得分:0)

简短的回答:没有这样的约定。作为一种语言,Python结合了面向对象和功能范例。就我个人而言,在每个特定情况下选择哪一个是Python开发人员最擅长的技能。

你应该回答很多问题,例如:你的对象应该如何使用?它会在线程之间共享吗?性能是个问题吗?应用程序架构的惯例是什么?也许答案会在以后发生变化,因此可以为重构做好准备。

Python对Java的限制要少得多,并且无法保证对象的状态。它既不能像Java那样做出低级别性能优化的假设。所以这个定义是可变的' /'不可变的'仅仅是Python类的惯例。我们理解对象的方式多于语言的技术特征。

在一般情况下(或有疑问)我建议遵循POLA principle并坚持常见模式。例如,如果您的对象行为类似于字符串,则返回新实例;如果像字典一样,执行就地修改。极端情况通常是错误的,优秀的Python设计使用两个世界中最好的。