在 Julia 中使用 PyCall.jl 时修改 Python 对象的属性
Modify a Python object's attribute when using PyCall.jl in Julia
我正在尝试通过 PyCall.jl 与 python 库进行交互,其中库 returns 具有我想要的属性的 python 对象(Julia 中的 PyObject)在 Julia 中修改。例如说我有以下虚拟 python class,
import numpy as np
class MyNumpy:
def __init__(self,n,m):
self.array = np.zeros((n,m))
self.size = (n,m)
现在在 Julia 中,我使用 PyCall.jl 加载这个 python class 并实例化,例如:
using PyCall
mynumpy = pyimport("MyNumpy.MyNumpy")
pyobject = mynumpy(3,3)
...
> pyobject.array
> 3×3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
...
pyobject.array[1,1] = 1.0
> pyobject.array
> 3×3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
最后一行代码执行没有任何错误,但是在调查 pyobject.array[1,1]
后,该值没有改变(即保持为 0.0)。
如何在 Julia 中更改 Pycall.jl PyObject 属性值,例如,我可以使用指针来执行此操作吗?如果可以,怎么做? 抱歉,如果这是很明显,但我运气不好,无法使用 PyCall.jl 文档弄清楚如何做到这一点。提前致谢。
P.S。实际的 python 库不是可以轻易修改的东西。
PyCall 默认将对象转换为 Julia 类型(如果它们适当地发出嘎嘎声)。在这种情况下,当您访问 MyNumpy
class 的 array
字段时,就会发生这种情况:它 returns 是一个 numpy 数组,PyCall 会将其转换为 Julian [=14] =] 在边界处。如果您想选择退出该自动转换,您可以使用 uglier, dot-access with a string:
julia> py"""
import numpy as np
class MyNumpy:
def __init__(self,n,m):
self.array = np.zeros((n,m))
self.size = (n,m)
"""
julia> mynumpy = py"MyNumpy"
PyObject <class '__main__.MyNumpy'>
julia> pyobject = mynumpy(3,3)
PyObject <__main__.MyNumpy object at 0x1383398d0>
julia> pyobject.array # converted (copied!) into a Julian Array
3×3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
julia> pyobject."array" # This is the "raw" numpy array!
PyObject array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
现在,您可以在 Python 的列表列表表示中工作,但这很烦人; API 不是最好的,您必须记住基于 0 的行主要实现。 PyCall 有一个很好、方便的助手,它通过 Julian AbstractArray
:
将数组公开为共享内存
julia> array = PyArray(pyobject."array")
3×3 PyArray{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
julia> array[1,1] = 1.0
1.0
julia> array
3×3 PyArray{Float64,2}:
1.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
julia> pyobject.array # remember, this is a copy
3×3 Array{Float64,2}:
1.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
我正在尝试通过 PyCall.jl 与 python 库进行交互,其中库 returns 具有我想要的属性的 python 对象(Julia 中的 PyObject)在 Julia 中修改。例如说我有以下虚拟 python class,
import numpy as np
class MyNumpy:
def __init__(self,n,m):
self.array = np.zeros((n,m))
self.size = (n,m)
现在在 Julia 中,我使用 PyCall.jl 加载这个 python class 并实例化,例如:
using PyCall
mynumpy = pyimport("MyNumpy.MyNumpy")
pyobject = mynumpy(3,3)
...
> pyobject.array
> 3×3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
...
pyobject.array[1,1] = 1.0
> pyobject.array
> 3×3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
最后一行代码执行没有任何错误,但是在调查 pyobject.array[1,1]
后,该值没有改变(即保持为 0.0)。
如何在 Julia 中更改 Pycall.jl PyObject 属性值,例如,我可以使用指针来执行此操作吗?如果可以,怎么做? 抱歉,如果这是很明显,但我运气不好,无法使用 PyCall.jl 文档弄清楚如何做到这一点。提前致谢。
P.S。实际的 python 库不是可以轻易修改的东西。
PyCall 默认将对象转换为 Julia 类型(如果它们适当地发出嘎嘎声)。在这种情况下,当您访问 MyNumpy
class 的 array
字段时,就会发生这种情况:它 returns 是一个 numpy 数组,PyCall 会将其转换为 Julian [=14] =] 在边界处。如果您想选择退出该自动转换,您可以使用 uglier, dot-access with a string:
julia> py"""
import numpy as np
class MyNumpy:
def __init__(self,n,m):
self.array = np.zeros((n,m))
self.size = (n,m)
"""
julia> mynumpy = py"MyNumpy"
PyObject <class '__main__.MyNumpy'>
julia> pyobject = mynumpy(3,3)
PyObject <__main__.MyNumpy object at 0x1383398d0>
julia> pyobject.array # converted (copied!) into a Julian Array
3×3 Array{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
julia> pyobject."array" # This is the "raw" numpy array!
PyObject array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
现在,您可以在 Python 的列表列表表示中工作,但这很烦人; API 不是最好的,您必须记住基于 0 的行主要实现。 PyCall 有一个很好、方便的助手,它通过 Julian AbstractArray
:
julia> array = PyArray(pyobject."array")
3×3 PyArray{Float64,2}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
julia> array[1,1] = 1.0
1.0
julia> array
3×3 PyArray{Float64,2}:
1.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
julia> pyobject.array # remember, this is a copy
3×3 Array{Float64,2}:
1.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0