Предисловие и предположения об окружающей среде
Pycharm 2017
Нижняя версия Pycharm не поддерживает Type Hint, поэтому здесь предполагается, что это относительно новая версия.
Python 3.5
В нынешнем сообществе Python 3 становится все более и более популярным, и несколько тяжеловесных библиотек/фреймворков больше не поддерживают 2. А 3.5 — более важная версия (если это новый проект, то обычно это сразу 3.5/3.6), поэтому в этой статье используется 3.5.
Статическая набравка важна
Поскольку я не являюсь соответствующим профессионалом, я буду называть это здесь так. Поскольку Python — динамический язык, Type Hint — это не то же самое, что статический тип вроде C++/Java, он используется только как подсказка из IDE (динамический язык выбран, а какой молоток нужен, так и используйте: )). К счастью, сейчас большинство людей используют программирование в среде IDE (имеется в виду написание производственного кода), поэтому Type Hint или что-то в этом роде по-прежнему стоит использовать.
Короче говоря, если Java/C++ уподобить ракетной пушке, то Type Hint легче. Глядя налево и направо, лучше использовать зажигалку, чем "сверлить дрова, чтобы развести огонь" :).
возможные потребности
Для аннотации типа у нас могут быть следующие требования.
Один из них — участие. По типу параметра его можно разделить на следующие категории:
- Основные встроенные типы, такие как str, int, list
- Сложные типы, полученные в результате комбинации примитивных типов, таких как list[int], dict[str, int]
- Пользовательские классы, такие как Person, Animal
- Параметры функции, а именно вызываемые, такие как параметры обратного вызова: (значение: str, индекс: int) => str
Второй — выходной параметр (возвращаемое значение). Это в основном то же самое, что и классификация входных параметров, и повторяться не будет.
Давайте посмотрим, как реализовать требования, перечисленные выше в пунктах 2 и 3 соответственно.
Второй способ Python: строка документа
Pycharm имеет относительно полную поддержку для этого, чего в принципе достаточно, единственный недостаток — громоздкость.
Пример выглядит следующим образом:
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
def get_name(self):
return self._name
def get_age(self):
return self._age
class Py2TypehintTester:
def test1(self, a, b, c):
"""第一种需求
基本很容易满足
:type a: str
:param a:
:type b: str
:param b:
:type c: list
:param c:
:rtype: list
:return:
"""
return [a, b, c]
def test2(self, a, b, c):
"""第二种需求
也很容易满足,只不过需要遵循 Pycharm 规定的语法, 它才能正确解析
:type a: list[str]
:param a:
:type b: list[int]
:param b:
:type c: dict[str, int]
:param c:
:rtype: dict[str, str]
:return:
"""
for item in a:
item.upper()
def test3(self, p):
"""第三种需求
也很容易满足.
不过需要对应的 class 在本module 的空间内( 比如, 从别处 import 进来也是可以的)
:type p: Person
:param p:
:return:
"""
age = p.get_age()
def test4(self, callback):
"""第四种需求
会让你容易满足, 需要遵循特定写法
:type callback: (str, int) -> str
:param callback:
:return:
"""
s = 's'
i = 1
result = callback(s, i)
print(result) # 能正确推导为str
Преимущества этого метода очевидны, а именно: Нет никакой зависимости, просто следуйте предписанному методу написания.
Способ Python 3: подсказка типа
Этот способ официально предусмотрен, по сравнению с вышеописанным, он в принципе намного проще и интуитивно понятен, и может потребоваться некоторое время, чтобы к нему привыкнуть.
Пример выглядит следующим образом:
import typing # 需求导入这个库
# 生成复合类型, 这段代码请无视
FloatVector = typing.List[float]
StrList = typing.List[str]
MyT = typing.TypeVar('T')
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
def get_name(self):
return self._name
def get_age(self):
return self._age
class Py3TypehintTester:
def test1(self, a: str, b: str, c: str) -> list:
"""第一种需求
很简单, 形式比较简洁
:param a:
:param b:
:param c:
:return:
"""
return [a, b, c]
def test2(self, a: typing.List[str],
b: typing.List[str],
c: typing.Dict[str, int]) -> typing.Dict[str, str]:
"""第二种需求
比较简单, 需要先了解 typing 这个库
:param a:
:param b:
:param c:
:return:
"""
return {
'str': 'str1'
}
def test3(self, p: Person):
"""第三种需求
比较简单
:param p:
:return:
"""
print(p.get_age())
def test4(self, callback: typing.Callable[[str, int], str]):
"""第四种需求
稍复杂, 需要先仔细阅读下代码
不过这种需求基本出现的频率不多, 倒也不影响大局
:param callback:
:return:
"""
s = 's'
i = 1
result = callback(s, i)
print(result) # 能推导为str
мой подход
if >= 3.5:
使用第二种,毕竟简洁许多,而且也没啥学习成本,十几分钟的事
要求也比较高: 对 IDE 版本和 Python 版本均有要求
else:
使用第一种,可以视作过渡吧,反正兼容性是最好的,哪个版本的 Pycharm 都能正确提示
приложение
- Документация по подсказкам типа Pycharm: https://www.jetbrains.com/help/pycharm/type-hinting-in-pycharm.html