Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this unpacking of arguments does not work?

Tags:

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_inputs 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.

like image 298
user3056783 Avatar asked Apr 11 '14 10:04

user3056783


People also ask

How do you unpack an argument in Python?

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.

What do you understand by the terms packing and unpacking?

Tuple packing refers to assigning multiple values into a tuple. Tuple unpacking refers to assigning a tuple into multiple variables.

What is packing and unpacking arguments in Python?

>>> 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.

How does unpacking work Python?

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, * .


2 Answers

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} 
like image 200
Martijn Pieters Avatar answered Sep 28 '22 04:09

Martijn Pieters


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'}) 
like image 40
RichieHindle Avatar answered Sep 28 '22 05:09

RichieHindle