Заклинание Jython

Узнайте, как реализация Python на Java поможет вам в ваших разработках

Jython представляет собой реализацию языка программирования Python, полностью выполненную на Java, которая объединяет преимущества Python с виртуальной машиной и библиотекой Java и выступает в роли удобного дополнения к платформе Java. В этой статье программист-консультант и автор многочисленных статей на developerWorks Уче Огбуджи представляет Jython 2.1 разработчикам, пишущим на Java, сопоставляя и сравнивая способы создания классов на этих языках и способы применения ими интерпретатора. Для иллюстрации различий Уче приводит примеры доступа к библиотеке Java, а также демонстрирует оболочку интерпретатора Jython и файлы с кодом.

Юч Огбуджи, Главный консультант, Fourthought

Юч Огбуджи (Uche Ogbuji) - консультант и один из основателей Fourthought Inc., компании, занимающейся поставками программного обеспечения и предоставлением консалтинговых услуг в области XML-решений для корпоративного управления знаниями. Fourthought разрабатывает 4Suite, платформу с открытым исходным кодом, для XML, RDF и приложений по управлению знаниями. Юч Огбуджи - инженер в области вычислительной техники, он родился в Нигерии, сейчас живет и работает в Боулдер-Сити (Boulder), штат Колорадо, США. С ним можно связаться по адресу uche@ogbuji.net.



06.08.2012

Jython, изначально известный как JPython, представляет собой полностью написанное на Java приложение, которое позволяет разработчикам использовать синтаксис и большинство возможностей языка программирования Python. Jython интересен программистам, пишущим на Java, по нескольким причинам:

  • Jython является версией оболочки интерпретатора Python и удобен для изучения и опробования идей и API без обычного для Java цикла компиляции/исполнения.
  • Благодаря динамичности и многофункциональности Python вам не придется добавлять соответствующие функции из сложных библиотек (таких как библиотеки Java для рефлексии и интроспекции). Это упрощает многие виды разработок и особенно полезно в системах автоматического тестирования.
  • Многим разработчикам нравится синтаксис Python и ощущение от работы с этим языком; они считают его чрезвычайно продуктивным способом разработки и сопровождения приложений Java.

В этой статье я представлю свежую версию Jython 2.1 и приведу некоторые примеры доступа к библиотекам Java с помощью оболочки интерпретатора Jython, а также продемонстрирую файлы с кодом Jython. Чтобы понять все это, вам не обязательно знать язык Python, но вам придется изучить его, если вы собираетесь выйти за рамки базовых примеров, приведенных в этой статье.

В данном случае я использую среду Red Hat 8.0 (ядро 2.4.18) и J2SE 1.4.0. На сайте Jython (см. Ресурсы), вы найдете много полезной информации о платформе Jython и средах Java, которые можно с ним использовать.

Примечание: и Jython, и Java работают в среде исполнения Java.

Приступаем к работе с Jython

Jython распространяется в виде одного .class файла Java, содержащего установщик. Просто загрузите файл jython-21.class, поместите его куда-нибудь в CLASSPATH, а затем подайте команду java jython-21. Выберите компоненты, которые хотите установить (в примере я выбрал все компоненты, предлагаемые по умолчанию), подтвердите свое согласие с условиями лицензии (это лицензия ПО с открытым исходным кодом BeOpen/CNRI) и укажите директорию для установки — об остальном позаботится установщик.

Если во время установки у вас возникнут проблемы, загляните на страницу с информацией об установке на сайте Jython. На платформах UNIX рекомендуется добавить путь к установленному Jython в переменную среды PATH. Теперь для запуска интерактивной оболочки достаточно будет набрать "jython":

Листинг 1. Запуск оболочки Jython
$ jython
Jython 2.1 on java1.4.0_01 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>>

Приглашение >>> позволяет вводить команды и немедленно получать результаты. В языке Java каждая программа должна определять хотя бы один класс. В листинге 2 показана законченная программа Java для вывода сообщения на экран:

