Bagaimana saya bisa menentukan tipe fungsi dalam petunjuk tipe saya?

137

Saya ingin menggunakan petunjuk tipe dalam proyek Python 3.5 saya saat ini. Fungsi saya harus menerima fungsi sebagai parameter.

Bagaimana saya bisa menentukan fungsi tipe dalam petunjuk tipe saya?

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

Saya memeriksa PEP 483 , tetapi tidak dapat menemukan petunjuk jenis fungsi di sana.

Jon
sumber
21
Fungsi adalahCallable
jonrsharpe
3
python.org/dev/peps/pep-0483/#fundamental-building-blocks , poin terakhir sebelum "kami dapat menambahkan".

Jawaban:

175

Seperti yang dicatat @jonrsharpe dalam komentar, ini dapat dilakukan dengan typing.Callable:

from typing import AnyStr, Callable

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

Issue is, Callableitu sendiri diterjemahkan Callable[..., Any]yang artinya:

Callable mengambil sejumlah / tipe argumen dan mengembalikan nilai tipe apa pun. Dalam kebanyakan kasus, ini bukan yang Anda inginkan karena Anda akan mengizinkan hampir semua fungsi untuk diteruskan. Anda ingin parameter fungsi dan tipe kembalian diberi petunjuk juga.

Itulah mengapa banyak typesdi typingtelah kelebihan beban untuk mendukung sub-skrip yang menunjukkan jenis tambahan ini. Jadi jika, misalnya, Anda memiliki fungsi sumyang membutuhkan dua ints dan mengembalikan int:

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

Anotasi Anda untuk itu adalah:

Callable[[int, int], int]

yaitu, parameter di-sub-skrip di langganan luar dengan tipe kembalian sebagai elemen kedua di langganan luar. Secara umum:

Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]
Dimitris Fasarakis Hilliard
sumber
26
typinghal ini menggerakkan seluruh bahasa python ke atas.
javadba
1
@javadba - oh, ya, tapi aku masih tidak yakin di mana panggil ... By the way - bagaimana Callable[[Arg, Types, Here], ...]untuk *args, **kwargs, args kata kunci hanya dan hanya args posisi? Apakah mereka tidak berpikir untuk memanggil konvensi dalam tipe signature untuk callable? ;)
Tomasz Gandor
10

Hal menarik lainnya yang perlu diperhatikan adalah Anda dapat menggunakan fungsi bawaan type()untuk mendapatkan jenis fungsi bawaan dan menggunakannya. Jadi Anda bisa saja

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

Atau sesuatu dari bentuk itu

Hallsville3
sumber
Petunjuk tipe bisa berupa apa pun yang Anda inginkan, tetapi tidak selalu dinilai malas. Juga, apakah fungsi Anda benar-benar hanya berfungsi builtin_function_or_methodsebagai my_function? Bukankah akan lambdaberhasil? Fungsi yang ditentukan pengguna atau metode terikat?
Tomasz Gandor