(Anotações função) sintaxe para alcançar a função de verificação de tipo de parâmetro baseado em Python 3 comentário

 

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ário
  • c: 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.

Acho que você gosta

Origin www.cnblogs.com/vincent-sh/p/12638649.html
Recomendado
Clasificación