Листинг 2. Законченная программа Java
class App
{  
  public static void main(String args[])
  {
    System.out.println("Я не люблю спам!");
  }
}

JPython сократит эти строки до следующей конструкции:

Листинг 3. Jython устраняет избыточность кода Java
>>> print "Я не люблю спам!"
Я не люблю спам!
>>>

Ключевое слово print является одним из основных инструментов, особенно в интерактивной оболочке, где оно сразу же печатает свои аргументы и возвращает вас в командную строку оболочки. Теперь вы сможете не только набирать и отлаживать меньше кода, — вы также сразу же получаете результаты, не выполняя цикла компиляции/запуска. Можно так же просто распечатать за один раз несколько значений и использовать простые выражения, как показано ниже:

Листинг 4. Print является важнейшим инструментом Jython
>>> print "один плюс один равно", 1+1
один плюс один равно 2
>>>

Выражения Jython подобны выражениям Java. Результат 1+1 является целым числом, которое print преобразует в строку и соединяет с предшествующей строкой, которая отделена запятой.

Для доступа к стандартным библиотекам Java из Jython тоже не потребуется сложных механизмов. Следующий пример демонстрирует доступ к java.util.Random:

Листинг 5. Доступ к стандартным библиотекам Java через Jython
>>> from java.util import Random
>>> rng = Random()
>>> i = rng.nextBoolean()
>>> print i
1
>>>

Ключевое слово import языка Jython подобно его версии в языке Java в том, что оно делает содержимое одного модуля доступным другому модулю, но есть и некоторые различия в синтаксисе и поведении.

В приведенном выше листинге 5 использовано родственное ключевое слово from, которое указывает, какие именно символы нужно импортировать из java.util. Следующая строка демонстрирует создание экземпляра класса Random. Как видите, ключевое слово new здесь не нужно.

Кроме того, не нужно объявлять тип переменной, содержащей новый экземпляр. Это еще один пример существенного упрощения работы в Jython и одно из преимуществ его динамического характера — поскольку это значительно сокращает потребность в контроле типов данных.

Следующая строка листинга 5 демонстрирует вызов метода. Это делается так же, как и в языке Java, не считая того, что отсутствует объявление типа результата. nextBoolean() в коде Java имеет булевский тип. В Jython 2.1 нет булевского типа (хотя эта ситуация вскоре может измениться; булевский тип будет добавлен в Python 2.3), поэтому он заменяет булевские значения целыми числами 00 или 1. Соответственно, чтобы вызвать метод Java, который ожидает булевское значение, ему нужно передать целое число, отвечающее этим требованиям.

Кроме того, ключевое слово import можно использовать так, чтобы полностью указать имена всех импортируемых символов, как показано в листинге 6:

Листинг 6. Импорт полностью определяет имена всех импортируемых символов
>>> import java.util.Random
>>> rng = java.util.Random()
>>> print rng.nextFloat()
0.9567907452583313
>>>

Числа с плавающей запятой в Jython такие же, как и в языке Java.


Написание кода непосредственно в исходном файле

Интерпретатор удобен для проведения проверок и экспериментов, но вы не обязаны выполнять всю работу именно в нем — Jython позволяет заносить код программы в файлы и затем запускать этот код (хотя компиляция в Jython необязательна). В качестве примера взгляните на следующую автономную программу на языке Jython:

Листинг 7. Пример программы Jython, моделирующей подбрасывание монеты (сохранен в файле listing7.py)
from java.util import Random
rng = Random()

#Это комментарий в Jython
print "Бросаем монету..."
if rng.nextBoolean():
    print "Орел"
else:
    print "Решка"

Прежде чем запустить эту программу, давайте рассмотрим ее код. В этом примере представлен оператор if— первое, что люди замечают, начиная работать с Jython (так же, как и в случае его предшественника Python). Здесь отсутствует символ-разделитель, отмечающий конец блока, который исполняется в случае удовлетворения условия (условия в Jython не нужно заключать в скобки, как того требует язык Java). Мы просто сдвигаем код на большую величину, чем окружающий код.

