【问题标题】:Unable to concatenate strings无法连接字符串
【发布时间】:2022-01-04 01:29:50
【问题描述】:

我正在尝试为我制作的密码制作一个编码程序,但我无法连接字符串,这是我的代码:

charToBin = {
  "a":1,
  "b":10,
  "c":11,
  "d":100,
  "e":101,
  "f":110,
  "g":111,
  "h":1000
}
binToWrd = {
  1:"Intel",
  10:"Info",
  11:"Indipendent",
  101:"Imposibble",
  100:"Info-stolen",
  110:"Indian-Ogres",
  111:"Initially",
  1000:"Infant-Orphan-Ogre-Ogle"
}

endTxt = " "
cipher = " "

def txtToBin():

  txt = input(":")
  txtArray = txt.split(" ")
  for x in range(len(txt)):
    endTxt += str(charToBin[txtArray[x]])+" "
  print(endTxt)

def binToCip():
  codeTxtArr = endTxt.split(" ")
  for x1 in codeTxtArr:
    for x2 in binToWrd:
      cipher =+ x1.replace(str(x2), binToWrd[x2])
  print(cipher)

txtToBin()
binToCip()

它返回了这个错误:

Traceback (most recent call last):
  File "main.py", line 40, in <module>
    txtToBin()
  File "main.py", line 30, in txtToBin
    endTxt = endTxt + str(charToBin[txtArray[x]])+" "
UnboundLocalError: local variable 'endTxt' referenced before assignment

谁能解释为什么会发生这种情况以及如何解决它?

【问题讨论】:

    标签: python string encryption concatenation encode


    【解决方案1】:

    或者,您仍然可以在外部初始化 endTxt,只需在您的函数中将其声明为全局(这是否是一个好的做法是一个单独的问题)

    charToBin = {
      "a":1,
      "b":10,
      "c":11,
      "d":100,
      "e":101,
      "f":110,
      "g":111,
      "h":1000
    }
    binToWrd = {
      1:"Intel",
      10:"Info",
      11:"Indipendent",
      101:"Imposibble",
      100:"Info-stolen",
      110:"Indian-Ogres",
      111:"Initially",
      1000:"Infant-Orphan-Ogre-Ogle"
    }
    
    endTxt = " "
    cipher = " "
    
    def txtToBin():
      global endTxt # add this
      txt = input(":")
      txtArray = txt.split(" ")
      for x in range(len(txt)):
        endTxt += str(charToBin[txtArray[x]])+" "
      print(endTxt)
    
    def binToCip():
      global cipher # and this
      codeTxtArr = endTxt.split(" ")
      for x1 in codeTxtArr:
        for x2 in binToWrd:
          cipher += x1.replace(str(x2), binToWrd[x2])
      print(cipher)
    
    txtToBin()
    binToCip()
    
    

    也只是您的charToBin 字典中的一个建议,您不必为每个字母都写下来,只需使用以下代码:

    def char_to_bin(char):
        if char.isalpha():
            num = ord(char.lower()) - 96
            return f"{num:8b}".strip()
        else:
            raise KeyError
    

    解释:
    如果您不熟悉 ASCII,请先查看 here。 ord 函数返回任何字符的 ascii 代码(以 10 为底),我们知道小写字母从 97 开始,所以我们可以从返回值中减去 97,但您从 1 开始计数,所以我们将减去 96。语句有一个 f 字符串,您可以检查 f 字符串 here 的微语法。基本上,f-string 只是将字符的二进制表示转换为字符串,但转换会在未使用的地方添加空格(因为字符串的大小必须为 8,正如我们在 f-string 中声明的那样),所以删除多余的空格 .strip() 被使用。

    【讨论】:

    • 您能解释一下您展示的第二个代码块是如何工作的吗?而且我忘了添加一个重要的部分现在在那里你能再回答一次吗?
    • 我如何在函数中创建全局对象
    • 你使用下面的语法global name_of_variable
    • 我做了那个 global endTxt += str(charToBin[txtArray[x]])+" " 它说语法无效
    • 不,声明全局变量时不能赋值,只需查看答案中的代码即可了解如何实现这一点,但请注意@BrokenBenchmark 这样做的方式更好
    【解决方案2】:

    你需要把endTxt的初始化移到txtToBin()里面:

    def txtToBin():
      endTxt = " "
      txt = input(":")
      txtArray = txt.split(" ")
      for x in range(len(txt)):
        endTxt += str(charToBin[txtArray[x]])+" "
      print(endTxt)
    

    编辑: OP 在最初发布答案后添加了额外的约束。我们可以将变量作为参数传入,解决多个函数共享变量的问题。

    def txtToBin():
      endTxt = " "
      txt = input(":")
      txtArray = txt.split(" ")
      for x in range(len(txt)):
        endTxt += str(charToBin[txtArray[x]])+" "
      return endTxt
    
    def binToCip(endTxt):
      cipher = " "
      codeTxtArr = endTxt.split(" ")
      for x1 in codeTxtArr:
        for x2 in binToWrd:
          cipher += x1.replace(str(x2), binToWrd[x2])
      return cipher
      
    endTxt = txtToBin()
    print(endTxt)
    print(binToCip(endTxt))
    

    【讨论】:

    • 我忘记添加重要的部分现在在那里你能再回答吗?
    • 他们在哪里?
    • =+ 应该是 +=。无论如何,已编辑。
    • 它增加了另一个相同类型的错误
    • 具体是什么错误?我无法产生任何错误。