Какой смысл в синтаксисе def some_method (param: int)? - PullRequest
4 голосов
/ 06 марта 2012

В частности, часть ": int" ...

Я предположил, что он каким-то образом проверял тип параметра во время вызова функции и, возможно, вызвал исключение в случае нарушения.Но следующий запуск без проблем:

def some_method(param:str):
    print("blah")

some_method(1)

def some_method(param:int):
    print("blah")

some_method("asdfaslkj")

В обоих случаях печатается "бла" - исключение не возникает.

Я не уверен, как называется функция, поэтому я не былне знаете, что гуглить.

РЕДАКТИРОВАТЬ: ОК, так что это http://www.python.org/dev/peps/pep-3107/. Я вижу, как это будет полезно в рамках, которые используют метаданные.Это не то, что я предполагал.Спасибо за ответы!

СЛЕДУЮЩИЙ ВОПРОС - Любые мысли о том, хорошая или плохая идея определить мои функции как def some_method (param: int), если я действительно могу обрабатывать только вводы int - даже еслиКак объясняет pep 3107, это всего лишь метаданные - никакого принуждения, как я изначально предполагал?По крайней мере, потребители методов будут ясно видеть, что я намеревался.Это альтернатива документации.Думаешь, это хорошо / плохо / трата времени?Конечно, хорошее именование параметров (в отличие от моего надуманного примера) обычно дает понять, какие типы должны передаваться.

Ответы [ 5 ]

4 голосов
/ 06 марта 2012

он ни для чего не используется - он просто для экспериментов (например, вы можете прочитать их из питона, если хотите). они называются «аннотациями функций» и описаны в pep 3107 .

я написал библиотеку, которая построена на нем для таких вещей, как проверка типов (и многое другое - например, вы можете более легко отобразить из JSON в объекты python), называемая pytyp ( больше информации ), но это не очень популярно ... (я должен также добавить, что часть проверки типов pytyp неэффективна - она ​​может быть полезна для отслеживания ошибок, но вы не захотите использовать ее через вся программа).

[обновление: я бы не рекомендовал использовать аннотации функций в целом (т.е. без особого использования, просто как документы), потому что (1) они могут в конечном итоге привыкнуть так, как вы этого не ожидали, и (2) точный тип вещей часто не так важен в Python (точнее, не всегда ясно, как лучше всего определить тип чего-либо полезным - объекты могут быть довольно сложными, и часто только «части» используются кем-либо функция, с несколькими классами, реализующими эти части по-разному ...). это является следствием утки, набирающей - см. ссылку «дополнительная информация» для связанного обсуждения того, как абстрактные базовые классы python могут использоваться для решения этой проблемы ...]

3 голосов
/ 06 марта 2012

Функциональные аннотации - это то, что вы делаете из них.

Они могут быть использованы для документации:

def kinetic_energy(mass: 'in kilograms', velocity: 'in meters per second'):
     ...

Они могут использоваться для проверки предварительных условий:

def validate(func, locals):
    for var, test in func.__annotations__.items():
        value = locals[var]
        msg = 'Var: {0}\tValue: {1}\tTest: {2.__name__}'.format(var, value, test)
        assert test(value), msg


def is_int(x):
    return isinstance(x, int)

def between(lo, hi):
    def _between(x):
            return lo <= x <= hi
    return _between

def f(x: between(3, 10), y: is_int):
    validate(f, locals())
    print(x, y)


>>> f(0, 31.1)
Traceback (most recent call last):
   ... 
AssertionError: Var: y  Value: 31.1 Test: is_int

Также см. http://www.python.org/dev/peps/pep-0362/ способ реализации проверки типов.

1 голос
/ 06 марта 2012

Вы также можете использовать нотацию "-> returnValue", чтобы указать, какой тип может возвращать функция.

def mul(a:int, b:int) -> None:
    print(a*b)
1 голос
/ 06 марта 2012

В основном он используется только для документации.Когда некоторые проверяют сигнатуру метода, они увидят, что param помечен как int, что скажет им, что автор метода ожидал, что они передадут int.

, потому что программисты на Pythonиспользуйте утку, это не означает, что у вас есть для передачи int, но это говорит о том, что код ожидает что-то "int-like".Таким образом, вам, вероятно, придется передавать что-то в основном «числовое» по своей природе, которое поддерживает арифметические операции.В зависимости от метода он может быть пригоден для использования в качестве индекса, а может и нет.

Однако, поскольку это синтаксис, а не просто комментарий, аннотация видна для любого кода, который хочет проанализироватьон .Это открывает возможность написания typecheck декоратора, который может обеспечить строгую проверку типов для произвольных функций;это позволяет вам размещать логику проверки типа в одном месте, и каждый метод объявляет, какие параметры он хочет, чтобы он был строго проверен (добавляя аннотацию типа) с минимальным синтаксисом, таким образом, чтобы это было видно для программистов-клиентов, которые просматриваютопределения методов, чтобы выяснить интерфейс.

Или вы можете делать другие вещи с этими аннотациями.Стандартизированное значение еще не разработано. Может быть , если кто-то придумает функцию убийцы, которая использует их и получит широкое распространение, то однажды она станет частью языка Python, но я подозреваю, что гибкость их использования будет такой, какой вы захотите, будет слишкомполезно когда-либо делать это.

1 голос
/ 06 марта 2012

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

Например, рассмотрим:

intToHexString(param:int)

Хотя язык может технически разрешить вам звонить intToHexString("Hello"), это не имеет смысла с семантической точки зрения. Наличие :int как части объявления метода помогает усилить это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...