Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python : class definition with **kwargs

When trying to instantiate the following class I am getting the following error :

"TypeError: __init__() takes exactly 2 arguments (3 given)"

Do you know what would be the issue ? Here is the class definition :

class db_create_table():
        '''
            doc here
        '''
        def __init__(self,TableName, **kwargs ):
            self.TableName = TableName
            for k,v in kwargs.iteritems():
                setattr(self, k, k)


schema =  {"id" : { "type":"Integer", "primary":"primary_key=True", "unique":"unique = True"},
           "col1" :  { "type":"String()", "primary":"primary_key=False", "unique":"unique = True"},
           "col2" :  { "type":"String()", "primary":"primary_key=False", "unique":"unique = False"},
           "col3" :  { "type":"String()", "primary":"primary_key=False", "unique":"unique = False"},
           "col4" :  { "type":"String()", "primary":"primary_key=False", "unique":"unique = False"},
           "CreatedOn" :  { "type":"DateTime", "primary":"", "unique":"unique = False"},
           "UpdatedOn" :  { "type":"DateTime", "primary":"primary_key=False", "unique":"unique = False"},
                            }


db_create_table('Table1', schema)
like image 964
Pelican Avatar asked Sep 14 '17 07:09

Pelican


2 Answers

In order to pass schema and to unpack it into **kwargs, you have to use **schema:

db_create_table('Table1', **schema)

Explanation: The single asterisk form (*args) unpacks a sequence to form an argument list, while the double asterisk form (**kwargs) unpacks a dict-like object to a keyworded argument list.

Without any asterisk, the given object will directly passed as it is, without any unpacking.

See also how to use *args and **kwargs in Python.

like image 93
glglgl Avatar answered Oct 09 '22 21:10

glglgl


The kwargs parameter in the function is capturing keyword arguments; you are passing a single object without unpacking it.

You either need to pass it with **, so it gets unpacked, or add *args to the function definition. For example, look how the function interprets the arguments:

def func(*args, **kwargs):
    print args
    print kwargs

func(arg)
func(*arg)
func(*arg, keyword='key')

output:

(('one', 'two'),)  -- passed as arg, single element
{}
('one', 'two')  -- passed as *arg - object is unpacked
{}
('one', 'two')
{'keyword': 'key'}  -- keyword arg looks like that

As you pass positional args with *args, you can pass keyword args with **kwargs when calling the func.

like image 25
Chen A. Avatar answered Oct 09 '22 21:10

Chen A.