ฉันจะระบุประเภทฟังก์ชันในคำแนะนำประเภทของฉันได้อย่างไร


137

ฉันต้องการใช้คำแนะนำประเภทในโครงการ Python 3.5 ปัจจุบันของฉัน ฟังก์ชันของฉันควรได้รับฟังก์ชันเป็นพารามิเตอร์

ฉันจะระบุฟังก์ชันประเภทในคำแนะนำประเภทของฉันได้อย่างไร

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แต่ไม่พบคำแนะนำประเภทฟังก์ชันที่นั่น


21
ฟังก์ชันคือCallable
jonrsharpe

3
python.org/dev/peps/pep-0483/#fundamental-building-blocksสัญลักษณ์แสดงหัวข้อสุดท้ายก่อน "เราอาจเพิ่ม"

คำตอบ:


175

ดังที่@jonrsharpeระบุไว้ในความคิดเห็นสามารถทำได้ด้วยtyping.Callable:

from typing import AnyStr, Callable

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

ปัญหาคือCallableแปลด้วยตัวเองCallable[..., Any]ซึ่งหมายความว่า:

callable จะใช้อาร์กิวเมนต์/ ประเภทจำนวนเท่าใดก็ได้และส่งกลับค่าประเภทใดก็ได้ ในกรณีส่วนใหญ่นี่ไม่ใช่สิ่งที่คุณต้องการเนื่องจากคุณจะอนุญาตให้ส่งผ่านฟังก์ชันใดก็ได้ คุณต้องการให้พารามิเตอร์ฟังก์ชันและชนิดการส่งคืนเป็นคำใบ้ด้วย

นั่นเป็นเหตุผลว่าทำไมหลาย ๆtypesอินถึงtypingได้รับการโหลดมากเกินไปเพื่อรองรับสคริปต์ย่อยซึ่งแสดงถึงประเภทพิเศษเหล่านี้ ตัวอย่างเช่นหากคุณมีฟังก์ชันsumที่ใช้เวลาสองintวินาทีและส่งกลับค่าint:

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

คำอธิบายประกอบของคุณจะเป็น:

Callable[[int, int], int]

นั่นคือพารามิเตอร์เป็นสคริปต์ย่อยในการสมัครสมาชิกภายนอกโดยมีชนิดการส่งคืนเป็นองค์ประกอบที่สองในการสมัครสมาชิกภายนอก โดยทั่วไป:

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

26
typingสิ่งนี้ทำให้ภาษา python ทั้งหมดขึ้น
javadba

1
@javadba - โอ้ใช่ แต่ฉันยังคงไม่แน่ใจว่าที่หน้าปัด ... โดยวิธีการ - สิ่งที่เกี่ยวกับCallable[[Arg, Types, Here], ...]สำหรับ*args, **kwargs, args คำหลักเท่านั้นและ args เพียงตำแหน่ง? พวกเขาไม่ได้คิดเกี่ยวกับการเรียกการประชุมในประเภทลายเซ็นสำหรับ callables หรือ? ;)
Tomasz Gandor

11

อีกประเด็นที่น่าสนใจคือคุณสามารถใช้ฟังก์ชันในตัวtype()เพื่อรับประเภทของฟังก์ชันในตัวและใช้งานได้ ดังนั้นคุณสามารถมี

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

หรือรูปแบบนั้น


คำใบ้ประเภทสามารถเป็นได้ทุกอย่างที่คุณต้องการ แต่พวกเขาไม่เคยขี้เกียจประเมิน นอกจากนี้ฟังก์ชั่นของคุณใช้เวลาเพียงbuiltin_function_or_methodเท่านี้my_functionหรือไม่? จะไม่เวิร์คlambdaเหรอ? ผู้ใช้กำหนดฟังก์ชันหรือวิธีการผูก?
Tomasz Gandor

เป็นวิธีที่ชาญฉลาดมากอย่างน้อยก็สำหรับการแก้ปัญหาหรือการระดมความคิด
oldpride
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.