Any object that iterates can be destructured on assignment. You can see a draft I wrote for the docs here: https://github.com/JuliaLang/julia/pull/30579/files (you’ve motivated me to polish it up, any thoughts or feedback would be appreciated).
In numpy, iterating over an n-dimensional array iterates over (n-1)-dimensional arrays. In Julia, iterating over an array iterates over the elements. There is eachcol/eachrow which gives you an iterator over each column/row:
julia> A = rand(3,2)
3×2 Array{Float64,2}:
0.607359 0.239138
0.695322 0.581047
0.774758 0.333456
julia> y,x = eachcol(A)
Base.Generator{Base.OneTo{Int64},Base.var"#179#180"{Array{Float64,2}}}(Base.var"#179#180"{Array{Float64,2}}([0.6073594183138431 0.23913800932018425; 0.695321894908304 0.5810467945907654; 0.7747577825874581 0.33345565551241685]), Base.OneTo(2))
julia> y
x3-element view(::Array{Float64,2}, :, 1) with eltype Float64:
0.6073594183138431
0.695321894908304
0.7747577825874581
julia> x
3-element view(::Array{Float64,2}, :, 2) with eltype Float64:
0.23913800932018425
0.5810467945907654
0.33345565551241685
Note that x and y here are views, not copies like numpy. To get that you can broadcast copy over the iterator:
julia> y,x = copy.(eachcol(A))
2-element Array{Array{Float64,1},1}:
[0.6073594183138431, 0.695321894908304, 0.7747577825874581]
[0.23913800932018425, 0.5810467945907654, 0.33345565551241685]
julia> y
x3-element Array{Float64,1}:
0.6073594183138431
0.695321894908304
0.7747577825874581
julia> x
3-element Array{Float64,1}:
0.23913800932018425
0.5810467945907654
0.33345565551241685