Блоки кода в Jython всегда обозначаются отступами, а не, скажем, фигурными скобками. Операторы, представляющие блоки кода, такие как if, заканчиваются двоеточием. Эта особенность Jython подразумевает, что при написании кода нужно соблюдать осторожность, поскольку при сдвиге кода вы фактически изменяете его значение. Например, в листинге 8a будет печататься только число 3, потому что расположенные выше два оператора являются частью блока if, условия которого никогда не удовлетворяются:

Листинг 8a. Отступ: печатается только "3"
if 0:
    print "1"
    print "2"
print "3"

Достаточно просто изменить отступ одной строки, чтобы напечатались числа 2 и 3:

Листинг 8b. Отступ: печатаются "2" и "3"
if 0:
    print "1"
print "2"
print "3"

Кроме того, отступ должен быть согласованным, он должен соответствовать операторам, которые разбивают код на блоки, и обычно он же управляет исполнением кода. Например:

Листинг 8c. Отступ: синтаксическая ошибка
print "1"
    print "2"
print "3"

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

Применение отступа для обозначения блоков является одной из самых сомнительных особенностей языков Python и Jython, но, как мне кажется, эту проблему часто преувеличивают. В конце концов, если вы будете строго придерживаться стиля написания программ, вы эту проблему просто не заметите. Если следовать стилю соблюдения отступов, то тот факт, что они являются обязательными, а не просто предназначены для повышения удобочитаемости, роли не играет.

Более того, я не знаю ни одного разработчика, который замечал бы это ограничение уже после нескольких часов работы с языком. Соблюдение отступов просто входит в привычку. Конечно, такая связь между отступами и синтаксисом может породить ошибки, с которыми вы раньше не встречались, но в то же время, отсутствие явных разделителей устраняет некоторые проблемы, присущие тем языкам, в которых они применяются.

Файл в листинге 7 (listing7.py) можно запустить без компиляции, просто передав имя файла в качестве аргумента команде jython, как показано ниже:

Листинг 9. Запуск "подбрасывания монеты" без компиляции
$ jython listing7.py
Бросаем монету...
Решка
$

Символ $ в предыдущем примере — это просто приглашение оболочки UNIX, вроде C:\> в системе Windows. Кроме того, вы можете скомпилировать модуль в байт-код Java (.class) с помощью команды jpythonc, что позволит запускать этот код непосредственно командой java или jre. Впрочем, на модули, которые компилируются таким способом, накладываются некоторые ограничения, но обсуждение этого вопроса выходит за рамки нашей статьи.


Построение глобальных функций

В Jython можно легко создавать глобальные функции, хотя язык Java создание глобальных функций не поддерживает. Также можно определять глобальные переменные (обычно для создания констант без содержащего их класса). К примеру, взгляните на следующий листинг:

Листинг 10. Глобальная функция возвращает последовательность чисел в форме строки (сохранен в файле listing10.py)
START = 1
SPACER = " "

def CounterString(length):
    buffer = ""
    for i in range(START, length):
        buffer = buffer + str(i) + SPACER
    return buffer

print CounterString(10)

Сначала мы определяем две глобальные переменные, которые используются в этой программе в качестве констант —START (начало) и SPACER (разделитель) — первая является целым числом, а вторая — строкой.

Затем мы определяем функцию CounterString с помощью ключевого слова def. Эта функция принимает единственный аргумент — целое число с именем length (длина). Тот факт, что Jython не контролирует тип аргумента, является преимуществом с точки зрения динамичности языка; но это может стать и недостатком, поскольку некоторые ошибки, связанные с неправильным назначением типов, в отличие от языка Java, могут довольно долго не обнаруживаться.

