#python #multiprocessing
#python #многопроцессорная обработка
Вопрос:
Я не смог найти никаких ответов на этот вопрос, но я думаю, что я не первый, кто задает этот вопрос. Так что, если он двойной — пожалуйста, простите меня 🙂
Этот код:
from multiprocessing import Manager
manager = Manager()
global_vars = manager.Namespace()
global_vars.x = 0
global_vars.y = True
global_vars.z = "hello"
print(global_vars)
С принтами:
Namespace(x=0, y=True, z='hello')
Если я использую этот объект пространства имен в другом процессе (используя многопроцессорную обработку), можно выполнять итерации по объекту пространства имен, не зная, какие переменные там находятся? Итак, что-то вроде:
for var in global_vars:
print(var)
Комментарии:
1. Может
for var in vars(global_vars)
быть?2. @DeepSpace: это не работает, ни одно из значений
var
не являетсяglobal_vars
необходимым атрибутом.
Ответ №1:
Вот еще один, немного менее хакерский ответ, чем мой предыдущий (и теперь удаленный).
Как выясняется, global_vars
на самом деле это экземпляр NamespaceProxy
, а не Namespace
экземпляр, из-за того, как multiprocessing.Manager
работают s. У первого класса есть a __dict__
, в котором хранятся его атрибуты.
Это все еще хакерски, потому что он использует частный _getvalue()
метод, который NamespaceProxy
наследуется от его BaseProxy
базового класса, чтобы получить копию значения базового Namespace
объекта __dict__
. Помимо потенциальной проблемы, которая может возникнуть (т. Е. Не Быть актуальной), применяются обычные риски использования любого частного метода, такие как тот факт, что они могут измениться или даже исчезнуть в какой-то момент в будущем без предварительного уведомления, и тот факт, что их использование нарушает инкапсуляцию.
Тем не менее, заимствуя название книги по C Аллена Голуба, здесь достаточно веревки, чтобы выстрелить себе в ногу: ;¬)
from multiprocessing import Manager
if __name__ == '__main__':
manager = Manager()
global_vars = manager.Namespace()
global_vars.x = 0
global_vars.y = True
global_vars.z = "hello"
for var in global_vars._getvalue().__dict__:
print(var)
Выходной сигнал:
x
y
z
Комментарии:
1. спасибо за ваш ответ! Кажется, это работает, но, как вы говорите, это немного халтурно. Но я боюсь, что лучшего способа сделать это нет, поэтому пока я буду использовать этот подход.
2. Это просто обходной путь для того факта, что
multiprocessing.Manager.Namespace
object не предоставляет способа сделать то, что необходимо (поэтому единственным выходом является зависимость от его текущей реализации). Возможно, вместо этого вам следует использовать amultiprocessing.Manager.dict
. В любом случае, пожалуйста, подумайте о том, чтобы принять мой ответ, поскольку, как вы говорите, он работает и, что более важно, отвечает на заданный вами вопрос.3. извините, забыл принять ваш ответ. Еще раз спасибо, я также дам многопроцессорную обработку. Менеджер. dict — это попытка, которая действительно может быть лучшей альтернативой.
4. Черт возьми, если использование словарей слишком неудобно, я думаю, было бы довольно легко создать пользовательский
Namespace
класс, который был бы итеративным, и заставить его работать с amultiprocessing,Manager
.