Примеры API и CLI
Все примеры ниже проверены на словаре av-ru и работают с установленным пакетом avar-me.
pip install avar-me
# или из репозитория: pip install -e ".[dev]"
import avar
from avar import lookup, normalize, translate, get_dictionary
from avar.translate import format_entry
Нормализация орфографии
При вводе с латинской клавиатуры часто путают палочку ӏ с цифрой 1, буквой l и т.п. Перед поиском всегда нормализуйте строку.
>>> normalize("бет1ер")
'бетӏер'
>>> normalize("рахlат") # латинская l вместо ӏ
'рахӏат'
CLI:
avar normalize "бет1ер"
# бетӏер
avar translate "бет1ер" # нормализация в lookup встроена в индекс
# голова, голова, головка, ...
Краткий перевод (translate)
Возвращает русские глоссы одной строкой или None, если слово не найдено.
>>> translate("рахӏат")
'отдых, покой; спокойствие'
>>> translate("абажур")
'абажур'
>>> translate("___нет_такого___") is None
True
CLI:
avar translate "рахӏат"
# отдых, покой; спокойствие
Омонимы: несколько статей на одно написание
Одна и та же строка может соответствовать нескольким статьям словаря. lookup всегда возвращает список Entry.
>>> entries = lookup("а")
>>> len(entries)
3
>>> for e in entries:
... gloss = e.sense_texts()[0] if e.sense_texts() else "(см. перекрёстную ссылку)"
... print(e.word, "→", gloss)
а → а
а → от ине иди (отсюда); уходи; ступай
ине → идти, уходить, (у)ехать, ...
Последняя статья — это целевая лемма из перекрёстной ссылки (see_also), попавшая в тот же запрос при разборе формы а у глагола ине.
CLI — полный текст всех статей:
avar lookup "а"
Полная статья (lookup + format_entry)
>>> entry = lookup("аб")[0]
>>> print(format_entry(entry))
аб
stem: а
forms: аб, алъ, алъул, ал
[1] это этот, эта, это
(только)
labels: местоимение, указательное местоимение
• аб дир къалам буго — это мой карандаш
• аб лъил чу? — чья эта лошадь?
see also: гьаб (see)
JSON для интеграций:
avar lookup "рахӏат" --json
Корень (stem)
Поле stem — основа словоизменения (не у всех статей заполнено).
>>> ab = lookup("аб")[0]
>>> ab.word, ab.stem
('аб', 'а')
>>> abali = lookup("абали")[0]
>>> abali.stem
'а'
>>> abgal = lookup("абгал")[0]
>>> abgal.stem
'абга'
Сравните с бетӏер — у существительного с богатой парадигмой корень в данных может не быть вынесен отдельно:
>>> bet = lookup("бетӏер")[0]
>>> bet.stem is None
True
>>> bet.forms[:4]
('бетӏер', 'бетӏералъ', 'ботӏроца', 'бетӏералъул')
Ударение (stress)
Поле stress — номер слога с ударением (1-based), как в исходном словаре.
>>> lookup("рахӏат")[0].stress
5
>>> lookup("абали")[0].stress
1
>>> lookup("абажур")[0].stress
5
Просмотр ударения вместе с формами:
def stress_info(word: str) -> None:
for entry in lookup(word):
print(f"{entry.word}: stress={entry.stress}, forms={', '.join(entry.forms)}")
stress_info("абадиялъ")
# абадиялъ: stress=1, forms=абадиялъ, абадиялъго
Формы слова и поиск по форме
Список forms индексируется при загрузке словаря: можно искать не только лемму, но и отдельную форму.
>>> lookup("бетӏер")[0].forms
('бетӏер', 'бетӏералъ', 'ботӏроца', 'бетӏералъул', 'ботӏрол', 'бутӏрул')
>>> lookup("ботӏроца")[0].word # форма → та же статья «бетӏер»
'бетӏер'
>>> lookup("аялъ")[0].word # форма буквы «а»
'а'
Проверить, входит ли строка в парадигму известной леммы:
def forms_of(lemma: str) -> set[str]:
result: set[str] = set()
for entry in lookup(lemma):
result.add(entry.word)
result.update(entry.forms)
return result
"ботӏроца" in forms_of("бетӏер")
# True
Родовые (местоименные) варианты (gender_forms)
>>> abali = lookup("абали")[0]
>>> abali.gender_forms
('абали', 'авали', 'айали')
>>> for form in abali.gender_forms:
... print(form, "→", [e.word for e in lookup(form)])
абали → ['абали']
авали → ['авали']
айали → ['айали']
Значения, метки и комментарии
У статьи senses — список значений. У каждого Sense:
| Поле | Описание |
|---|---|
text |
русский перевод / определение |
comment |
пояснение редактора |
labels |
грамматические и стилистические метки |
examples |
примеры av / ru |
>>> entry = lookup("абадиялъ")[0]
>>> len(entry.senses)
2
>>> s0, s1 = entry.senses
>>> s0.text
'навсегда, навеки, навечно, навеки; на вечные времена'
>>> s0.labels
('наречие',)
>>> s1.text
'никогда, никогда в жизни'
>>> s1.labels
('в переносном значении',)
Слова с множеством значений — бетӏер (голова, глава, паровоз, …):
>>> bet = lookup("бетӏер")[0]
>>> len(bet.senses)
11
>>> for i, s in enumerate(bet.senses, 1):
... tags = ", ".join(s.labels) if s.labels else "—"
... print(f"{i}. {s.text} [{tags}]")
1. голова [—]
2. голова [—]
...
10. заголовок, заглавие, название [—]
11. паровоз [устаревшее слово, выражение, разговорное слово]
Метки на уровне статьи (entry.labels) встречаются реже; чаще — на уровне смысла или примера.
Примеры в контексте (examples)
>>> raxat = lookup("рахӏат")[0]
>>> ex = raxat.senses[0].examples[0]
>>> ex.av, ex.ru
('рахӏат гьечӏеб', 'беспокойный, не спокойный, тревожный')
>>> for ex in raxat.senses[0].examples:
... print(f" {ex.av}\n → {ex.ru}")
Пример с меткой пословица у бетӏер:
>>> bet = lookup("бетӏер")[0]
>>> proverbs = [
... ex for s in bet.senses for ex in s.examples if "пословица" in ex.labels
... ]
>>> proverbs[0].av
'бетӏер батӏиясул гӏакълу батӏияб, щекъер батӏиясул гьаракь батӏияб'
Перекрёстные ссылки (see_also)
>>> ab = lookup("аб")[0]
>>> for ref in ab.see_also:
... print(ref.target, ref.kind, ref.link_helper)
гьаб see None
>>> abgal_entries = lookup("абгал")
>>> abgal_entries[0].see_also[0]
SeeAlso(target='огоб', kind='from', link_helper=None)
>>> lookup("огоб")[0].sense_texts()[0]
'рожь'
Обход ссылок «синоним / антоним / см. также»:
def follow_see_also(word: str, *, kinds: set[str] | None = None) -> list[str]:
"""Вернуть целевые леммы из see_also (опционально фильтр по kind)."""
targets: list[str] = []
for entry in lookup(word):
for ref in entry.see_also:
if kinds is None or ref.kind in kinds:
targets.append(ref.target)
return targets
follow_see_also("аб", kinds={"see"})
# ['гьаб']
follow_see_also("аб-аби")
# [] — у масдара другая связь, см. ниже
Специальные поля в sense.extra и entry.extra
Поля вне основной схемы сохраняются в extra, чтобы не терять данные словаря.
>>> ababi = lookup("аб-аби")[0]
>>> ababi.senses[0].extra
{'masdarfrom': 'аб-абизе'}
>>> ababi.senses[0].labels
('масдар', 'учащительная форма', 'глагол')
>>> abgal = lookup("абгал")[0]
>>> abgal.senses[0].extra
{'pluralfor': 'огоб'}
>>> abgil = lookup("абгил")[0]
>>> abgil.senses[0].extra
{'genitivefrom': 'огоб'}
>>> abgil.senses[0].comment
'родительный падеж'
>>> abgil.senses[1].text
'ржаной'
Удобная выборка «производных» форм:
def sense_links(entry) -> list[tuple[str, str]]:
out = []
for s in entry.senses:
for key in ("masdarfrom", "genitivefrom", "pluralfor"):
if key in s.extra:
out.append((key, s.extra[key]))
return out
sense_links(lookup("аб-аби")[0])
# [('masdarfrom', 'аб-абизе')]
sense_links(lookup("абгал")[0])
# [('pluralfor', 'огоб')]
Словарь целиком: метаданные и итерация
>>> d = get_dictionary("av-ru")
>>> d.pair
'av-ru'
>>> d.entry_count > 22_000
True
>>> d.key_count > d.entry_count # ключи = леммы + формы
True
>>> sum(1 for _ in d) # итерация по всем статьям
22842
CLI:
avar info
# pair: av-ru
# entries: 22842
# index keys: ...
Поиск статей с ударением и примерами (фрагмент для корпусной обработки):
d = get_dictionary("av-ru")
with_stress = [e for e in d if e.stress is not None]
with_examples = [
e for e in d
if any(ex.av for s in e.senses for ex in s.examples)
]
len(with_stress), len(with_examples)
Сводка: типичные задачи
| Задача | API |
|---|---|
| Исправить ввод пользователя | normalize(text) |
| Быстрый RU-перевод | translate(word) |
| Все статьи по строке | lookup(word) |
| Корень | entry.stem |
| Ударение (№ слога) | entry.stress |
| Парадигма | entry.forms, поиск lookup(form) |
| Род. формы местоимений | entry.gender_forms |
| Определения и метки | entry.senses[].text, .labels, .comment |
| Примеры | sense.examples[].av, .ru |
| Ссылки | entry.see_also, sense.extra |
| Человекочитаемый вывод | format_entry(entry) |
| JSON / пайплайн | avar lookup WORD --json |