返回完整的表达式,或返回存储在变量中的值

时间:2018-02-06 13:13:46

标签: python return return-value pep

我正在查看一些代码并找到以下几行:

def get_char_count(tokens):
    return sum(len(t) for t in tokens)


def get_long_words_ratio(tokens, nro_tokens):
    ratio = sum(1 for t in tokens if len(t) > 6) / nro_tokens
    return ratio

如您所见,在第一种情况下返回完整表达式,而在第二种情况下,首先计算表达式并将其存储到变量中,然后返回该变量。我的问题是,哪种方式更好,更pythonic方式?

我不完全确定Python如何处理函数的返回。它是通过引用返回,还是直接返回值?它会解析表达式并返回吗?总之,将表达式的值存储到变量并返回变量是否更好,或者将表达式作为一个整体返回也是完全正常的(效率和PEP方式)?

2 个答案:

答案 0 :(得分:1)

  

是否以参考文献[?]

返回

有效的是。返回对象时,函数内对象的id(即内存地址)与函数外部对象的id相同。它不会制作副本或任何东西。

  

[...]还是直接返回值?

如果你说“它是否像'pass-by-value'参数传递了许多编程语言的系统,在那里制作副本并且对新值的更改不会影响原始值?除了返回价值而不是传递它们?“,然后不,它不是那样的。除非你明确说明,否则Python不会复制任何内容。

  

它是否解析表达式并返回?

是。表达式几乎总是立即解决。不包含的时间

  • 当你定义了一个函数(但还没有执行它)时,即使Python必须“传递”这些行以创建函数对象,该函数中的表达式也不会得到解析
  • 当你创建一个lambda对象时,(但还没有执行它),......等等。

  

总之,将表达式的值存储到变量并返回变量是否更好,或者将表达式作为一个整体返回是否完全正常(效率和PEP)?

从功能之外的任何代码的角度来看,两种方法完全相同。您无法区分“返回的表达式”和“返回的变量”,因为它们具有相同的结果。

你的第二个函数比第一个稍慢,因为它需要为变量名分配空间并在函数结束时释放它。所以你也可以使用第一种方法,为自己保存一行代码和百万分之一秒的运行时间。

以下是使用这些不同方法的两个函数的字节代码的示例细分:

def f():
    return 2 + 2

def g():
    x = 2 + 2
    return x

import dis
print("Byte code for f:")
dis.dis(f)

print("Byte code for g:")
dis.dis(g)

结果:

Byte code for f:
  2           0 LOAD_CONST               2 (4)
              2 RETURN_VALUE
Byte code for g:
  5           0 LOAD_CONST               2 (4)
              2 STORE_FAST               0 (x)

  6           4 LOAD_FAST                0 (x)
              6 RETURN_VALUE

请注意,它们都以RETURN_VALUE结尾。没有单独的RETURN_EXPRESSIONRETURN_VARIABLE代码。

答案 1 :(得分:0)

虽然我更喜欢第一种方法(因为它使用较少的内存),但两种表达式在行为上是等效的。

PEP8样式指南并没有真正说明这一点,除了与你的回复陈述一致。

  

在回复陈述中保持一致。函数中的所有return语句都应该返回一个表达式,或者它们都不应该返回。如果任何return语句返回一个表达式,那么任何没有返回值的return语句都应该明确地将其声明为return None,并且在函数末尾应该有一个显式的return语句(如果可以访问)。