2012-03-06 3 views
4

В частности, часть «: int» ...В чем смысл def some_method (param: int) синтаксис?

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

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

some_method(1) 

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

some_method("asdfaslkj") 

В обоих случаях печатается «бла» - исключение исключено.

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

EDIT: OK, так что это http://www.python.org/dev/peps/pep-3107/. Я вижу, как это было бы полезно в рамках, которые используют метаданные. Я не предполагал, что это так. Спасибо за ответы!

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

+2

[Функция аннотаций] (http://www.python.org/dev/peps/pep-3107/) –

ответ

4

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

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

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

+0

Большие пункты ... –

1

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

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

intToHexString(param:int) 

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

1

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

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

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

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

+0

Основываясь на этой идее, мне интересно, если вместо specifiying _int_ вас может указывать что-то вроде _numerical_value_, так как это все равно метаданные. Вам нужно было бы определить _number_value_ где-то и один недостаток (по крайней мере, в PyCharm) - это то, что _number_value_ не выделяется ярким цветом, как делает _int_. Тем не менее, может быть какая-то настройка, чтобы сделать это возможным. –

3

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

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

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

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

def mul(a:int, b:int) -> None: 
    print(a*b) 
+0

спасибо! Я задавался вопросом, есть ли способ сделать это! –

Смежные вопросы