Як дізнатися тип повернення функції та типи аргументів?


85

Хоча я знаю концепцію набору тексту качки в Python, іноді я боюся з типом аргументів функцій або типом поверненого значення функції.

Тепер, якщо я написав функцію самостійно, Я ДІЯ знаю типи. Але що, якщо хтось хоче використовувати і викликати мої функції, як він / вона очікує знати типи? Зазвичай я ввожу інформацію про тип у документацію функції (наприклад: "...the id argument should be an integer..."and "... the function will return a (string, [integer]) tuple.")

Але чи шукати інформацію в документі (і розміщувати її там як кодер) справді так, як це передбачається робити?

Редагувати: Хоча, мабуть, більшість відповідей спрямовують на "так, документ!" Я вважаю, що це не завжди дуже просто для `` складних '' типів.
Наприклад: як коротко описати в документі, що функція повертає список кортежів із кожним кортежем форми (node_id, node_name, uptime_minutes) і що елементами є відповідно рядок, рядок і ціле число?
Документація PEP-документації не містить жодних вказівок щодо цього.
Я думаю, контраргументом буде те, що в такому випадку слід використовувати класи, але я вважаю python дуже гнучким, оскільки він дозволяє передавати ці речі за допомогою списків та кортежів, тобто без класів.


2
Коротка відповідь - "так". Довга відповідь - "так, звичайно". Я не знаю, чи багато ви розглядали код Python, але, мабуть, слід оновити питання, щоб вказати, які пакети ви насправді використовуєте, щоб ми могли направити вас до коду, який ви можете прочитати, щоб побачити, як все робиться в коді бібліотеки, який ви фактично використовую прямо зараз.
S.Lott

@ S.Lott: Зараз я борюся з механізованим пакетом, але, мабуть, це просто (на жаль) погано задокументовано.
Рабарберскі

4
Python крутий, тому що ви можете швидко писати багато коду, і вам не доведеться турбуватися про буденні речі, такі як типи повернення, типи аргументів, ефективність виконання, люди, які повинні використовувати та підтримувати ваш код спагетті протягом наступних 10 років і т. Д. Зітхніть .
jarmod

Відповіді:


121

Ну, з 2011 року все трохи змінилося! Тепер у Python 3.5 є підказки щодо типів, за допомогою яких можна анотувати аргументи та повертати тип вашої функції. Наприклад це:

def greeting(name):
  return 'Hello, {}'.format(name)

тепер можна записати так:

def greeting(name: str) -> str:
  return 'Hello, {}'.format(name)

Як тепер ви можете бачити типи, існує якась необов’язкова перевірка статичного типу, яка допоможе вам та вашому засобу перевірки типу дослідити ваш код.

для більш детального пояснення я пропоную поглянути на публікацію в блозі про підказки щодо типу в блозі PyCharm .


Зверніть увагу, що синтаксис натяку на тип також був запропонований для Python 2.7 тут, у тому самому PEP-0484. І це працює в PyCharm, принаймні з версії 2017.3.
viddik13

1
Якщо функція привітання з точно таким же визначенням повертає об'єкт типу int, помилок не виникне. Отже, що таке використання перевірки типу, якщо ви прямо згадуєте тип повернення, але не дотримуєтесь правила і повертаєте інший тип об’єкта?
Арашсих,

2
@Arashsyh: Так, ти маєш рацію, натяк на тип не перетворює Python на статично набрану мову, від вас залежить, як правильно використовувати правильні типи. І такі підказки вам допомагають - швидше розробляти, самодокументувати свій код або отримувати попередження, коли щось заплутаєте. Особливо, коли ви використовуєте PyCharm (або подібну IDE), це попередить вас, якщо ви використовуєте інший тип і допоможе з кількома іншими речами. Рекомендую прочитати публікацію в блозі, запропоновану у відповіді вище.
Nerxis

Це швидше обчислювально?
Брайс Уейн,

17

Ось як працюють динамічні мови. Однак це не завжди добре, особливо якщо документація погана - хтось намагався використовувати погано задокументований фреймворк python? Іноді доводиться повертатися до читання джерела.

Ось кілька стратегій, щоб уникнути проблем із набором качок:

  • створити мову для проблемного домену
  • це допоможе вам правильно називати речі
  • використовувати типи для представлення концепцій мовою вашого домену
  • параметри функції імені, використовуючи словниковий запас мови домену

Крім того, один з найважливіших моментів:

  • зберігайте дані якомога локальнішими!

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

Пов’язаний (і також пов’язаний із документами) у пітоні існує техніка, яка називається doctests. Використовуйте це, щоб задокументувати, як передбачається використовувати ваші методи - і одночасно мати гарне охоплення модульним тестом!


1
Документація Numpy є хорошим репрезентативним прикладом філософії, зазначеної у відповіді вище.
Музикант Путрід

5

Так, вам слід використовувати docstrings, щоб зробити ваші класи та функції більш дружніми до інших програмістів:

Більше: http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring

Деякі редактори дозволяють бачити текстові рядки під час набору тексту, тому це справді полегшує роботу.


+1: задокументуйте це, це єдиний розумний спосіб, і це стосується і статично набраних мов. Типи повернення - це незначна частка загальної картини.
помер

Мені подобаються мої типи дуже дякую. Документація + типи = рай
masm64

5

Я відвідував курс курсу, був урок, на якому нас навчали про дизайнерські рецепти.

Нижче формату документації я знайшов preety корисним.

захисна зона (основа, висота):
    '' '(число, число) -> номер # ** TypeContract **
    Повернення площі трінг з розмірами підстава # ** Опис **
    і висота

    >>> область (10,5) # ** Приклад **
    25,0
    >> площа (2,5,3)
    3.75
    ''
    повернення (основа * висота) / 2 

Думаю, якщо такі документи написані таким чином, це може дуже допомогти розробникам.

Посилання на відео [Перегляньте відео] : https://www.youtube.com/watch?v=QAPg6Vb_LgI


2

Так.

У Python функція не завжди повинна повертати змінну того самого типу (хоча ваш код буде більш читабельним, якщо ваші функції завжди повертають один і той же тип). Це означає, що ви не можете вказати єдиний тип повернення для функції.

Так само параметри не завжди повинні бути однотипними.


1

Наприклад: як коротко описати в документі, що функція повертає список кортежів, з кожним кортежем форми (node_id, node_name, uptime_minutes) і що елементами є відповідно рядок, рядок і ціле число?

Гм ... Немає "стислого" опису цього. Це складно. Ви спроектували його як складний. І це вимагає складної документації в документації.

Вибачте, але складність - ну - складна.


2
В ПОРЯДКУ. Поза темою (на кшталт): але що тоді буде чистішим дизайном? Заняття?
Рабарберскі

@ Рабарберскі: Не обов'язково. Тут складності звучить неминуче. Лаконічність не завжди досяжна або навіть бажана.
S.Lott

Очевидний спосіб задокументувати подібні речі - це використання чогось подібного до Java-дженериків, як у: list <tuple <int, str, int >>. Але це не спосіб Python, в кращу чи в гіршу сторону.
skyler


0

Документи (та документація загалом). Python 3 вводить (необов’язкові) анотації функцій, як описано в PEP 3107 (але не залишайте рядки документації)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.