Pull to refresh

Comments 10

Я один из двух главных разработчиков Python.NET (с 2018ого, до этого проект разрабатывался другими людьми). AMA

Не очень силен в Python, поэтому лучше спрошу напрямую -- я правильно понимаю что вы хостите свою clr, что-то типа [вот этого](https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting) метода?
Если да, есть ли какие-то подводные камни?
Если нет, можете рассказать как это под капотом работает (вызов .NET из Python)?

Да, именно так. .NET Core ещё только в preview, но Mono и .NET Framework загружаются похожим способом. Отдельно нужно упомянуть, что pythonnet поддерживает не только CLR в Python, но и Python в CLR.

Подводных камней на самом деле полно. Главные:
— т.к. Python — динамический язык, вызов методов .NET с учётом перегрузок по типу параметров может превратиться в угадайку.
— есть некоторая магия с типом int из Python: для удобства он автоматически преобразуется к System.Int32 или System.Int64 по необходимости, но на самом деле это не совсем верно, т.к. int из Python может принимать сколь угодно большие значения. Однако если бы он был замапан на .NET BigInteger, код на Python использующий Python.NET был бы перегружен приведениями типов
— многопоточность. СPython всё ещё активно использует Global Interpreter Lock и многопоточный код на .NET должен это учитывать. Я, честно говоря, так и не разобрался, нужно ли использовать какие-либо другие примитивы синхронизации помимо Py.GIL (C#), чтобы предотвратить чтение stale data. Вопреки ожиданиям, похоже, что да. Т.е. захват Py.GIL не гарантирует, что вы увидите результат действий другого потока, который его только что отпустил. В целом у питона плохо с многопоточностью, особенно не своей.

как это под капотом работает (вызов .NET из Python)?

После загрузки хоста CLR Python вызывает функцию инициализации, написанную на C#. Та помимо прочего создаёт (с использованием Python C API) типы в Python «зеркалирующие» типы .NET, которые код на Python потом может вызывать как обычно.

Спасибо! Я не увидел clr-loader когда смотрел на репозиторий исходного проекта.
Мне на самом деле была интересна именно интеграция clr, понятно что маршаллинг объектов между двумя языка это довольно сложною
Если можно еще один тупой вопрос: каким образом становятся доступны .NET неймспейсы из Python? from System import String? Вы где-то держите баиндинги для BCL типов или это как-то можно сгенерировать на лету?

У меня сугубо практический интерес, я немного участвую в аналогичном проекте по скрещиванию R и Rust, хочется понять как типичные задачи подобного плана решают другие команды.

BTW, я не увидел этого в этой статье, но если pythonnet работает напрямую с MSIL .dll и вы хостите свою clr, то не должно быть никаких ограничений на использование только C#. Можно писать код на F# и даже на голом IL.

каким образом становятся доступны .NET неймспейсы из Python? from System import String?
Python позволяет (с определёнными ограничениями) переопределить import. Вызывается метод на .NET, который ищет через reflection указанный namespace, т.е. на лету. Думаю, в Rust так не выйдет.

Да, pythonnet можно использовать хоть с Visual Basic .NET

Ха, так и думал что это магия с импортом, теперь стало понятнее.

Спасибо за объяснения!
С удовольствием прочитал бы более детальную статью о технической стороне pythonnet если вдруг вы задумаетесь о написании таковой, и я думаю я здесь такой не один.

В статье не упомянуто — решение работает под определенную платформу (Windows), или платформо-независимое (Windows/Linux).
Делаю вывод что под Linux тоже поднимется, или я ошибаюсь?
Под linux, к сожалению, не проверял. Только под win тестировал.
И Linux, и MacOS полностью поддерживаются на AMD64. Другие архитектуры как повезёт.
Only those users with full accounts are able to leave comments. Log in, please.