Python functions return type

Python Typing: declare return value type based on function argument

That list is not exhaustive, I’d like to be able to use any type with appropriate constructor. Then, I’d like to add type hints for that function. What should be the type hint for return value of that function? I’ve tried using simply t , as t is a type:

def fun(t: type) -> t: return t(42) 
from typing import TypeVar T = TypeVar("T") def fun(t: T) -> T: return t(42) 

But that doesn’t seem to be right, as T denotes a type, so it suggests that type itself is returned, not its instance. Mypy rejects it:

from typing import Any def fun(t: type) -> Any: return t(42) 

Related question: Python type hint for (any) class — Stack Overflow ■ Side note, if you don’t require fun to be a function and the return value is’ custom class you may want to make that class generic and call it like Fun[Union[int, float]]() .

2 Answers 2

TLDR: You need a TypeVar for the return type of calling t :

def fun(t: Callable[[int], R]) -> R: . 

Constraining on a type is too restrictive here. The function accepts any Callable that takes an integer, and the return type of the function is that of the Callable . This can be specified using a TypeVar for the return type:

from typing import Callable, TypeVar R = TypeVar('R') # the variable return type def fun(t: Callable[[int], R]) -> R: return t(42) fun(int) # Revealed type is 'builtins.int*' fun(float) # Revealed type is 'builtins.float*' reveal_type(fun(lambda x: str(x))) # Revealed type is 'builtins.str*' 

This works for types as well, because type instantiation is a call.

Читайте также:  Sovets net 4153 kak obnovit navigator navitel html

If a more complex signature, e.g. with keyword arguments, is needed, use Protocol (from typing or typing_extensions ).

Note that if one explicitly wants to pass only 42 to the Callable , Literal (from typing or typing_extensions ) can be used to specify that.

R = TypeVar('R') def fun(t: Callable[[Literal[42]], R]) -> R: return t(42) 

Note that any function of the type Callable[[int], R] also satisfies Callable[[Literal[42]], R] .

Источник

