# Julia vs. Python: \*\*kwargs

**URL:** <https://discourse.julialang.org/t/julia-vs-python-kwargs/10491>\
**Category:** New to Julia\
**Tags:** python, kwargs\
**Created:** [April 23, 2018, 2:46pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491 "2018-04-23T14:46:40Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 23, 2018, 2:46pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/1 "2018-04-23T14:46:41Z")

</div>

I’m looking into interfacing Julia to another language with different rules for identifiers. Specifically, e.g., “m.R” would be a valid identifier in this other language. In the past, I’ve worked with this problem for Python. In Python, suppose I define a function:

```python
def my_func (** kwargs):
  return kwarg

```

then I get the following behavior:

```python
my_func (a=2, b=3)

```

leads to `{’a’: 2, ’b’: 3}`, and

```python
D = {"a":2, "b": 3}
my_func(**D)

```

leads to `{’a’: 2, ’b’: 3}` .

Similarly, `my_func(m.R = 8.31)` crashes in Python – because “m.R” is an illegal identifier, while:

```python
D = {"m.R":8.31}
my_func(**D)

```

gives the desired result: `{'m.R':8.31}`.

Thus: for those identifiers in this other language that are valid Python (or: Julia) identifiers, I can use keyword assignment when calling the function. For those identifiers that are _invalid_ Python identifiers, I can resort to this “dirty” trick of specifying the identifiers as dictionary keys (where any string is valid).

Is there a similar trick in Julia?

-B

---

<div class="post-metadata">

**Author:** ![gabrielgellner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gabrielgellner/32/75_2.png) [@gabrielgellner](https://discourse.julialang.org/u/gabrielgellner)\
**Post date:** [April 23, 2018, 3:01pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/2 "2018-04-23T15:01:35Z")

</div>

You can get the \*args, and \*\*\*kwargs in Julia by doing

```julia
function my_func(args... ; kwargs...)
end

```

which will fill `kwargs` with a dictionary like you would expect. I am not sure you can do the trick with the string keys as kwargs keys must be a `Symbol` so the dotted part is not legal. I am sure some macro tricks could get around this, but likely better to just use an underscore instead of a dot.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [April 23, 2018, 3:08pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/3 "2018-04-23T15:08:47Z")

</div>

Note that the type of `kwargs` will be different between Julia 0.6 and master:

```julia
getkwargs(; kwargs...) = kwargs

```

On 0.6:

```julia
julia> getkwargs(a = 1, b = 2)
2-element Array{Any,1}:
 (:a, 1)
 (:b, 2)

```

On master:

```julia
julia> getkwargs(a = 1, b = 2)
pairs(::NamedTuple) with 2 entries:
  :a => 1
  :b => 2

```

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [April 23, 2018, 4:29pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/4 "2018-04-23T16:29:10Z")

</div>

As tkoolen already answered: Symbols may contain a lot of invalid julia identifiers. On 0.62:

```julia
bar(; kwargs...)=@show kwargs
julia> bar(; kwargs...)=@show kwargs;
julia> bar(a=1, b=2);
kwargs = Any[(:a, 1), (:b, 2)]
julia> bar(;(:a,1), (Symbol("b"),2), (Symbol("a.b = 54"),3));
kwargs = Any[(:a, 1), (:b, 2), (Symbol("a.b = 54"), 3)]
julia> Symbol("foo\0bar")
ERROR: ArgumentError: Symbol name may not contain \0

```

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [April 23, 2018, 4:46pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/5 "2018-04-23T16:46:28Z")

</div>

Note that this example throws an error on Julia master.

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [April 23, 2018, 4:56pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/6 "2018-04-23T16:56:42Z")

</div>

I don’t know if this will work with your interface, but you might use `Pair`s

On a recent version of Julia v0.7 …

```julia
julia> f(;kwargs...) = @show kwargs
f (generic function with 1 method)

julia> f(:a=3)
ERROR: syntax: keyword argument is not a symbol: ":a"

julia> g(kwargs::Pair...) = @show kwargs
g (generic function with 1 method)

julia> g(:a => 1)
kwargs = (:a=>1,)
(:a=>1,)

julia> g(:a => 1, Symbol("R.m") => 2)
kwargs = (:a=>1, Symbol("R.m")=>2)
(:a=>1, Symbol("R.m")=>2)

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 23, 2018, 7:32pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/7 "2018-04-23T19:32:38Z")

</div>

OK…

```julia
function my_func(;kwargs...)
return kwargs
end

```

leads to `my_func(a=1,b=2)` returns a dictionary. Which I guess implies that internally, the kwargs are interpreted as a Dict. But I also need to _alternatively_ use a Dict as an argument, and have it come through the call in the form of a Dict.

Perhaps I need to have two methods for this, and rely on dispatching?

Regarding symbols, and, e.g., “m.R”… my understanding is that the syntax:

- :(expression) really means an unevaluated expression, and it is only in the case that “expression” equals a valid identifier that this is equal to a symbol. In other words… :(m.R) is _not_ a symbol.
- in general, Symbol(string) creates a symbol for anything within the string, e.g., Symbol(“m.R”) gives the symbol.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 23, 2018, 7:42pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/8 "2018-04-23T19:42:40Z")

</div>

Ooops… `my_func(a=1,b=2)` returns an _array of pairs_, `[(:a,1), (:b,2)]` – more or less. **Not** a Dict…

On the other hand, `Dict(my_func(a=1,b=2))` returns the Dict…

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [April 23, 2018, 7:51pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/9 "2018-04-23T19:51:23Z")

</div>

The equivalent to python’s `foo(**D)` in Julia is `foo(;D...)` in which `D` is a collection of `Pairs` (a Dict with Symbol keys will work, as will a vector of `Pair{Symbol, whatever}`. For example, on Julia v0.7 master:

```julia
julia> f(;kw...) = kw
f (generic function with 1 method)

julia> f(hello=1, world=2)
pairs(::NamedTuple) with 2 entries:
  :hello => 1
  :world => 2

julia> D = [:hello => 1, :world => 2]
2-element Array{Pair{Symbol,Int64},1}:
 :hello => 1
 :world => 2

julia> f(;D...)
pairs(::NamedTuple) with 2 entries:
  :hello => 1
  :world => 2

julia> D = Dict([:hello => 1, :world => 2])
Dict{Symbol,Int64} with 2 entries:
  :hello => 1
  :world => 2

julia> f(;D...)
pairs(::NamedTuple) with 2 entries:
  :hello => 1
  :world => 2

```

and using this syntax you can pass arguments with keys that are not valid identifiers:

```julia
julia> f(;[:hello => 1, Symbol("@boo") => 2]...)
pairs(::NamedTuple) with 2 entries:
  :hello => 1
  Symbol("@boo") => 2

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 23, 2018, 8:35pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/10 "2018-04-23T20:35:16Z")

</div>

Thanks! Looks nice!

This doesn’t work in Julia 0.6.2, as far as I can see. But good to know that it is coming!

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 23, 2018, 8:54pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/11 "2018-04-23T20:54:00Z")

