Перспективный брокер идентифицирует классы по имени, когда говорит о них по сети. Класс получает свое имя частично из модуля, в котором он определен. Сложная проблема с определением классов в файле, который вы запускаете из командной строки (т. Е. Ваш «основной сценарий»), заключается в том, что они могут в итоге получить неожиданное имя. Когда вы делаете это:
python foo.py
Имя модуля, которое Python дает коду в foo.py
, отличается от "foo"
, как и следовало ожидать. Вместо этого это что-то вроде "__main__"
(именно поэтому трюк if __name__ == "__main__":
работает).
Однако, если какая-то другая часть вашего приложения позже попытается импортировать что-то из foo.py
, тогда Python пересмотрит его содержимое, чтобы создать новый модуль с именем "foo"
.
Кроме того, классы, определенные в модуле "__main__"
одного процесса, могут не иметь ничего общего с классами, определенными в модуле "__main__"
другого процесса. Это случай в вашем примере, где __main__.RemoteClass
определен в вашем серверном процессе, но в модуле __main__
вашего клиентского процесса нет RemoteClass
.
Итак, PB перепутан и не может завершить передачу объекта.
Решение состоит в том, чтобы минимизировать объем кода в вашем основном скрипте и, в частности, никогда не определять вещи с именами (без классов, без определений функций).
Однако другой проблемой является ожидание того, что RemoteCopy
может быть отправлено через PB без дополнительной подготовки. Copyable
можно отправить, создав RemoteCopy
на одноранговом узле, но это не симметричные отношения. Ваш клиент также должен разрешить это, сделав аналогичный (или другой) вызов pb.setUnjellyableForClass
.