LINUX.ORG.RU

Боль динамической типизации

 , , , ,


0

2

Всем привет.

Поделитесь продвинутыми методами поиска списка членов какой-либо произвольной переменной в языках типа python.

Кроме самых очевидных:

1. Документация - часто неполная или отсутствует

2. IDE - ОЧЕНЬ часто сама не может определить тип переменной для динамических языков.

3. Пристальный взгляд в код - поиск мест использования

Для себя использую следующие ламерские методы:

1. Параллельно пишу код в IDLE и делаю dir(something) - знаю, жесть.

2. Поставить breakpoint в дебаге и палить окошко watch - тоже жесть.

Есть ли какая-нибудь удобная тула для навигации по docstrings?

По сравнению с java, где список методов получается легко и быстро (даже доки не нужны), эта проблема с питоном сильно тормозит разработку.

В качестве подтверждения попробуйте взять mechanize и определить, что есть в Browser.form. Лапшенавигирование по коду гарантировано.

Документация - часто неполная или отсутствует

Это не следствие динамической типизации.

vurdalak ★★★★★ ()
Ответ на: комментарий от vurdalak

я не спорю. Но такая ситуация встречается очень часто. Просто с динамически типизированным языком она переносится болезненно.

cccian ()

Использую ipython, там дополнение методов по TAB'у плюс вызов документации (кстати, в тех либах, которые я использую в своих проектах, она обычно вполне на уровне). Но согласен, в статике IDE пофичастее будут.

provaton ★★★★★ ()
Ответ на: комментарий от cccian

Не вижу разницы. Как будто в статически типизированных больше документации.

vurdalak ★★★★★ ()
Ответ на: комментарий от vurdalak

разница есть. В стат. тип. языке я сделаю N раз go to definition, и вот он - список всех членов.

В дин. тип. языке я попытаюсь 1 раз go to definition, на что IDE тупо не отреагирует - тип определить нельзя :)

cccian ()
Ответ на: комментарий от cccian

Это не документация. Так и я могу в repl'е добраться до нужного члена.

vurdalak ★★★★★ ()
Ответ на: комментарий от vurdalak

но только в ран-тайме. Что, согласитесь, несколько ограничивает применение этого метода.

cccian ()
Ответ на: комментарий от cccian

Я к тому, что описанные мной и тобой методы к документации отношения не имеют. Документация — это то, что на сайте разработчика висит в html и pdf.

vurdalak ★★★★★ ()
Ответ на: комментарий от vurdalak

Это не документация.

что бы это ни было - задачей оно справляется отлично.

cccian ()

А можно вопрос — _зачем_ тебе знать тип переменной. Если ты туда сохраняешь строку — это будет строка, если цифру — то цифра, разве не так? Как ты используешь знание о типе переменной? Насколько это критично?

GreenBag ★★ ()
Ответ на: комментарий от GreenBag

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

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

vurdalak ★★★★★ ()
Ответ на: комментарий от vurdalak

может я глупость скажу, но если я использую какую-то переменную (читай инстанс класса), то обычно я знаю что я делаю и какие методы есть у класса. Сторонний модуль? Но ты же его включаешь, и должен знать что за класс ты используешь. Нет?

GreenBag ★★ ()
Ответ на: комментарий от GreenBag

Но ты же его включаешь, и должен знать что за класс ты используешь. Нет?

Откуда знаешь? Допустим, у этого модуля нет документации. Или есть, но не все классы.

vurdalak ★★★★★ ()
Ответ на: комментарий от GreenBag

но если я использую какую-то переменную (читай инстанс класса), то обычно я знаю что я делаю и какие методы есть у класса

Когда пишешь - да. Когда через год-два тебе нужно перечитать большой проект с целью что-то пофиксить/улучшить - тут уже интересней.

aidan ★★★★ ()
Ответ на: комментарий от vurdalak

Если нужно вызвать метод/обратиться к члену на крайняк есть getattr. Ваш КО.

ТС-у: у Вас странные желания, но со врнменем это пройдет. Удобнее всего таб в интерпретаторе.

