我正在设计一个用python玩的策划游戏。但是,当尝试将函数设置为在尝试不完全正确时重复自身时会遇到一些问题。
我的代码分为两部分。对于第一部分,它要求用户输入正确的号码,然后第二个用户尝试输入他的尝试号码。代码的第二部分将其尝试分解为数字列表,并计算正确整数的数量和正确位置的整数数量,然后,如果答案不完全正确,程序将要求用户提供第二个输入。
def getnumber():
predestine = input("Please input your test number")
a = str(predestine)
attempt()
def attempt():
attempt = input("Attempt:")
b = str(attempt)
correctrecord = []
sequencerecord = []
for i in b:
if i in a:
correctrecord.append(1)
for i in range(0,4):
if b[i] == a[i]:
s equencerecord.append(1)
correctlength = len(correctrecord)
sequencelength = len(sequencerecord)
print(f"You have made {correctlength} correct attempts, and of these {sequencelength} are of correct positions")
if sequencelength == 4:
print("You have won, the game is ended")
else:
return attempt()
问题出在最后一个代码上:return try()。似乎无法重复出现带有“ str object not callable”错误的函数。
答案 0 :(得分:3)
代码中的问题在于可变阴影。
您的重复函数位于名为attempt
的变量中,该变量是全局变量。然后,在attempt
函数内部,定义一个attempt
字符串变量,该变量是该函数的局部变量,因此暂时隐藏了保存该函数的全局attempt
变量。
因此,attempt()
调用失败,因为您实际上是在尝试调用字符串。
解决方案是重命名本地字符串变量attempt
,以免隐藏全局变量:
def attempt():
attempt_ = input("Attempt:")
b = str(attempt_)
correctrecord = []
sequencerecord = []
for i in b:
if i in a:
correctrecord.append(1)
for i in range(0,4):
if b[i] == a[i]:
sequencerecord.append(1)
correctlength = len(correctrecord)
sequencelength = len(sequencerecord)
print(f"You have made {correctlength} correct attempts, and of these {sequencelength} are of correct positions")
if sequencelength == 4:
print("You have won, the game is ended")
else:
return attempt()
答案 1 :(得分:0)
您多次使用相同的变量名。 Python函数是一等公民,您可以这样做:
# define a function by name r
def r():
return 1
print(type(r)) # <class 'function'> now r is a function
# reassign name r to be a string
r = "22"
print(type(r)) # <class 'str'> now r is a string
如果您现在r()
,则会得到TypeError: 'str' object is not callable
您的代码使用全局变量,您再次调用自己的函数并使用-这会导致递归溢出-请参见What is the maximum recursion depth in Python, and how to increase it?
计算重复项时正确的“数字”数量时,您将得到错误的结果-尝试将“ 1122”作为正确值,将“ 1234”作为尝试。
无需递归即可编写游戏代码。我对其进行了一些重组,以展示一种不同的方式:
def getnumber(text):
"""Loops until a number is inputted. Returns the number as string.
'text' is the prompt for the user when asking for a number."""
while True:
try:
predestine = int(input(text).strip())
return str(predestine)
except:
print("Only numbers allowed!")
def attempt(correct_number):
"""One game round, returns True if correct result was found."""
attempt = getnumber("Attempt: ")
# avoid double-counting for f.e. 1212 and 1111 inputs
correct_digits = len(set(attempt) & set(correct_number))
sequencelength = 0 # no need to collect into list and use len
for i,c in enumerate(attempt): # simply increment directly
if c == correct_number[i]:
sequencelength += 1
print(f"You have found {correct_digits} correct digits, and of these {sequencelength} are of correct positions.")
if len(attempt) < len(correct_number):
print("Your number has too few digits.")
elif len(attempt) > len(correct_number):
print("Your number has too many digits.")
return correct_number == attempt
# game - first get the correct number
number = getnumber("Please input your test number: ")
# loop until the attempt() returns True
ok = False
while not ok:
ok = attempt(number)
print("You have won, the game is ended")
输出:
Please input your test number: 1234
Attempt: 1111
You have found 1 correct digits, and of these 1 are of correct positions.
Attempt: 1212
You have found 2 correct digits, and of these 2 are of correct positions.
Attempt: 1321
You have found 3 correct digits, and of these 1 are of correct positions.
Attempt: 1234
You have found 4 correct digits, and of these 4 are of correct positions.
You have won, the game is ended