对于以下代码,在我看来,我们将打印功能分配给变量垃圾邮件。
spam = print('Hello!')
我想知道为什么不拨打垃圾邮件,打印出“你好!”?
答案 0 :(得分:4)
因为spam
不是函数,所以它是调用print
函数的结果'Hello!'
,None
,类型为NoneType
}。
如果要将该表达式分配给变量,则可以使用lambda:
l = lambda: print('Hello!') # Doesn't actually call print
l() # 1. Prints 'Hello!'
l() # 2. Prints 'Hello!'
l() # 3. Prints 'Hello!'
答案 1 :(得分:0)
spam = print('Hello!')
评估右侧的表达式并将其值绑定到spam
。 (Python 3)print()
函数的返回值为None
,因此spam
引用None
:
>>> spam = print('Hello!')
Hello!
>>> spam is None
True
处理此问题的一种方法是使用functools.partial()
创建部分函数:
>>> from functools import partial
>>> spam = partial(print, 'Hello!')
>>> spam
functools.partial(<built-in function print>, 'Hello!')
>>> spam()
Hello!
或lambda
表达式:
>>> spam = lambda : print('Hello!')
>>> spam
<function <lambda> at 0x7f619cabf9d8>
>>> spam()
Hello!
基本上上面两个都使用围绕这样的函数的闭包:
def printer(s):
def f():
print(s)
return f
>>> spam = printer('Hello!')
>>> spam
<function printer.<locals>.f at 0x7f619cabfb70>
>>> spam()
Hello!
答案 2 :(得分:0)
根据函数的编写方式,函数可能有也可能没有显式返回值。由函数的作者决定他想如何实现他的功能。具有显式返回值的函数必须包含return
语句。 return
语句导致函数结束,并且return
语句后面的值被“返回”到调用代码。当函数到达其代码的末尾而没有实际的return
语句时,就像最后有一个隐式return None
。所以......
def is_5(num):
if num is 5:
return True
上面发生了什么?如果num为5,则该函数返回布尔值True。但是如果num不是5,则没有最终return
语句,因此返回隐式None
。
关于你的问题,函数的“名称”和调用函数之间也存在差异。在上面的示例中,函数的“名称”是is_5
,我们通过使用带括号的函数名称来调用它。如果函数名后面没有括号,那么函数名就像任何其他变量一样,只有它才能保存对函数的引用。当您使用括号跟随它时,会导致调用该函数。这就是为什么我们可以打电话
is_5(2+3)
但我们也可以说:
myfunc = is_5
myfunc(2+3)
并获得相同的结果。对于lambda
和functools.partial
,两者都用于创建所谓的“无名”函数 - 它们返回对函数的引用,但该函数没有名称。您可以捕获其中任何一个的返回值并将其存储在变量中。然后,您可以通过使用括号跟随变量的名称来调用该函数,就像上面一样。请记住,在使用括号调用函数之前,函数不会运行。所以,例如:
mylambda = lambda x: True if x is 5 else None
mylambda(1+4)
说完这一切之后,关于你的问题,变量spam
得到print()
函数的返回值(如果有的话)。 print()
没有返回值,因此为spam
分配值None
。如果您想将打印功能的引用分配给spam
,您可以说:
spam = print
然后你可以说
spam("Hello!")
你会得到你的“你好!”当时打印在屏幕上的字符串。
此外,具有返回值并将字符串打印到屏幕或终端是两回事。一个函数可以同时执行这两个操作,也可以同时执行这两个操这完全取决于编码员想要完成的任务。