#matplotlib #julia
#matplotlib #julia
Вопрос:
У Меня у меня очень простой вопрос. Возможно ли загружать модули по требованию в Julia. То есть, могут ли модули загружаться тогда, когда они действительно необходимы, вместо того, чтобы загружаться во время «синтаксического анализа» на верхнем уровне.
Сценарий использования, который я имею в виду, заключается в том, что у меня есть некоторый набор кода, который способен выполнять некоторые построения с помощью PyPlot, но код далеко не всегда выполняется.
На данный момент это означает, что у меня на верхнем уровне есть оператор типа using PyPlot
, загрузка которого занимает довольно много времени.
(Да, я знаю: не следует часто перезапускать Julia, бла-бла-бла … но, тем не менее, это вызывает раздражение)
Есть ли способ гарантировать, что PyPlot загружается только в том случае, если это действительно необходимо? Самой простой идеей было бы включить using PyPlot
внутри функции, которая фактически выполняет построение графика
function my_plot()
using PyPlot
plot(1:10,1:10)
end
но это приводит к синтаксической ошибке:
ERROR: syntax: "using" expression not at top level
Итак, есть ли другой способ добиться этого?
Комментарии:
1. вы могли бы
eval
этоusing
выразить в глобальной области.2. @Gnimuc Спасибо за ваш комментарий, но я не понимаю, что вы имеете в виду. Не могли бы вы привести пример?
3. добавить
@eval
передusing PyPlot
Ответ №1:
Инструкция «using» выполняется при обнаружении строки кода и не обязательно должна находиться в верхней части файла. Это должно быть в глобальной области видимости, что означает, что переменные в модуле, загруженные с помощью «using», будут доступны для всех функций в вашей программе после выполнения инструкции «using», а не только для одной функции, как это может произойти в локальной области видимости функции.
Если вы вызываете инструкцию using как выражение в инструкции Julia eval, весь код, выполняемый в инструкции «eval» в Julia, автоматически выполняется в глобальной области видимости, даже если синтаксический вызов eval выполняется в локальной области видимости функции. Итак, если вы используете макрос @eval
function my_plot()
@eval using PyPlot # or without the macro, as eval(:(using PyPlot))
plot(1:10,1:10)
end
это действует так, как будто использование PyPlot выполняется вне функции, и поэтому позволяет избежать синтаксической ошибки.
Комментарии:
1. Спасибо за ответ. Однако теперь возникают новые проблемы. Когда я помещаю
@eval
в функцию, она все равно не может найти PyPlot: у меня есть:@eval using PyPlot ; clf()
и получаю «ОШИБКА: LoadError: MethodError: нет метода, соответствующего clf() Применимый метод может быть слишком новым: выполняется в мире 25167, в то время как текущий мир 25173. » В каком-то другом месте кода, который я случайно запустилusing PyCall
, поэтому я все еще получаю столкновение?2. clf() — это функция PyPlot. Сообщение об ошибке означает, что код, который ссылается на подпрограммы PyPlot, был скомпилирован до запуска с использованием PyPlot. Вы могли бы найти функцию, генерирующую ошибку, и запустить инструкцию using до того, как обнаружится этот код, но поскольку это может оказаться неустойчивым к дальнейшему рефакторингу вашего кода, получение этой ошибки означает, что вы должны просто запустить PyPlot вверху.,
3. Я должен добавить, что иногда указание clf в качестве PyCall, clf() в коде, в котором выполняется вызов clf(), также может работать, поскольку PyPlot() может изменять ссылку clf() с PyCall.clf на PyPlot.clf() при запуске программы.