【发布时间】:2018-09-10 00:14:43
【问题描述】:
我刚开始学习 Python,并且有足够的能力开始尝试初学者的井字游戏程序。
因此,我的问题是:我想要一个名为 getInput() 的通用输入函数,它将从用户那里获取输入,从该输入中去除尾随空格,然后,如果一个函数通过可选参数传递给它“specialTest”,getInput() 将通过这个提供的函数运行输入,并返回 specialTest 函数吐出的输出。
有时这个 specialTest 函数除了用户输入之外还需要额外的参数。出于我的目的,假设用户输入将始终是第一个参数并且是必需的,并且任何其他参数都会在之后出现。
我尝试通过 *args 来实现这种情况,如果 specialTest 函数没有额外的参数,我就可以正常工作。但是当我第一次尝试向它提供额外的参数时,它失败了。
例如,getInput("Age?", specialTest=int) 有效。它提示用户输入并通过 int() 函数提供输入,最后以整数形式返回输出。但是,当我尝试传递 getInput() 一个具有附加参数的函数时 - 一个包含字符串作为键和字典作为值的有序字典 - 程序失败并出现 TypeTypeError: getInput() got multiple values for argument 'specialTest' 。需要进行哪些调整才能使其按预期工作?
代码:
import collections
def getInput(msg, specialTest=None, *TestArgs):
"""Get user input and export to the desired format."""
while True:
string = input(msg + ' ').strip()
# If the user passed a function to the SpecialTest parameter,
# pass the user input through that function and return its value.
# If the SpecialTest function returns False or we hit an error,
# that means the input was invalid and we need to keep looping
# until we get valid input.
if specialTest:
try:
string = specialTest(string, *TestArgs)
if string is False: continue
except:
continue
return string
def nametoMove(name, board):
"""Convert player's move to an equivalent board location."""
location = {name: theBoard.get(name)}
# return false if the location name isn't present on the board
if location[name] is None:
return False
return location
# ---Tic-Tac-Toe routine---
# fill the board
row_name = ('top', 'mid', 'lower')
col_name = ('left', 'center', 'right')
theBoard = collections.OrderedDict()
size = 3 # 3x3 board
for x in range(size):
for y in range(size):
key = row_name[x] + ' ' + col_name[y]
value = {'row': x, 'col': y}
theBoard.update({key: value})
# get player's desired board symbol
playerSymbol = getInput("X's or O's?")
# get player's age
playerAge = getInput("Age?", specialTest=int)
# get player's move and convert to same format as theBoard object
# e.g., "top left" --> {'top left': {'row': 0, 'col': 0}}
playerMove = getInput("Move?", specialTest=nametoMove, *theBoard)
【问题讨论】:
-
Python 不喜欢关键字参数 (
specialTest=nametoMove) 之后的位置参数 (如*theBoard)。将specialTest=nametoMove更改为nametoMove即可。 -
您能否展示您期望调用
specialTest的样子?也就是说,您希望它是specialTest('top', 'left', 2)还是什么?看起来您正在尝试传递关键字参数(因为theBoard是一个字典),但是您的键中有空格。 -
如果您总是要在调用中使用参数列表(例如
getInput ("Move?", specialTest=nametoMove, *theBoard))而不是多个单独的值,您可能根本不想要*args.只需将一个称为specialArgs的序列作为一个普通的参数,并按原样传递theBoard而不是*theBoard。 (这有一个额外的好处,您可以在调用函数时使用specialArgs作为关键字。) -
同时,
theBoard是一个OrderedDict。虽然您可以使用*theBoard来表达它,但您所做的只是将键作为位置参数传递,而不是将键值对作为关键字参数传递。这是你想要的吗? -
@BrenBarn,当我调用实际的 nametoMove() 函数时,它需要一个字符串和一个有序字典。然后它检查有序字典是否包含与字符串匹配的任何键,如果是,则返回该字典项。例如,
nametoMove("top left", theBoard))将返回{'top left': {'row': 0, 'col': 0}},因为与Board 字典中的“左上”键匹配的值是{'row': 0, 'col': 0}
标签: python python-3.x typeerror args