2017-09-14 1 views
3

Lorsque vous essayez d'instancier la classe suivante, je reçois l'erreur suivante:Python: définition de classe avec kwargs **

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

Savez-vous quel serait le problème? Voici la définition de la classe:

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) 

Répondre

3

Pour passer schema et de le décompresser dans **kwargs, vous devez utiliser **schema:

db_create_table('Table1', **schema) 

Explication: Le formulaire unique astérisque (*args) décompresse une séquence pour former une liste d'arguments, tandis que la forme à double astérisque (**kwargs) décompresse un objet semblable à un dict en une liste d'arguments indexés.

Sans astérisque, l'objet donné sera directement transmis tel quel, sans aucun déballage.

Voir aussi how to use *args and **kwargs in Python.

+1

En développant cette réponse, vous pourriez aussi écrire (simplifié): 'db_create_table ('Table1', id = 1, col1 = 2, col2 = 3, CreatedOn = '2017-09')' – rocksteady

0

Vous passez deux arguments, mais seulement attraper kwargs.
schema est passé en tant qu'argument de position qui serait intercepté par *args; si on voulait être pris par **kwargs que vous auriez à passer comme argument mot-clé:

db_create_table('Table1', schema=schema) 
+0

La fonction n'a aucun argument appelé "schéma". Peut-être que vous vouliez dire "kwargs = schema"? (Même alors, je pense que vous avez besoin du double astérisque?) – Basya

+0

Il n'a pas d'argument nommé 'schema', non. Il a cependant '** kwargs ', et * tout * passé * argument * nommé va y aller. – deceze

+0

@deceze fait lors du passage schéma = schéma et vous imprimez les variables de classe: test = db_create_table (« Tableau 1 », schéma = schéma) impression vars (test) vous pouvez voir ce schéma est passé comme une chaîne, au lieu d'avoir les clés dict. – Pelican

2

Les kwargs paramètre dans la fonction capture des arguments de mots-clés; vous passez un seul objet sans le déballer. Vous devez soit le passer avec **, soit le décompresser, ou ajouter * args à la définition de la fonction. Par exemple, regardez comment la fonction interprète les arguments:

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

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

sortie:

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

Comme vous passez args de position avec * args, vous pouvez passer args avec mot-clé ** kwargs lorsque vous appelez la fonct.