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

Python 返回完整表达式,或返回存储在变量中的值,python,return,return-value,pep,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 如您所见,在第一种情况下,返回完整的表达式,而在第二种情况下,首先计算

我正在查看一些代码,发现以下行:

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
如您所见,在第一种情况下,返回完整的表达式,而在第二种情况下,首先计算表达式并将其存储到变量中,然后返回变量。我的问题是,哪种方式更好,更像蟒蛇的方式

我不完全确定Python如何处理函数返回。它是通过引用返回还是直接返回值?它是否解析表达式并返回该表达式?总之,将表达式的值存储到变量中并返回变量是更好的方法,还是将表达式作为一个整体返回也是非常高效和明智的方法

它是否通过引用返回[?]

实际上是的。返回对象时,函数内对象的id(即内存地址)与函数外对象的id相同。它不会复制什么东西

[…]还是直接返回值

如果你是说,它是否像许多编程语言的“按值传递”参数传递系统,复制一个新值,对新值的更改不会影响原始值?除了返回值而不是传递值之外,不,不是这样的。Python不会复制任何东西,除非您明确告诉它

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

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

当您定义了一个函数但尚未执行它时,该函数中的表达式将不会被解析,即使Python必须通过这些行来创建函数对象 当您创建一个lambda对象,但尚未执行它时。。。等等。 总之,将表达式的值存储到变量中并返回变量是更好的方法,还是将表达式作为一个整体返回也是非常高效和明智的方法

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

第二个函数比第一个函数稍慢,因为它需要为变量名分配空间,并在函数结束时取消分配。因此,您也可以使用第一种方法,节省一行代码和百万分之一秒的运行时间

下面是使用以下不同方法的两个函数的字节码分解示例:

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\u表达式和RETURN\u变量代码。

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

《PEP8风格指南》除了与您的回报声明保持一致外,并没有真正说明这一点

在返回语句中保持一致。函数中的所有return语句都应该返回表达式,或者都不应该返回。如果任何return语句返回表达式,则未返回值的任何return语句都应显式地将其声明为return None,如果可以访问,则应在函数末尾显示显式的return语句


根据pep8,在返回声明中保持一致。函数中的所有return语句都应该返回表达式,或者都不应该返回。如果任何return语句返回表达式,则任何未返回值的return语句都应显式地将其声明为return None,并且函数末尾应存在一个显式return语句I将保留第一个语句,并将第二个语句重新写入为return sumlent>6(对于t in tokens/nro_tokens)