Cross Keyword Arguments

I have a class function that should "pass" a particular keyword argument:

def createOrOpenTable(self, tableName, schema, asType=Table): if self.tableExists(tableName): return self.openTable(tableName, asType=asType) else: return self.createTable(self, tableName, schema, asType=asType) 

When I call it, I get this error:

 TypeError: createTable() got multiple values for keyword argument 'asType' 

Is there a way to β€œskip” such a keyword argument?

I thought of a few answers, but none of them are optimal. From worst to best:

  • I can change the keyword name for one or more functions, but I want to use the same keyword for all three functions, since the parameter has the same value.

  • I could pass the asType parameter by position instead of the keyword, but if I add other keyword parameters to openTable or createTable , I will have to remember about changing the calls. I would prefer it to adapt automatically, as if I could use a keyword form.

  • Instead, I could use the **args form to get a dictionary of keyword parameters, rather than using the default parameter, but this is like using a sledgehammer to move a fly (due to extra lines of code, you need to parse it correctly).

Is there a better solution?

+4
source share
3 answers

You are doing it right ... Just take out self in the second function call :)

  return self.createTable(self, tableName, schema, asType=asType) 

it should be:

  return self.createTable(tableName, schema, asType=asType) 
+9
source

I have to say that I first thought of a more complex problem. But the answer of David Wolever is absolutely right. This is just a duplicate of me here, which creates a problem. Thus, the positional parameters go beyond the line, and asType receives the value as an assignment parameter (once) and as a keyword parameter (second time!).

A more interesting problem is what to do when you want to improve the called procedure (createTable in the example) without increasing the intermediate function. Here's the solution ** args does the trick:

For instance:

 def createOrOpenTable(self, tableName, schema, **args): if self.tableExists(tableName): return self.openTable(tableName, **args) else: return self.createTable(tableName, schema, **args) 

This way you can improve the signature of createTable and openTable without changing createOrOpenTable.

When create and openTable can have different keyword parameters, then, of course, both procedures should be defined as follows:

 def createTable(self, tableName, schema, asType=None, **others): ... 

The others parameter absorbs all the parameters of the keyword that are unknown to the method - it also does not need to be evaluated.

+5
source

I would post a comment on a Juergen post, but I need to write some sample code. Here's a slightly more general version:

 def createOrOpenTable(self, tableName, schema, *args, **argd): if self.tableExists(tableName): return self.openTable(tableName, *args, **argd) else: return self.createTable(tableName, schema, *args, **argd) 

This will also allow positional arguments (which is important if you really want it to be cross-cutting.

+5
source

Source: https://habr.com/ru/post/1286472/


All Articles