Tür ipuçlarımda işlev türünü nasıl belirtebilirim?


137

Mevcut Python 3.5 projemde tip ipuçlarını kullanmak istiyorum. Benim fonksiyonum parametre olarak bir fonksiyon almalıdır.

Yazım ipuçlarımda tür işlevini nasıl belirtebilirim?

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

PEP 483'ü kontrol ettim , ancak orada bir işlev türü ipucu bulamadım.


21
Bir işlevCallable
jonrsharpe

3
python.org/dev/peps/pep-0483/#fundamental-building-blocks , "ekleyebiliriz" den önceki son madde işareti.

Yanıtlar:


175

@Jonrsharpe'ın bir yorumda belirttiği gibi , bu şu şekilde yapılabilir typing.Callable:

from typing import AnyStr, Callable

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

Sorun, Callablekendi başına tercüme edilmiştir, Callable[..., Any]bunun anlamı:

Çağrılabilir, herhangi bir sayıda / türde bağımsız değişken alır ve herhangi bir türden bir değer döndürür. Çoğu durumda, hemen hemen her işlevin geçmesine izin vereceğiniz için istediğiniz bu değildir. İşlev parametrelerinin ve dönüş türlerinin de ipucu verilmesini istiyorsunuz.

İşte en niçin birçok typesiçinde typingbu ekstra türlerini belirtir destek alt komut dosyası için aşırı edilmiştir. Öyleyse, örneğin, sumiki ints alan ve bir döndüren bir fonksiyonunuz varsa int:

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

Bunun için ek açıklamanız şöyle olacaktır:

Callable[[int, int], int]

diğer bir deyişle, parametreler, dış abonelikte ikinci öğe olarak dönüş türü ile dış abonelikte alt kodlanır. Genel olarak:

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

26
bu typingşeyler tüm python dilini bir çentik yukarı taşır.
javadba

1
@javadba - Ah, evet, ama ben arada ... hangi kadranında emin hala değilim - ne hakkında Callable[[Arg, Types, Here], ...]için *args, **kwargsanahtar kelime okunur args ve konumsal tek args? Çağırılabilir tip imzalarında kongre çağırmayı düşünmediler mi? ;)
Tomasz Gandor

11

Unutulmaması gereken bir başka ilginç nokta, yerleşik bir işlevin type()türünü elde etmek ve bunu kullanmak için yerleşik işlevi kullanabilmenizdir. Böylece alabilirsin

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

Ya da bu biçimde bir şey


Bir tür ipucu dilediğiniz gibi olabilir, ancak her zaman tembel olarak değerlendirilmemiştir. Ayrıca, işlev gerçekten sadece sürer builtin_function_or_methodolarak my_function? Bir lambdaiş olmaz mı? Kullanıcı tanımlı bir işlev mi yoksa bağlı bir yöntem mi?
Tomasz Gandor

en azından sorun giderme veya beyin fırtınası için çok akıllıca bir yol
oldpride
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.