我正在尝试通过PyCall.jl与python库进行接口,其中该库返回一个带有我想在Julia中修改的属性的python对象(Julia中的PyObject)。例如说我有以下虚拟python类,
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类并实例化,如下所示:
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文档弄清楚该怎么做。提前致谢。
附言实际的python库不是很容易修改的东西。
最佳答案
PyCall默认将对象适当地转换为Julia类型。在这种情况下,当您访问array
类的MyNumpy
字段时就会发生这种情况:它返回一个numpy数组,PyCall会将其转换为边界处的Julian Array
。如果要退出自动转换,可以使用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的list-of-lists表示形式内工作,但这很烦人。该API并不是最好的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
关于python - 在Julia中使用PyCall.jl时修改Python对象的属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58698393/