Как правильно узнавать типы данных (из внешних пакетов) для объявления своих функций?
По-хорошему принято указывать типы для всех аргументов функций.
Но вот, допустим, есть у нас скрипт, который работает с SQLAlchemy с банальным кодом вроде:
engine = create_engine(args.db)
Но если дальше я передаю engine в функцию - какой тип мне указать для него? Для всех базовых типов, для своих классов - все понятно. Но как узнать это для стороннего пакета? (вопрос не именно про SQLAlchemy, а для общего случая)
Если я печатаю type(engine) то я узнаю: sqlalchemy.engine.base.Engine
ChatGPT советует - sqlalchemy.engine.Engine
хелп в VSCode говорит - "Create a new _engine.Engine instance."
при этом часто ведь возвращаемый тип может быть разным (например, можно допустить что в альтернативном пакете для mysql и для postgresql сами типы могут быть разные, но от общего предка). То есть, я не могу использовать то, что мне `type()` выдал.
Как при работе с незнакомым пакетом правильно определить, какой тип использовать? Есть какой-то единый прямой каноничный способ?
например, можно допустить что в альтернативном пакете для mysql и для postgresql сами типы могут быть разные
Какая разница альтернативный пакет или нет. Алхимия для этого и создана, чтобы со всем работать одинаково.
В данном случае create_engine всегда будет возвращать Engine
«Пользователь удалён», Wispik так разные же Engine. Даже если они одинаковые, есть разные символы:
- sqlalchemy.Engine
- sqlalchemy.engine.Engine
- sqlalchemy.engine.base.Engine
Чтобы узнать, разные или нет - надо полазить по исходникам. Неужели это правильный путь?
и еще, наверное, есть какой-то _engine.Engine откуда-то, я даже не нашел откуда.
Пусть даже в нашем частном случае (с sqlalchemy) - все они указывают на один класс, как определить какой из них правильнее?
Мне интересно не с этим конкретным типом разобраться, а с общим правилом. Есть некоторая функция F из пакета P, какой тип использовать для того значения, которое она возвращает?
они одинаковые, просто импортированы из разных мест
Чтобы узнать, разные или нет - надо полазить по исходникам.
не может быть в рамках одной библиотеки несколько разных классов с одним названием
В целом проблема не понятна. Просто посмотреть, какой тип возвращает функция F (для этого не обязательно в исходники лезть, IDE все отлично показывает)
Wispik, Это и есть - разные. Класс, вероятно, одинаковый, но символы разные. :-). Вопрос же не в том, чтобы программа работала (для этого можно хоть int'ом объявить - работать все равно будет).
Но если объявить неправильный символ (импортированный не из того модуля, как задумал автор), в следующей версии он может все реорганизовать внутри своего пакета (оставив все "официальные" символы на месте, а "внутренний" перебросить из file1.py в file2.py или из Engine в MyEngine переименовать, но импортировать его "as Engine"), и тогда наш код, где мы используем file1.Engine вообще поломается на этапе импорта этого неправильного символа.
Я ниже в "ответах" выслал скрин, что IDE показывает. Нечто без полного пути (знаем только последнюю часть - оканчивается на Engine) и есть по меньшей мере 3 разных символа, (вероятно) указывающих на один и тот же класс. (Даже чтобы перепроверить эту версию, что все 3 - это один и тот же класс, надо потратить время).
Я просто надеялся, что есть какой-то прямой путь. Либо функция подобная type() чтобы вернула заведомо правильное название класса (например, не тип именно этого объекта, а тип того его предка, который надо использовать), либо хотя бы VSCode. У меня он не пишет, какой именно Engine надо использовать.
Во-первых, зачем париться с типами
Во-вторых, я всегда указываю (когда указываю) тот тип, который возвращается (sqlalchemy.engine.Engine) или тот, от которого наследуется.
В-третьих, ни о каких каноничных стандартах, кроме PEP, я не слышал
Aragorn, я так понял, что IDE ничего не вычисляет, а тупо показывает прототип и подсказку docstring из кода.
В случае sqlalchemy create_engine это у нас "... -> Engine", который (если перейти, чтобы понять, какой именно из множества символов Engine в этом пакете имеется в виду) приводит в sqlalchemy.engine.base и в нем уже Engine...