【问题标题】:Why don't string variables update when they are changed为什么字符串变量在更改时不更新
【发布时间】:2017-02-10 14:39:30
【问题描述】:

假设我们有一些这样的代码:

placehold = "6"
string1 = "this is string one and %s" % placehold

print string1

placehold = "7"
print string1

运行时,两个 print 语句都返回好像 placehold 始终为 6。但是,就在第二个语句运行之前,placehold 更改为 7,那么为什么它没有动态反映在字符串中?

另外,你能建议一种方法让字符串返回 7 吗?

谢谢

【问题讨论】:

  • 字符串是不可变的。他们不会改变。使用 StringVar 之类的东西或重新分配
  • 您需要在更改为placehold 的值后再次执行string1 = "this is string one and %s" % placehold 以使string1 的值发生更改。

标签: python string python-2.7 string-formatting


【解决方案1】:

string1 将使用placehold 在声明string1 时存在的任何值。在您的示例中,该值恰好是"6"。要将string1 设置为“以 7 返回”,您需要在更改 placehold 的值后重新分配它 (string1 = "this is string one and %s" % placehold)。

【讨论】:

    【解决方案2】:

    因为在执行语句后,您已经为该变量赋值。

    听起来你宁愿需要一个函数,例如:

    def f(placehold):
        return "this is string one and %s" % placehold
    

    现在您可以print(f("7")) 来实现所需的功能。

    【讨论】:

      【解决方案3】:

      当你这样做时:

      string1 = "this is string one and %s" % placehold
      

      您正在创建一个字符串string1,其中%s 替换为placehold 的值稍后更改placehold 的值不会对string1 产生任何影响,因为字符串不具有动态变量的属性。为了反映值改变的字符串,您必须再次重新分配字符串。

      或者,您可以将.format() 用作:

      string1 = "this is string one and {}"
      placeholder = 6
      print string1.format(placeholder)
      # prints: this is string one and 6
      
      placeholder = 7
      print string1.format(placeholder)
      # prints: this is string one and 7
      

      【讨论】:

        【解决方案4】:

        字符串是不可变的,无法更改,但是您尝试做的事情也不适用于可变对象,因此可变性(或缺乏可变性)在这里是一个红鲱鱼。

        真正的原因是 Python 不像 Excel 那样工作。对象不会记住对它们执行的所有操作,然后在您更改进入它们的任何信息时重新执行这些操作。为了让 Python 以这种方式工作,该语言需要保留每个对象曾经处于的每个状态,或者曾经对它们执行的所有操作及其参数。要么会让你的程序使用更多的内存并且运行得更慢。最重要的是,假设您在另一个表达式中使用了string1:该值也需要更新。在 Python 3 中,print() 是一个函数;当打印的变量改变时是否应该再次调用它?

        在某种程度上,有些语言可以这样工作,但 Python 不是其中之一。除非您以其他方式明确安排(通过编写和调用函数),否则 Python 会计算一次表达式并使用该确切结果。

        事实上,你想要的在 Python 中是不可能实现的。当您进行字符串插值(% 操作)时,执行它的代码只会看到您正在插值的值。它不知道"6" 来自一个名为placehold 的变量。因此,即使它想更改字符串,它也不能稍后更改,因为它无法知道placeholdstring1 之间有任何关系。 (另外,考虑到您不需要插入单个变量:它可以是诸如 placehold + "0" 之类的表达式。因此 Python 需要记住整个表达式,而不仅仅是变量名,以便稍后重新评估它。)

        您可以编写自己的字符串子类来提供您想要的特定行为:

        class UpdatingString(str):
            def __str__(self):
                return self % placehold
        
        placehold = "6"
        string1 = UpdatingString("this is string one and %s")
        print(string1)
        placehold = "7"
        print(string1)
        

        但这充满了范围问题(基本上,类需要能够看到placehold,这意味着变量和类需要在同一个函数或全局范围内定义)。此外,如果您在与另一个字符串的操作中使用这个特殊字符串,比如连接,它几乎肯定会不再是特殊的。解决这些问题是可能的,但是......毛茸茸的。不推荐。

        【讨论】:

        • 很好的解释和解决方案!
        猜你喜欢
        • 2019-05-29
        • 1970-01-01
        • 2015-03-17
        • 1970-01-01
        • 1970-01-01
        • 2019-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多