Come posso specificare il tipo di funzione nei miei suggerimenti sul tipo?


137

Voglio usare i suggerimenti sul tipo nel mio attuale progetto Python 3.5. La mia funzione dovrebbe ricevere una funzione come parametro.

Come posso specificare la funzione del tipo nei miei suggerimenti sul tipo?

import typing

def my_function(name:typing.AnyStr, func: typing.Function) -> None:
    # However, typing.Function does not exist.
    # How can I specify the type function for the parameter `func`?

    # do some processing
    pass

Ho controllato PEP 483 , ma non sono riuscito a trovare un suggerimento sul tipo di funzione.


21
Una funzione èCallable
jonrsharpe

3
python.org/dev/peps/pep-0483/#fundamental-building-blocks , ultimo punto elenco prima di "potremmo aggiungere".

Risposte:


175

Come ha notato @jonrsharpe in un commento, questo può essere fatto con typing.Callable:

from typing import AnyStr, Callable

def my_function(name: AnyStr, func: Callable) -> None:

Il problema è Callableche da solo è tradotto in Callable[..., Any]che significa:

Un callable accetta un numero qualsiasi di argomenti / tipo e restituisce un valore di qualsiasi tipo. Nella maggior parte dei casi, questo non è ciò che desideri poiché consentirai il passaggio di praticamente qualsiasi funzione. Si desidera che vengano suggeriti anche i parametri della funzione e i tipi restituiti.

Ecco perché molti typesdi typingessere stato sovraccaricato di supporto sub-scripting che denota questi tipi di extra. Quindi, se, ad esempio, hai una funzione sumche richiede due se intrestituisce un int:

def sum(a: int, b: int) -> int: return a+b

La tua annotazione per esso sarebbe:

Callable[[int, int], int]

vale a dire, i parametri sono sotto script nella sottoscrizione esterna con il tipo restituito come secondo elemento nella sottoscrizione esterna. In generale:

Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]

26
questa typingroba sposta l'intero linguaggio Python su una tacca.
javadba

1
@javadba - Oh, sì, ma non sono ancora sicuro su cui quadrante ... Tra l'altro - che dire Callable[[Arg, Types, Here], ...]per *args, **kwargs, args per parole chiave solo e soltanto argomenti di posizione? Non hanno pensato di chiamare la convenzione nelle firme del tipo per i callables? ;)
Tomasz Gandor

10

Un altro punto interessante da notare è che puoi usare la funzione incorporata type()per ottenere il tipo di una funzione incorporata e usarla. Quindi potresti avere

def f(my_function: type(abs)) -> int:
    return my_function(100)

O qualcosa di quella forma


Un suggerimento sul tipo può essere quello che desideri, ma non sono sempre stati valutati in modo pigro. Inoltre, la tua funzione prende davvero solo builtin_function_or_methodcome my_function? Non lambdafunzionerebbe? Una funzione definita dall'utente o un metodo vincolato?
Tomasz Gandor
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.