我可以在Python中重新赋值给同一变量吗
我在Python里有一个变量
DATE_FILENAME = datetime.datetime.now().strftime("%b-%d-%Y-%I%M%p")
这个变量应该每次都有不同的值。但是我听说字符串是不可变的,这是不是意味着它只能保存一个值呢?
这是结果 _May-22-2011-1002PM.tar.gz
我的脚本花了3分钟备份8个文件夹,但它们的日期和文件名部分都是一样的。所以我想知道为什么它没有改变。
4 个回答
没错,DATE_FILENAME
一旦被赋值后就会保持一个固定的值,但这和字符串不可变没有关系,这只是 Python 中变量赋值的工作方式。变量其实就是名字,给变量赋值的意思是让计算机计算右边的表达式,然后把结果存储到左边的名字里。
如果你希望每次使用 DATE_FILENAME
时它的值都不一样,你需要的是一种叫做惰性计算值的东西,也就是每次使用时根据赋值表达式重新计算的值(通过引用它)。在 Python 中,最自然的做法是把 datetime.datetime.now().strftime("%b-%d-%Y-%I%M%p")
放到一个函数里。
def datetime_now_in_string():
return datetime.datetime.now().strftime("%b-%d-%Y-%I%M%p")
DATE_FILENAME = datetime_now_in_string()
或者
date_filename = lambda: datetime.datetime.now().strftime("%b-%d-%Y-%I%M%p")
file_name = date_filename() + '.txt'
你明白这个意思了吧。
字符串是不可改变的,但名字绑定是可以改变的。你可以随时给 DATE_FILENAME
赋一个新值。
如果你想让 DATE_FILENAME
每次被使用时都有不同的值,那就有点复杂了。我想你可以通过定义一个类,并重写 __str__()
方法来实现这个功能。
编辑:让我澄清一下:你是在你的模块中定义这个常量一次吗?如果是这样的话,它是不会改变的;每次你想写文件的时候,你都得更新这个名字。一个简单的方法是写一个小函数 get_name
,每次调用它的时候都会生成一个新的名字。
字符串不改变的原因是,如果这段代码是在模块的顶层(没有缩进),那么它只会在模块执行的时候执行一次。之后就不会再改变了。
这和字符串的不可变性是两个不同的问题。
当执行这一行代码时,解释器会查找系统时间,根据 strftime
的字符串参数格式化时间,然后把这个值存储到一个变量里。
这里有一个关于Python中名字绑定的重要点。考虑这一行
foo = 1
你可能会想知道这里背后发生了什么。当解释器看到这一行时,它会做两件事:
- 它创建一个整数对象,并把它存储在某个内部表格里。
- 它把名字
foo
绑定到这个对象;换句话说,它在某个内部表格里记录了foo
代表这个对象的事实。
重要的是,foo
只是我们可能称之为1的对象的一个名字。特别是,你可以通过重新绑定来让 foo
代表其他东西,比如 foo = 2
。但是你不能改变 1
!
同样的道理,你也不能改变你可能创建的日期时间字符串。那个对象是不可变的。但你可以让名字指向不同的字符串,或者实际上是任何类型的不同对象!