2012-08-30 6 views
5

Las anotaciones de funciones parecen duplicar el comportamiento que ya se encuentra en Python. No sólo eso, el significado que adquieren no se hace cumplir de ninguna manera, por lo que se pueden usar para cualquiera de los siguientes documentado en PEP 3107:¿Por qué las anotaciones de funciones necesitan una sintaxis dedicada en Python?

  • Proporcionar escribir la información
  • Tipo comprobar
  • IDE permiten mostrar qué tipo de una función espera y devuelve
  • sobrecarga de funciones/funciones genéricas
  • puentes en lengua extranjera
  • Adaptati en
  • funciones de la lógica de predicados
  • mapeo de consulta de base de datos
  • parámetro de cálculo de referencias de RPC
  • Otra información
  • Documentación de parámetros y devolver valores

o incluso algo completamente diferente.

En cierta forma, función anotaciones me recuerda la vieja broma en Python's humour collection:

De hecho, Python ya es compatible con delimitadores de bloque:

> 
>  if foo: #{ 
>   foo1(); 
>   foo2(); 
>   foo3(); 
>  #} 

en que

def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9): 
    ... 

no es más útil que:

# a: 'x', b: 5 + 6, c: list 
def foo(a, b, c): #-> max(2, 9): 
    ... 

Se podría argumentar que las anotaciones de función son necesarias porque a diferencia de los comentarios, que se puede acceder desde dentro del código, como:

>>> def spam(a: 'eggs') -> 'ni!': 
...  pass 
... 
>>> spam.__annotations__ 
{'a': 'eggs', 'return': 'ni!'} 

aunque este mismo comportamiento se puede conseguir fácilmente con decoradores, como:

def param(**kw): 
    def decorator(func): 
     def wrap(*args): 
      print kw 
      func(*args) 
     return wrap 
    return decorator 

def return_(arg): 
    def decorator(func): 
     def wrap(*args): 
      func(*args) 
      print arg 
     return wrap 
    return decorator 

@param(a='eggs') 
@return_('ni!') 
def spam(a): 
    pass 

spam(None) 

# Output: 
# ------- 
## {'a': 'eggs'} 
## ni! 

Python ya puede hacer lo que hacen las anotaciones, entonces ¿por qué las anotaciones de funciones necesitan una sintaxis dedicada?

EDIT: Voy a hacer un poco de expansión en mi pregunta, ya que su significado ha resultado ser poco claro.

estoy haciendo esta pregunta específicamente acerca función anotaciones en contraposición a decoradores, donde

@decorator 
def spam(): 
    pass 

es la abreviatura de

def spam(): 
    pass 
spam = decorator(spam) 

y método de llamada, donde

self.method(param) 

es corta para

Class.method(self, param) 

Con estos dos atajos sintácticos abreviados, sus significados no pueden variar. No estoy preguntando por qué tales atajos son necesarios cuando hay alternativas preexistentes; eso es una cuestión de legibilidad. función anotaciones son ligeramente diferentes de estos dos accesos directos, en el que

def spam() -> int: 
    pass 

y

def spam() -> 'integer': 
    pass 

puede tener significados idénticos a los humanos, pero no tienen significados idénticos a un ordenador. Incluso si un programador conoce qué las anotaciones deberían definir, no hay una definición acordada de cómo las anotaciones lo definen. Además, las anotaciones no afectan a la funcionalidad, por lo que no es necesario ser coherente.

Así que aquí es mi pregunta revisada:

¿Por qué la función anotaciones necesitan una sintaxis específica cuando proporcionan una forma cambiante y potencialmente incompatibles de acceder a las características del lenguaje ya existentes? ¿Por qué no hay una definición forzada en cómo usar las anotaciones, cuando hay una definición perfecta de para qué pueden usarse (PEP 3107)?

+1

C ya puede hacer lo que hace Python, entonces ¿por qué Python necesita una sintaxis dedicada? –

+1

@ Michał Górny "Binary ya puede hacer lo que C, entonces ¿por qué C necesita una sintaxis dedicada?" Te estás perdiendo mi punto. Si quisiera usar otro lenguaje de programación, lo haría. –

+3

Creo que * usted * está perdiendo mi punto. Básicamente, estás preguntando: ¿por qué agregar nuevas funciones cuando se puede lograr lo mismo con pocas líneas personalizadas? –

Respuesta

6

PEP 3107 que se vincula a parece dar una respuesta a su pregunta en la sección de "lógica":

Fundamento

Debido a la serie 2.x de Python carece de una forma estándar de anotar un los parámetros de la función y los valores de retorno, una variedad de herramientas y bibliotecas parecen llenar este vacío. Algunos utilizan los decoradores introducidos en "PEP 318", mientras que otros analizan el docstring de una función, buscando anotaciones allí.

Este PEP tiene como objetivo proporcionar una forma única y estándar de especificar esta información , reduciendo la confusión causada por la amplia variación en el mecanismo y la sintaxis que ha existido hasta este punto.

+0

Creo que las soluciones existentes son mejores. – endolith

6

¿Cuál es el punto de la sintaxis del decorador?No permite que hagas nada que no podía hacer antes:

@staticmethod 
def foo(): 
    pass 

es apenas

def foo(): 
    pass 
foo = staticmethod(foo) 

Pero la sintaxis de decorador es más agradable.

De estos dos, que es más agradable:

@param(a='eggs') 
@return_('ni!') 
def spam(a): 
    pass 

def spam(a: 'eggs') -> 'ni!': 
    pass 

Las opiniones pueden ser diferentes, pero creo que la segunda es más agradable.

Cuestiones relacionadas