</div>

Ooops, I did it again :-). It _does_ work in Julia 0.6.2…

```julia
julia> my_func(;kw...)=kw

```

and:

```julia
julia> my_func(a=1,b=2)
2-element Array{Any,1}:
 (:a, 1)
 (:b, 2)

```

while:

```julia
julia> my_func(;[(:a,1),(:b,2)]...)
2-element Array{Any,1}:
 (:a, 1)
 (:b, 2)

```

and

```julia
julia> my_func(;Dict([(:a,1),(:b,2)])...)
2-element Array{Any,1}:
 (:a, 1)
 (:b, 2)

```

Finally:

```julia
julia> my_func(;[(Symbol("m.R"),8.31),(Symbol("diff(T,x)"),3)]...)
2-element Array{Any,1}:
 (Symbol("m.R"), 8.31)
 (Symbol("diff(T,x)"), 3)

```

So – I guess the change in Julia v. 0.7/1.0 will be that instead of 2-element array, the result will be pairs.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 24, 2018, 7:34am UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/12 "2018-04-24T07:34:31Z")

</div>

So – essentially, in Julia v.0.6.2, using keyword assignment passes the arguments as a vector of pairs (tuple) of symbol + value. Right? Like in:

```julia
julia> c = my_func(a=1,b=2)

```