AIv ★★★★★ ()
Ответ на: комментарий от AIv

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

vurdalak ★★★★★ ()

Есть ли какая-нибудь удобная тула для навигации по docstrings?

sphinx.

эта проблема с питоном сильно тормозит разработку.

Это только поначалу, пока stdlib в подкорке не улегся.

baverman ★★★ ()
Ответ на: комментарий от vurdalak

Простите за нубский вопрос, но как докстроки помогают узнать с каким конкретно классом имеешь дело, например в теле метода/функции? Типы-то в аргументах не прописаны.

anonymous ()
Ответ на: комментарий от anonymous

Я имел в виду, что докстроки конкретного класса помогают узнать, какие у него есть методы.

Вернее, какие методы как работают и какие аргументы принимают.

vurdalak ★★★★★ ()
Последнее исправление: vurdalak (всего исправлений: 1)

Нужно больше лиспа

Тут не хватает лиспа

vonenij ()
Ответ на: комментарий от vurdalak

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

Или там типа сидит такой ИИ и смотрит - о, чей то мне тут поишло? Акак у этой байды вызывается отрисовка, дай ка докчтринг распарсю!:-)

AIv ★★★★★ ()
Ответ на: комментарий от AIv

Если приходиться угадывать, значит в дизайне косяк.

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

vurdalak ★★★★★ ()

вместо

dir(something)
попробуй
help(something)
будешь приятно удивлен.

Еще можно попробовать освоить язык по хорошему учебнику.

Virtuos86 ★★★★★ ()

проблема не столько в динамической типизации, сколько в возможности динамически изменять список членов класса/объекта. очень сильная фича. если она не используется, то автодополнение должно работать нормально. если используется - то обязательно должна быть внятная документация, тут уж ничего не поделать.

MyTrooName ★★★★★ ()
Ответ на: комментарий от vurdalak

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

отличный эвфемизм

MyTrooName ★★★★★ ()
Ответ на: комментарий от AIv

В критических местах можно ставить ручную проверку типов, можно замутить прлверку типов аргументлв функции через декоратлр

AIv всегда готов предложить парочку извращенных решений, замешанных на интроспекции ;)

Virtuos86 ★★★★★ ()
Ответ на: комментарий от vurdalak

При достаточно развитой системе типов сигнатуры становятся отличной, а главное, автоматически верифицируемой документацией. Это, правда, не про жаву совсем.

anonymous ()
Ответ на: комментарий от Virtuos86

Да, только ни то ни то к интроспекции не относится:-)

AIv ★★★★★ ()

Это неизлечимая анальная боль динамических языков. Через некоторое время тебе может начать нравится и ты начнёшь себя считать Элитой :D

vtVitus ★★★★★ ()

Всем спасибо за ответы.

ipython и sphinx определённо пригодятся.

cccian ()

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

Deleted ()

Dynamic typing - зло, Static typing + type inference - благо.

Ian ★★ ()
Последнее исправление: Ian (всего исправлений: 1)

тебе надо знать интерфейс и использовать его, тебе не надо знать тип и прочую ерунду.

не знаешь интерфейс... требуй постановку задачи и не берись за говнокод(если за это конечно не платят приличных денег)

dimon555 ★★★★★ ()

4. Переход на нормальные языки со статической типизацией.

Miguel ★★★★★ ()
Ответ на: комментарий от vurdalak

Вообще, это довольно самонадеянно - использовать чужой модуль, не зная, как он устроен внутри и не имея исчерпывающей документации на этот счёт. Сейчас-то Вы, конечно, посмотрите, какие у него есть методы и поля, но завтра автор выкатил новую версию, изменив реализационную часть (он-то, наивный, думает, что всё, что не публично, сторонним кодом не используется), и, оп-па, деда, ты попал!

Ну а, вообще, ТС уже все слова сказал сам: dir(smth). Я подозреваю, что автокомплит во многих средах так и реализован.

AlexM ★★★★★ ()
Последнее исправление: AlexM (всего исправлений: 1)
Ответ на: комментарий от Ian

