gpt4 book ai didi

python - 如何设置代理对象的可下标属性的元素值

转载 作者:行者123 更新时间:2023-12-01 06:56:51 25 4
gpt4 key购买 nike

我用过这个stackoverflow question尝试实现一个管理自定义对象属性写入的manager对象。我知道我需要通过在我的文件中定义 _exposed_ 来公开像 __getattribute____setattr____delattr__ 这样的神奇方法。代理类。但是,当我尝试设置自定义对象的可下标属性的元素值时,它保持不变。

查看multiprocessing文档,我在任何地方都找不到前面提到的帖子中提到的multiprocessing.managers子类NamespaceProxy。我一方面可以导入它;另一方面我可以导入它。但是,我一直怀疑它没有正确实现。

以下是我尝试更改归因于自定义类的对象的数组元素的值的方法:

from multiprocessing.managers import BaseManager, NamespaceProxy
import numpy as np

class TestClass(object):
def __init__(self, a):
'''
Args:
a (np.ndarray): the array that needs to be changed
'''
self.a = a

class TestProxy(NamespaceProxy):
# exposes the magic methods for TestProxy objects needed for setting their attributes
_exposed_ = ('__getattribute__', '__setattr__', '__delattr__')

class MyManager(BaseManager):
pass

if __name__ == '__main__':
MyManager.register('test', TestClass, TestProxy)
manager = MyManager()
manager.start()

arr = np.array([0,0,0,0])
managed_obj = manager.test(arr)
managed_obj.a[0] = 1

print(managed_obj.a)

# Console: [0 0 0 0]

# Expected ouput: [1 0 0 0]

编辑:我能够使用类似的内容更改a的实际值

arr2 = np.array([0])
managed_obj.a = arr2
print(managed_obj.a)

# Console : [0]

但是,我仍然不知道如何更改a元素的值。

最佳答案

我还没有弄清楚如何(或是否)通过某种通用的 __setitem__ 方法来实现这一点 - 我最初的目标 - 但这里是如何定义一个自定义方法(名为 my_setitem() 下面)似乎能够更改数组中索引元素的值。

它不允许您按照自己的意愿直接更改代理对象的可订阅属性的值,但它确实展示了一种更改它们的方法。

我认为这将在 Python 3.7 中工作,因为我试图避免做任何只在 v3.8 中工作的事情有一个异常(exception),即这个 new feature添加到 f 字符串支持对于调试来说非常方便 - 但如果需要的话,它应该相对容易删除/替换。

from multiprocessing.managers import BaseManager, NamespaceProxy
import numpy as np

from functools import partial
print = partial(print, flush=True) # Change default.


class TestClass(object):
def __init__(self, a):
'''
Args:
a (np.ndarray): the array that needs to be changed
'''
print(f'TestClass.__init__ called, {a = }')
self.a = a

def my_setitem(self, name, index, value):
print(f'in TestClass.my_setitem()')
attr = getattr(self, name)
attr[index] = value


class TestProxy(NamespaceProxy):
# exposes the magic functions for TestProxy objects needed for setting their attributes
_exposed_ = ('__getattribute__', '__setattr__', '__delattr__', 'my_setitem')

def my_setitem(self, name, index, value):
print(f'in TestProxy.my_setitem()')
callmethod = object.__getattribute__(self, '_callmethod')
return callmethod('my_setitem', (name, index, value))


class MyManager(BaseManager):
pass


if __name__ == '__main__':
MyManager.register('Testclass', TestClass, TestProxy)
manager = MyManager()
manager.start()

arr = np.array([0,0,0,0])
print(f'calling manager.Testclass(arr)')
managed_obj = manager.Testclass(arr)
print(f'result: {managed_obj = }')
print()

# managed_obj.a[0] = 42 # The problem, doesn't work.
name = 'a'
index = 1
# index = slice(0, 2) # slices also work
print(f'executing managed_obj.my_setitem({name=}, {index=}, 42)')
managed_obj.my_setitem(name, index, 42)

print(f'result: {managed_obj.a = }') # -> result: managed_obj.a = array([ 0, 42, 0, 0])

这是它产生的输出(在我的系统上使用 Py 3.8.0 运行):

calling manager.Testclass(arr)
TestClass.__init__ called, a = array([0, 0, 0, 0])
result: managed_obj = <TestProxy object, typeid 'Testclass' at 0x4b3f520>

executing managed_obj.my_setitem(name='a', index=1, 42)
in TestProxy.my_setitem()
in TestClass.my_setitem()
result: managed_obj.a = array([ 0, 42, 0, 0])

关于python - 如何设置代理对象的可下标属性的元素值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58775802/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com