2016/01/06
função Notes (Anotações de função)
Função sintaxe anotação permite definir a função das anotações agregar valor tempo sobre os parâmetros e retorno:
def foobar (a: int, b: "É b", c: str = 5) -> tuple:
voltar a, b, c
a: int
Este parâmetro é um comentárioc: str = 5
Notas há um valores de parâmetros padrão-> tuple
O valor de retorno é um comentário.
anotações conteúdo pode ser ambos os tipos também pode ser uma string, e até mesmo a expressão:
def foobar (a: 1 + 1) -> 2 * 2:
o retorno de um
Então, como é que vamos chegar a anotação função para defini-lo? Há pelo menos duas maneiras:
-
__annotations__
:>>> foobar .__ annotations__ { 'a': int, 'b': "É b", 'c': str, 'return': tupla}
-
inspect.signature
:>>> Importação Inspecione >>> SIG = Inspecionar . Assinatura ( foobar ) >>> # Obter parâmetros da função >>> SIG . Paraments mappingproxy ( OrderedDict ([( 'A' , < o parâmetro "A: int" > ), ( 'B' , < o parâmetro "B:" TI 'S B "">), (' C ', <o parâmetro "C:. STR = 5">)])) >>> # getters parâmetros anotação >>>para K , v emsig . parâmetros . itens (): print ( '{k}: {! um r}' . formato ( k = k , a = v . anotação )) a : < class ' int '> b : "É b" c : < class ' str '> >>> #返回值注解>> sig . return_annotation tupla
Desde que a função de anotação pode ser definido, então podemos usar o tipo de parâmetro verificando-lo.
verificação de tipo
Python intérprete e verificação de tipo não virá função de anotação automaticamente com base, temos de perceber sua própria verificação de tipo:
>>> foobar .__ annotations__
{ 'a': int, 'b': "É b", 'c': str, 'return': tupla}
>>> foobar (a = 'a', b = 2, c = 3)
( 'um', 2, 3)
Agora por inspect.signature
que podemos obter os parâmetros de ordem e de anotação função da definição de função, então podemos verificar o tipo do parâmetro passado para a função são consistentes com a função de anotação, definindo um decorador, função decorador implementado aqui (check_type.py) como se segue:
# Codificação: UTF8
importação coleções
Import functools Import Inspecione DEF Verifique ( FUNC ): MSG = ( 'do tipo esperado {! Esperado P & lt} para o argumento {argumento},' {! Valor R & lt} 'Mas tipo GOT {! GOT R & lt} com o valor ' ) # obter a função definida parâmetros SIG = Inspecione . Assinatura ( FUNC ) parâmetros = SIG . parâmetros # parâmetro ordenou dicionário arg_keys = tupla ( parâmetros . Teclas ()) # nome do parâmetrofunctools.wraps @ ( FUNC ) DEF warpper ( * args , ** kwargs ): CheckItem = coleções . namedtuple ( 'CheckItem' , ( 'Anno' , 'arg_name' , 'valor' )) check_list = [] # * args a coleta args parâmetro transmitido e o correspondente parâmetros da função de anotação para I , valor nos Enumerar ( args ): arg_name = arg_keys [ I ]Anno = Parâmetros [ arg_name ] . Anotação check_list . Append ( CheckItem ( Anno , arg_name , valor )) # ** kwargs os kwargs coletar argumentos passados parâmetros e correspondentes anotações para arg_name , valor em kwargs . Itens (): Anno = parâmetros [ arg_name ] . Anotação check_list . append ( CheckItem ( Anno ,arg_name , valor )) # tipo de verificação de ponto no check_list : se não isinstance ( artigo . valor , artigo . anno ): erro = msg . formato ( esperado = artigo . anno , argumento = artigo . arg_name , tem = tipo ( artigo . valor ), valor = artigo. valor ) aumento TypeError ( erro ) de retorno func ( * args , ** kwargs ) retorno invólucro
Vamos testar a nossa decorador:
@check
def ola (um: int, b: str, c: flutuador = 3.2) -> tupla:
regresso a, b, c
Fim parâmetro de teste de passagem:
>>> ola (1, 'b')
(1 'b', 3,2)
>>> ola (1, 'b', 3,5)
(1, 'b', 3,5)
>>> ola ( 'a' , 'b')
...
TypeError: tipo esperado <class 'int'> para o argumento a, mas o tipo tem <class 'str'> com valor 'a
>>> foobar (1, 2)
...
TypeError: Espera tipo <class 'str'> para o argumento b, mas o tipo tem <class 'int'> com o valor 2
>>> foobar (1, 'b', 3)
...
TypeError: Espera tipo <class 'float'> para argumento c, mas o tipo tem < 'int' class> com valor
Keyword passagem de parâmetros:
>>> ola (b = 'b', a = 2)
(2 'b', 3,2)
>>> ola (b = 'b', a = 2, c = 3,5)
(2 'b', 3.5)
>>> foobar (a = 'foo', b = 'bar')
...
TypeError: tipo esperado <class 'int'> para o argumento a, mas o tipo tem <class 'str'> com valor 'foo'
>>> foobar (b = 3, a = 2)
...
TypeError: tipo esperado <class 'str'> para o argumento b, mas o tipo tem <class 'int'> com valor 3
>>> foobar (a = 2 , b = 'bar', c = 3)
...
TypeError: Espera tipo <class 'float'> para o argumento c, mas o tipo tem <class 'int'> com valor
Anotações funcionar por meio de um único parâmetro do tipo decorador verificação assim alcançada.