Using Type Hints When Defining A Python Function [Intermediate Python Functions Series #6]

You’ve already covered a lot of ground in this Intermediate Python Functions series. In this article, you’ll read about a relatively new addition in Python called type hinting or type annotation. Unlike all the other topics you learnt about in the previous articles, this one will not change the behaviour of the function you define. So why bother? Let’s find out.

Overview Of The Intermediate Python Functions Series

Here’s an overview of the seven articles in this series:

  1. Introduction to the series: Do you know all your functions terminology well?
  2. Choosing whether to use positional or keyword arguments when calling a function
  3. Using optional arguments by including default values when defining a function
  4. Using any number of optional positional and keyword arguments: args and kwargs
  5. Using positional-only arguments and keyword-only arguments: the “rogue” forward slash / or asterisk * in function signatures
  6. [This article] Type hinting in functions
  7. Best practiceswhen defining and using functions

Type Hints in Python Functions

Let’s see what type hints are with the following example:

def greet_person(person: str, number: int): for greeting in range(number): print(f"Hello ! How are you doing today?") # 1. greet_person("Sam", 4) # 2. greet_person(2, 4)

You define the function greet_person() which has two parameters:

In the function definition, the parameters also have type hints. The type hint follows immediately after the parameter name and a colon. The function’s signature shows str as the data type annotation for person and int as the annotation for number .

However, these are just hints or annotations. They do not force the parameters to take only those data types as inputs. You can confirm this by running the code above. Both function calls run without errors even though the second call has an int as its first argument when its type hint indicates that it’s meant to be a str :

Hello Sam! How are you doing today? Hello Sam! How are you doing today? Hello Sam! How are you doing today? Hello Sam! How are you doing today? Hello 2! How are you doing today? Hello 2! How are you doing today? Hello 2! How are you doing today? Hello 2! How are you doing today?

So, if the code still works, what do type hints do?

Tools Which Make Use Of Type Hints in Python Functions

Let’s look at the code above as seen in the IDE I’m using. I’m using PyCharm, but you’ll also get similar behaviour in other IDEs.

Screenshot from PyCharm showing warnings due to type hints in Python

You can see that one of the arguments is highlighted in yellow in the second function call. The first argument, the integer 2 , has a warning. When you hover over the argument, a warning pops up: “Expected type ‘str’, got ‘int’ instead”.

Even though the code still runs and doesn’t give an error message, the IDE warns you before you run your code to inform you that the argument you used doesn’t match the expected data type. The expected data type is the one used in the type hint.

There are other tools which check type hints and provide warnings, too. Therefore, even though type hints do not change the function’s behaviour, they can minimise errors and bugs. The user is less likely to misuse the function if they get warnings when using the wrong data types.

Type Hints For Return Values in Python Functions

Let’s look at another variation of the function:

def greet_people(people: list) -> list: return [f"Hello ! How are you doing today?" for person in people] result = greet_people(["James", "Matthew", "Claire"]) for item in result: print(item.upper())

The parameter people has a type annotation showing it should be passed a list. There’s also the -> symbol followed by list before the colon at the end of the function signature. You’ll see what this is soon.

Let’s first look at the output from this code:

HELLO JAMES! HOW ARE YOU DOING TODAY? HELLO MATTHEW! HOW ARE YOU DOING TODAY? HELLO CLAIRE! HOW ARE YOU DOING TODAY?

The annotation -> list at the end of the signature shows that the function’s return value should be a list. This type hint lets anyone reading the function definition know that this function returns a list.

More complex type hints

Let’s go a bit further to see the benefit of this type of annotation. Here’s another version. There’s an error in the for loop:

def greet_people(people: list) -> list: return [f"Hello ! How are you doing today?" for person in people] result = greet_people(["James", "Matthew", "Claire"]) for item in result: print(item.append(5))

This code raises the following error:

Traceback (most recent call last): File ". ", line 7, in print(item.append(5)) ^^^^^^^^^^^ AttributeError: 'str' object has no attribute 'append'

The variable result is a list which contains strings. Therefore, the variable item in the for loop will contain a string. You cannot use append() on these strings since append() is not a str method. The type annotation you have now doesn’t help in this situation. It indicates that the function should return a list, which it does.

But is it possible to get a warning of this issue before you run the code using type hints? Can we find out that this is not the right kind of list?

Let’s improve the return value’s type annotation:

def greet_people(people: list) -> list[str]: return [f"Hello ! How are you doing today?" for person in people] result = greet_people(["James", "Matthew", "Claire"]) for item in result: print(item.append(5))

Note that the return value’s type annotation is now list[str] . This indicates that the function returns a list of strings, not just any list.

Let’s see what this code looks like in PyCharm:

Screenshot from PyCharm showing warnings due to type hints in Python for function return values

The IDE highlights the append() method on the last line. Type hints indicate that the data the function returns is a list of strings. Therefore the IDE “knows” that item should be a str in the final for loop since result is a list of strings. The IDE warns you that append() is not a string method.

Should You Start Using Type Hints When Defining Python Functions?

Opinions are split in the Python community on how and when you should use type hinting. Python is a dynamic language–this means that you don’t have to declare the data type of variables as they are dynamically assigned when the program runs. Type hinting does not make Python a static language.

You may hear some say that you should always use type hints. In some programming environments, such as in teams writing production code, type hints have nearly become standard. They make working in large teams easier and minimise bugs. In such programming teams, type hints are almost always used.

However, there are situations when you don’t need them and the code you write is simpler without them. There are still many programming applications in which code which doesn’t have type hints is perfectly fine.

So don’t feel pressured to use them all the time!

Further Reading

  • Chapter 3: Power-up Your Coding: Create Your Own Functions for an in-depth introduction to Python functions
  • Chapter 6: Functions Revisited. This chapter covers topics that will be dealt with later on in the series
  • The White Room: Understanding Programming. In this article, I briefly referred to parameters as boxes which store data. This is part of a broader analogy I like to use. You can read more in this chapter
  • Using Python Optional Arguments When Defining Functions is an article I wrote for Real Python if you want to read ahead.

Источник

How to specify method return type list of (what) in Python?

If I want to be more specific and tell that my return type is a list of ValidationMessages? How should I / Can I achieve that? (I would check off the mark as a duplicate, since this is not about extending a list or flattening) I’m asking about how to be more specific on identifying the return type of a method.

Go straigth to the documentation: docs.python.org/3/library/typing.html — define an alias and return that as type hint — your exactuse case would be here

More an opinion than an answer, but if you want strict type checking, Java is a better choice than Python. Anyway, PatrickArtner’s comment is the answer.

1 Answer 1

With Python 3.6, the built-in typing package will do the job.

from typing import List def validate(self, item:dict, attrs:dict)-> List[str]: . 

The notation is a bit weird, since it uses brackets but works out pretty well.

Edit: With the new 3.9 version of Python, you can annotate types without importing from the typing module. The only difference is that you use real type names instead of defined types in the typing module.

def validate(self, item:dict, attrs:dict)-> list[str]: . 

NOTE: Type hints are just hints that help IDE. Those types are not enforced. You can add a hint for a variable as str and set an int to it like this:

 a:str = 'variable hinted as str' a = 5 # See, we can set an int 

Your IDE will warn you but you will still be able to run the code. Because those are just hints. Python is not a type strict language. Instead, it employs dynamic typing.

Источник

Оцените статью