思考一下下面的代码片段:
def foo(numbers=[]): numbers.append(9) print numbers
在这里,我们定义了一个 list (默认为空),给它加入9并且打印出来。
>>> foo() [9] >>> foo(numbers=[1,2]) [1, 2, 9] >>> foo(numbers=[1,2,3]) [1, 2, 3, 9]
看起来还行吧?可是当我们不输入number 参数来调用 foo 函数时,神奇的事情发生了:
>>> foo() # first time, like before [9] >>> foo() # second time [9, 9] >>> foo() # third time... [9, 9, 9] >>> foo() # WHAT IS THIS BLACK MAGIC?! [9, 9, 9, 9]
那么,这是神马情况?直觉告诉我们无论我们不输入 number 参数调用 foo 函数多少次,这里的9应该被分配进了一个空的 list。这是错的!在Python里,函数的默认值实在函数定义的时候实例化的,而不是在调用的时候。
那么我们仍然会问,为什么在调用函数的时候这个默认值却被赋予了不同的值?因为在你每次给函数指定一个默认值的时候,Python都会存储这个值。如果在调用函数的时候重写了默认值,那么这个存储的值就不会被使用。当你不重写默认值的时候,那么Python就会让默认值引用存储的值(这个例子里的numbers)。它并不是将存储的值拷贝来为这个变量赋值。这个概念可能对初学者来说,理解起来会比较吃力,所以可以这样来理解:有两个变量,一个是内部的,一个是当前运行时的变量。现实就是我们有两个变量来用相同的值进行交互,所以一旦 numbers 的值发生变化,也会改变Python里面保存的初始值的记录。
那么解决方案如下:
def foo(numbers=None): if numbers is None: numbers = [] numbers.append(9) print numbers
通常,当人们听到这里,大家会问另一个关于默认值的问题。思考下面的程序:
def foo(count=0): count += 1 print count
当我们运行它的时候,其结果完全是我们期望的:
>>> foo() 1 >>> foo() 1 >>> foo(2) 3 >>> foo(3) 4 >>> foo() 1
这又是为啥呢?其秘密不在与默认值被赋值的时候,而是这个默认值本身。整型是一种不可变的变量。跟 list 类型不同,在函数执行的过程中,整型变量是不能被改变的。当我们执行 count+=1 这句话时,我们并没有改变 count 这个变量原有的值。而是让 count 指向了不同的值。可是,当我们执行 numbers.append(9) 的时候,我们改变了原有的 list 。因而导致了这种结果。
下面是在函数里使用默认值时会碰到的另一种相同问题:
def print_now(now=time.time()): print now
跟前面一样,time.time() 的值是可变的,那么它只会在函数定义的时候计算,所以无论调用多少次,都会返回相同的时间 — 这里输出的时间是程序被Python解释运行的时间。
>>> print_now() 1373121487.91 >>> print_now() 1373121487.91 >>> print_now() 1373121487.91
* 这个问题和它的解决方案在 Python 2.x 和 3.x 里都是类似的,在Python 3.x 里面唯一的不同,是里面的print 表达式应该是函数调用的方式(print(numbers))。
行动时刻 - 设置变量的默认值 我们并不总是确定变量是否存在。 Unlang为我们提供了语法,以便在变量不存在时指定默认值。 我们将再次通过修改上一个练习来证明这一点。 我们将使用radtest首先在请求中包含Framed-Protocol = PPP,并将其排除在外。 如果Framed-Protocol AVP不存在,我们将返回一个默认字符串。 编辑FreeRADIUS配置目录下的sites-a
本文向大家介绍Python实例变量的默认值,包括了Python实例变量的默认值的使用技巧和注意事项,需要的朋友参考一下 示例 如果变量包含不可变类型的值(例如字符串),则可以分配这样的默认值 在初始化可变对象(例如构造函数中的列表)时,需要小心。考虑以下示例: 此行为是由于以下事实引起的:在Python中,默认参数是在函数执行时绑定的,而不是在函数声明时绑定的。要获得实例之间不共享的默认实例变量,
问题内容: 我正在运行MySql Server 5.7.11,这句话: 是 不是 工作。给出错误: 但是以下内容: 正常工作 。 DATE的情况相同。 作为 附带说明 ,它在MySQL文档中有所提及: DATE类型用于具有日期部分但没有时间部分的值。MySQL检索并以’YYYY-MM-DD’格式显示DATE值。支持的范围是“ 1000-01-01”至“ 9999-12-31”。 即使他们也说: 无
问题内容: 可以为JPA中的列设置默认值吗?如果使用注释,如何做到这一点? 问题答案: 实际上,在JPA中是可能的,尽管使用批注的属性有些小小的改动,例如:
问题内容: 我正在运行一个非常简单的查询,但是对于某些结果,一个字段中的值为空。如果该值为null,如何将其设置为“字符串”? 就像是 它将在sql server 2005上运行 谢谢 问题答案: 使用以下内容: 或@Lieven指出: COALESCE的动态之处在于您可以定义更多的参数,因此,如果第一个为null,则获取第二个参数,如果第二个为null,则获取第三个,依此类推…