leads to the vector `[(:a,1),(:b,2)]`, and I can convert the vector to Dict, say, `d = Dict(c)` and refer to the values as, e.g., `d[:a]`…

While in Julia v.0.7, the result is a Named Tuple?? Does that mean that in Julia v. 0.7, if I do the same as above, I can directly refer to `c[:a]`?

Another thing… I tested the following in v.0.6.2:

```julia
julia> my_func(a=1,b=2,a=3)

```

with result `[(:a,1), (:b,2), (:a,3)]`. It is not clear to me how a function would treat this wrt. the value of `:a`.

-B

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 26, 2018, 4:31am UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/13 "2018-04-26T04:31:48Z")

</div>

> [@BLI](#):
>
> While in Julia v.0.7, the result is a Named Tuple?? Does that mean that in Julia v. 0.7, if I do the same as above, I can directly refer to c[:a]?

I think so… see this:

```julia
julia> r = my_func(a=1,b=2)
pairs(::NamedTuple) with 2 entries:
  :a => 1
  :b => 2

julia> r[:a]
1

julia> r[:b]
2

```

Let’s try the duplicate key case. It’s fixed!

```julia
julia> r = my_func(a=1,b=2,a=3)
ERROR: syntax: keyword argument "a" repeated in call to "my_func"

```

Note: I’m using a nightly build that’s several weeks old.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 26, 2018, 10:21am UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/14 "2018-04-26T10:21:18Z")

</div>

Thanks, tk3369!

Out of curiosity…

- How does named tuples work in v.0.7? (The same way as in v.0.6.2? Or a simpler way? Do one still have to use the NamedTuples package? And the same macro system to define the named tuples?)

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 26, 2018, 10:22am UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/15 "2018-04-26T10:22:30Z")

</div>

```julia
julia> c = (a=3, b=2)
(a = 3, b = 2)

julia> c.a
3

julia> c.b
2

julia> c[:a]
3

julia> c[:b]
2

```

No package needed.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 26, 2018, 10:39am UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/16 "2018-04-26T10:39:39Z")

</div>

Beautiful! But doesn’t work in v. 0.6.2… can’t wait for v. 0.7 (I’m not a solid computer scientist, so I’ll wait for the official release…)

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 26, 2018, 12:06pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/17 "2018-04-26T12:06:07Z")

</div>

Ah. Yes, beautiful…

This is similar keyword assignment in function calls.

BUT: what if I have “keywords” that are not proper Julia identifiers? The same trick as with function calls?

```julia
kw = [Symbol("m.T") => 5]
ntup = (;kw...)

```

1. If so, can elements be addressed as attribute, e.g, like `c.b`? How?
2. If have symbols such as `"US$"` (interpolation `$`?) or `"\frac{x}{y}"` (escape symbols?), what then?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 26, 2018, 12:17pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/18 "2018-04-26T12:17:29Z")

</div>

```julia
julia> kw = [Symbol("us\$") => 5]
1-element Array{Pair{Symbol,Int64},1}:
 Symbol("us$") => 5

julia> ntup = (;kw...)
(us$ = 5,)

julia> getfield(ntup, Symbol("us\$"))
5

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [April 26, 2018, 12:49pm UTC](https://discourse.julialang.org/t/julia-vs-python-kwargs/10491/19 "2018-04-26T12:49:13Z")

</div>

Great. I love it when it is systematic :-).

Presumably also:

```julia
ntup[Symbol("us\$")]
5

```
