I get an error type object argument after ** must be a mapping, not tuple
.
I have this code: create_character = player.Create(**generate_player.generate())
this is player.py
module:
class Create(object): def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender
this is generate_player.py
module:
import prompt def generate(): print "Name:" name = prompt.get_name() print "Age:" age = prompt.get_age() print "Gender M/F:" gender = prompt.get_gender() return name, age, gender
The prompt
module is just bunch of raw_input
s that return either string or integers (int for age
).
Why is it returning tuples? When I run print type
in generate_player
module I get string, int, string for my arguments.
Unpacking keyword arguments When the arguments are in the form of a dictionary, we can unpack them during the function call using the ** operator. A double asterisk ** is used for unpacking a dictionary and passing it as keyword arguments during the function call.
Tuple packing refers to assigning multiple values into a tuple. Tuple unpacking refers to assigning a tuple into multiple variables.
>>> range ( * args) # call with arguments unpacked from a list. [ 3 , 4 , 5 ] Packing. When we don't know how many arguments need to be passed to a python function, we can use Packing to pack all arguments in a tuple.
Unpacking in Python refers to an operation that consists of assigning an iterable of values to a tuple (or list ) of variables in a single assignment statement. As a complement, the term packing can be used when we collect several values in a single variable using the iterable unpacking operator, * .
The **
syntax requires a mapping (such as a dictionary); each key-value pair in the mapping becomes a keyword argument.
Your generate()
function, on the other hand, returns a tuple, not a dictionary. You can pass in a tuple as separate arguments with similar syntax, using just one asterisk:
create_character = player.Create(*generate_player.generate())
Alternatively, fix your generate()
function to return a dictionary:
def generate(): print "Name:" name = prompt.get_name() print "Age:" age = prompt.get_age() print "Gender M/F:" gender = prompt.get_gender() return {'name': name, 'age': age, 'gender': gender}
You just want a single asterisk:
create_character = player.Create(*generate_player.generate())
You're passing a sequence of arguments, for which you use one asterisk. The double-asterisk syntax is for passing a mapping, for instance to do something like this:
player.Create(**{'name': 'Richie', 'age': 21, 'gender': 'male'})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With