Làm cách nào để chỉ định kiểu hàm trong gợi ý kiểu của tôi?


137

Tôi muốn sử dụng gợi ý kiểu trong dự án Python 3.5 hiện tại của mình. Hàm của tôi sẽ nhận một hàm dưới dạng tham số.

Làm cách nào để chỉ định hàm kiểu trong gợi ý kiểu của tôi?

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

Tôi đã kiểm tra PEP 483 , nhưng không thể tìm thấy gợi ý loại hàm ở đó.


21
Một chức năng làCallable
jonrsharpe

3
python.org/dev/peps/pep-0483/#fundaries-building-blocks , dấu đầu dòng cuối cùng trước "chúng tôi có thể thêm".

Câu trả lời:


175

Như @jonrsharpe đã lưu ý trong một nhận xét, điều này có thể được thực hiện với typing.Callable:

from typing import AnyStr, Callable

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

Vấn đề là, Callablebản thân nó được dịch sang Callable[..., Any]có nghĩa là:

Một có thể gọi nhận bất kỳ số / loại đối số nào và trả về một giá trị thuộc bất kỳ loại nào. Trong hầu hết các trường hợp, đây không phải là điều bạn muốn vì bạn sẽ cho phép chuyển khá nhiều chức năng. Bạn cũng muốn các tham số hàm và kiểu trả về cũng được gợi ý.

Đó là lý do tại sao nhiều typestrong typingđã bị quá tải để hỗ trợ tập lệnh phụ biểu thị các loại bổ sung này. Vì vậy, ví dụ, nếu bạn có một hàm sumnhận hai ints và trả về int:

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

Chú thích của bạn cho nó sẽ là:

Callable[[int, int], int]

nghĩa là, các tham số được viết theo tập lệnh con trong gói đăng ký bên ngoài với kiểu trả về là phần tử thứ hai trong gói đăng ký bên ngoài. Nói chung:

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

26
typingcông cụ này nâng toàn bộ ngôn ngữ python lên một bậc.
javadba

1
@javadba - ồ, vâng, nhưng tôi vẫn không chắc về mặt số nào ... Nhân tiện - còn Callable[[Arg, Types, Here], ...]đối với *args, **kwargsargs chỉ từ khóa và args chỉ vị trí thì sao? Họ đã không nghĩ về quy ước gọi trong các chữ ký kiểu cho các bên gọi? ;)
Tomasz Gandor

10

Một điểm thú vị khác cần lưu ý là bạn có thể sử dụng hàm tích hợp type()để lấy loại hàm tích hợp và sử dụng nó. Vì vậy, bạn có thể có

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

Hoặc một cái gì đó ở dạng đó


Gợi ý kiểu có thể là bất cứ điều gì bạn muốn, nhưng chúng không phải lúc nào cũng được đánh giá một cách lười biếng. Ngoài ra, chức năng của bạn chỉ thực sự có chức năng builtin_function_or_methodnhư my_functionthế nào? Sẽ không phải là một lambdacông việc? Một chức năng do người dùng xác định hoặc phương thức ràng buộc?
Tomasz Gandor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.