Static typing + type inference - благо

Маловато будет. Надо ещё type ака FCO. И наличие в том числе и «прототипированных» возможностей: определение интерфейса как набора «свойств» по уже существующей «иерархии классов», расширение уже где-то созданных объектов, может ещё что - сразу и не скажу.

yyk ★★★★★ ()
Ответ на: комментарий от dimon555

тебе надо знать интерфейс и использовать его, тебе не надо знать тип и прочую ерунду.

Хех, забавная логика :)

Чтобы УЗНАТЬ интерфейс, нужно получить список членов. Тип, так или иначе, в этом сильно поможет.

не знаешь интерфейс... требуй постановку задачи и не берись за говнокод

эммм... Неужели вы бросаете задачу каждый раз, когда вам не удаётся осилить интерфейсы :) ? Постановка задачи тут не причём.

cccian ()
Ответ на: комментарий от AlexM

Вообще, это довольно самонадеянно - использовать чужой модуль, не зная, как он устроен внутри и не имея исчерпывающей документации на этот счёт

не зная, как он устроен внутри

Вы слышали что такое инкапсуляция?

Я не спорю - знать лучше, чем не знать. Но неужели вы изучаете внутреннюю кухню каждого модуля, перед тем как его использовать? С таким подходом вы вообще не должны ничего писать, а только изучать кишки всех ваших зависимостей :)

не имея исчерпывающей документации на этот счёт

Реальность такова, что «исчерпывающей документации» очень часто не бывает.

cccian ()
Ответ на: комментарий от AlexM

Иногда дира недостаточно, если перегружен __getattr__

AIv ★★★★★ ()
Ответ на: комментарий от cccian

Я рекомендовал бы посмотреть предыдущую переписку, прежде чем.

AlexM ★★★★★ ()
Ответ на: комментарий от cccian

Вы слышали что такое инкапсуляция?

Это когда нельзя посмотреть как оно работает?

PolarFox ★★★★★ ()
Ответ на: комментарий от PolarFox

Вы слышали что такое инкапсуляция?

Это когда нельзя посмотреть как оно работает?

Нет, это называется «быдлокод^Wобфускация».

tailgunner ★★★★★ ()
Ответ на: комментарий от AIv

Эх :-) А кому щаз легко. Если перегружены __getattr__ и, в особенности, __getattribute__ , задача определения атрибутов объекта становится принципиально не определяемой снаружи, только полным анализом кода :)

AlexM ★★★★★ ()
Ответ на: комментарий от PolarFox

Это когда нельзя посмотреть как оно работает?

Это когда неважно как оно работает.

Debasher ★★★★★ ()
Ответ на: комментарий от cccian

Чтобы УЗНАТЬ интерфейс, нужно получить список членов.

ты пишешь код, который обрабатывает объекты с неизвестным интерфейсом? И ты в рантайме определяешь интерфейс через тип, чтобы организовать нужное взаимодействие?

это кривая архитектура, это нужно переделать. Диспетчеризация на основе типа в питоне, это странно.

dimon555 ★★★★★ ()
Ответ на: комментарий от AlexM

В общем случае да. Но в некоторых актуальных частных случаях можно пропатчить dir или ее аналоги. Например SWIG для оберток плюсовых классов перегружает __getattr__, но (выясняется путем анализа кода;-)) все атрибуты лежат в словарях __swig_get/setattribute__, откуда их и надо брать. С дургой стороны в __dict__ SWIG кладет всякую муру типа this и thisown которую трогать не надо.

Я с-но к чему - код смотреть все равно приходиться.

AIv ★★★★★ ()
Ответ на: комментарий от AIv

Ох, ну swig - это отдельная песня. Я тут давеча организовывал следующую конструкцию:

Java program -> C++ library -> Java callback based on С++ interface. Со сквозными эксепшнами и разнообразными контейнерами.

На удивление, всё заработало, и заняло ~неделю. Но не оставляло ощущение изучения «Искусства Тёмных Сил».

AlexM ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.