Заметьте, что строка определения функции заканчивается двоеточием, а это означает начало нового блока, обозначенного отступом последующих строк. Первая строка этого нового блока инициализирует буфер пустой строкой. Этот буфер будет использоваться для хранения результатов работы функции.

Следующая строка создает цикл. Оператор for в Jython принципиально отличается от аналогичного оператора языка Java. В Java вы определяет начальные и конечные условия, а также шаг приращения для каждого цикла. В Jython цикл всегда проходит определенную последовательность от начала и до конца. Обычно эта последовательность имеет вид списка — очень важного типа данных в Jython.

Список из трех строковых значений выглядит примерно так:

["a", b", "c"]

Если вы хотите перебрать числа от 1 до N (что мы и делаем), вы можете использовать функцию range(), которая возвращает список чисел в указанном диапазоне. Чтобы лучше ознакомиться с работой этого инструмента, поэкспериментируйте в интерактивной командной строке Jython:

Листинг 11. Примеры функции range()
>>> range(5)
[0, 1, 2, 3, 4]
>>> range(1, 5)
[1, 2, 3, 4]
>>> range(1, 10, 2)
[1, 3, 5, 7, 9]
>>> range(10, 1, -3)
[10, 7, 4]

Взгляните на листинг 10. Каждая итерация цикла for исполняет блок кода, дополнительно сдвинутый относительно тела функции. Этот блок состоит из одной строки, в которой текущее содержимое буфера соединяется с новым числом, которое предварительно преобразуется в строку с помощью функции str() (а не cast, как было бы в языке Java). Затем к строке добавляется разделитель. После этого цикл прекращается, и возвращается итоговый буфер. Сразу за телом функции следует строка кода для ее проверки. И снова Jython позволяет выполнить это без специальных средств, таких как метод main в классе приложения. Результат работы листинга 10 показан ниже:

Листинг 12. Результат работы Листинга 10
$ jython listing10.py
1 2 3 4 5 6 7 8 9

Построение классов не сложнее, чем построение функций

Создание класса в Jython выполняется столь же просто, как и создание глобальной функции. Пример этого приведен в листинге 13:

Листинг 13. Простой пример определения класса (сохранен в файле listing13.py)
class Dog:
    def __init__(self, bark_text):
        self.bark_text = bark_text
        return
    
    def bark(self):
        print self.bark_text
        return

    def annoy_neighbors(self, degree):
        for i in range(degree):
            print self.bark_text
        return

print "Фидо родился"
fido = Dog("Гав-гав")
print "Давайте послушаем Фидо"
fido.bark()
print "А теперь пора подразнить соседей"
fido.annoy_neighbors(5)

Первая строка приведенного выше кода указывает имя класса, который определяется одним большим блоком кода.

Первым определяется специальный метод-инициализатор (аналогичный конструктору Java). Он всегда называется __init__ и вызывается при создании нового экземпляра класса. В языке Jython вы в явной форме объявляете текущий экземпляр, который будет использован (или, в случае инициализатора, создан) в качестве аргумента. Традиционно этот аргумент называют self.

В инициализаторе Dog аргумент bark_text (строка) сохраняется как переменная экземпляра с помощью self. Метод bark() не принимает при вызове никаких явных параметров, но вы все-таки должны указать self.

Метод annoy_neighbors принимает один явный аргумент, который указывается в дополнение к self и является числом, указывающим, сколько раз должна пролаять собака, чтобы раздразнить соседей. Обратите внимание, как легко этот код переходит к глубокому вложению и, следовательно, глубокому отступу. Метод annoy_neighbors содержит блок цикла, расположенный внутри определения метода, который расположен внутри определения класса. Код, начинающийся с print "Фидо родился", демонстрирует работу класса. Вывод листинга 13 выглядит примерно так:

Листинг 14. Вывод листинга 13
$ jython listing13.py
Фидо родился
Давайте послушаем Фидо
Гав-гав
А теперь пора подразнить соседей
Гав-гав
Гав-гав
Гав-гав
Гав-гав
Гав-гав

Наведение мостов между языками программирования

В этой статье мы лишь поверхностно ознакомились с преимуществами, которые может дать добавление Jython к арсеналу средств Java:

  • Jython сокращает объем кода, который нужно написать для выполнения операций.
  • Интерпретатор Jython способствует быстрой разработке кода, позволяя запускать его без компиляции.
  • Jython позволяет определять глобальные функции и переменные, чего нельзя делать в языке Java.
  • Jython предлагает динамическую типизацию, используя вывод типов и приведение типов для корректной работы в виртуальной машине со статическими типами.
  • Jython предоставляет универсальные типы данных (хотя в следующих версиях Java, таких как Tiger, универсальные типы данных тоже появляются).
  • Jython позволяет легко разрабатывать системы автоматического тестирования.

В приведенной серии примеров мы также представили некоторые различия в синтаксисе и типах данных, о которых должен знать разработчик, в том числе синтаксическое значение отступов в Jython и применение целого числа вместо неподдерживаемого булевского типа.

Применение Jython ни в коей мере не означает, что вы должны забыть о Java. Jython может быть очень полезным дополнением, подходящим для быстрой проверки и создания прототипов, тестирования и написания фрагментов кода, для которых он более удобен.

Ресурсы

  • Оригинал статьи: Charming Jython.
  • Посетите домашнюю страницу Jython, где можно загрузить эту реализацию и узнать больше о том, как ее использовать; а если у вас уже есть Jython, опробуйте эти ресурсы, которые помогут вам с установкой и решением проблем, связанных с определенной платформой.
  • Jython представляет собой реализацию языка Python; если вы планируете использовать Jython, не лишне будет ознакомиться с документацией и другими ресурсами на сайте Python.org.
  • Если вы только начинаете писать на Java, вам пригодится учебник "Введение в программирование на языке Java" (developerWorks, ноябрь 2004 г.), который описывает Java с помощью примеров, демонстрирующих синтаксис этого языка в объектно-ориентированной системе и в стандартных методах программирования. (Некоторые примеры в этой статье основаны на примерах из этого учебника.)
  • В статье "Диагностика кода Java: применение Repl для интерактивной оценки" (developerWorks, март 2002 г.) Эрик Аллен (Eric Allen) приводит пример применения Jython для построения элегантной конструкции repl— "чтение-вычисление-распечатка-цикл".
  • Посетите списки рассылки для пользователей Jython— превосходное место для получения онлайновой поддержки и интерактивного обсуждения Jython с коллегами-разработчиками.
  • Издательство O'Reilly и Ноэл Раппин (Noel Rappin) предлагают статью "Советы по написанию скриптов Java в Jython, Часть 1," которая охватывает 11 специфических функций Jython, экономящих время или интересных для программистов, пишущих на Java.
  • Книга Основы Jython (Самуэль Педрони (Samuele Pedroni), Ноэл Раппин (Noel Rappin), O'Reilly, март 2002 г.) дает подробное введение в Jython с многочисленными примерами взаимодействия Jython/Java и ссылками на модули и библиотеки для Jython-программистов. (Глава 1 доступна в сети.)
  • Научитесь строить Web- и корпоративные приложения с помощью Jython, прочитав книгу Программирование на языке Python с применением библиотек классов Java (Ричард Хайтауэр (Richard Hightower), Addison-Wesley/Pearson, июнь 2002).
  • На странице ActiveState Programmer Network предлагаются два ресурса по Jython: реализованный в Jython простой специальный тег JSP и простой Jython-сервлет.
  • Fourthought Inc.— производитель программного обеспечения, специализирующийся на XML-решениях для управления корпоративными знаниями. Компания Fourthought разработала 4Suite, платформу с открытым исходным кодом для XML, RDF и приложений для управления знаниями.

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java, Linux
ArticleID=829864
ArticleTitle=Заклинание Jython
publish-date=08062012