Return 方法中的就地修改语句

Return statement in method that modifies in-place

假设我想要一个简单的方法,它采用 list 并通过向其附加 5 来就地修改它。下面是执行此操作的两种方法,但是 ret(l) returns 而 no_ret(l) 不会。

def ret(l): 
   l.append(5) 
   return l 


def no_ret(l):
   l.append(5)

哪种方法更pythonic?我猜 no_ret() 因为如果该方法用于就地修改,那么就不需要 return 因为我们已经有了对被修改对象的引用。

它们在时间和 space 效率方面的比较如何?

我注意到 Python 提供了就地非 returning 实例方法 sort() 和非就地 returning 静态方法 sorted()。但是我不能让我的就地方法成为默认 类 的实例方法,比如 list

您不应该做的第一件事是用您自己的方法复制现有功能 - 但是,我假设您只是在举一个例子,这不是您计划的实际代码运行.

所有方法都在Pythonreturn一个值。如果一个方法没有 return 语句,它 returns None.

任何就地修改但不修改的函数return;不应该 return 一个值。这是有道理的,因为这就是 "normal" 就地方法的工作方式。

正确的实施方式是:

def do_something(foo, bar):
   foo.do_something_inplace(bar)
   return None # or simply, return

空白 return 与 return None 相同,但请记住 - 显式优于隐式。

至于您关于 space 和时间效率的其他问题,这将完全取决于实际进行替换的方法的实现。当您在示例中为内置方法编写代理时,"speed penalty" 可以忽略不计。

在评估 pythonic 某些代码时,我们应该查看标准库。两个可变对象是:

list 使用就地方法 append:

mylist = [1,2,3]
mylist.append(5).append(3) # Throws error 'NoneType' object has no attribute 'append'

dict 使用就地方法 update:

mydict={}
mydict.update(mydict).update(mydict) # Throws error 'NoneType' object has no attribute 'update'

我们可以得出结论,就地方法应该 return None

性能注意事项:

test.py

def ret(l): 
   l.append(5) 
   return l

def no_ret(l):
   l.append(5)

def test_ret():
    l=[]
    for i in xrange(100000):
        ret(l)

def test_no_ret():
    l=[]
    for i in xrange(100000):
        no_ret(l)

在 IPython 与 %timeit:

In [3]: %timeit test_ret()
10 loops, best of 3: 163 ms per loop

In [4]: %timeit test_no_ret()
10 loops, best of 3: 161 ms per loop

not-returning 方法 not 比 C-Python.

中的 returning 更快

编辑评论

您可以使任何方法成为 python 中 class 的实例方法:

class MyObject(object):
    def __init__(self):
        self.l=[]

def ret(self):
    self.l.append(randint(10,15))
    return self

IPython:

In [3]: setattr(MyObject,"ret", ret)

In [4]: MyObject().ret()
Out[4]: <test.MyObject at 0x7f6428e8ccd0>

In [5]: MyObject().ret().l
Out[5]: [15]