0

I'm trying to understand the following.

 def exp(**argd):
     print(argd)

  a={1:'a',2:'b'}
  exp(**a)

This will give TypeError: exp() keywords must be strings. 

This is working fine if i use a={'1':'a','2':'b'}. why i can't pass the dictionary key as a number to the exp function ?

Tharanga Abeyseela
  • 3,255
  • 4
  • 33
  • 45

2 Answers2

3

exp(**a) in your example expands literally to exp(1='a', 2='b'), which is an error because integer literals cannot be variable names.

You might think, why doesn't the ** process cast keys into strings as part of the expansion? There's no one singular reason, but in general Python's philosophy is "explicit is better than implicit", and implicit casting can have some pitfalls -- many object types that are distinct from each other, for instance, will cast to the same string, which could cause unintended consequences if you relied on implicit string casting during expansion.

Andrew Gorcester
  • 19,595
  • 7
  • 57
  • 73
  • 1
    neither can `"a variable name"` ... but it would accept that – Joran Beasley Jul 07 '14 at 23:58
  • That's a good point and, actually, something I didn't know until I read your answer. I can only assume that's a loophole or unspecified behavior, and not an acceptable way to create normally invalid variable names! – Andrew Gorcester Jul 08 '14 at 00:02
  • I dont disagree ... but that fact basically invalidates alot of this answer imho (that said its still a solid answer) – Joran Beasley Jul 08 '14 at 00:04
  • you state that its because its a syntax error to use the unpacked variable names ... but it allows an infinitely countable number of impossible variable names ... its just because the python interpreter requires that function keywords are strings ... it has nothing (or at least very little) to do with syntactically correct argument names (it would be trivial for the interpreter to enforce variable naming conventions if that was their intention) – Joran Beasley Jul 08 '14 at 00:10
  • 1
    Yes, I edited the answer to remove the reference to a syntax error as the actual error thrown is a type error. Still, I think that the answer that integer literals and other non-strings cause an exception because they are not suitable as variable names is correct. The fact that the interpreter does not enforce other non-type related constraints on variable names in this case is a strange detail, but I don't think it invalidates the above. – Andrew Gorcester Jul 08 '14 at 00:36
2

because you cannot (Guido is probably the only one who can tell you why) ... it makes them partially adhere to variable naming rules ... the **a_dict unpacks the dict

a={1:'a',2:'b'}
exp(**a)  #is basically exp(1='a',2='b') 

which is obviously a syntax error

although it does allow funny things like

a = {'a variable':7,'some$thing':88}
exp(**a)

as long as they are strings... it seems the only rule they enforce is that they are strings ... this is likely to guarantee that they are hashable(a huge guess...)

disclaimer: this is probably a gross oversimplification

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179