3

In python the method parameter types need not be specified. Python dynamically interprets them.

But in some code snippets I see the type being defined.

def method(p1: int, p2: int) -> None

1) Why is this done 2) for other data structures i need to define only the data structure and not type of the parameters it is accepting

def multiply(num1: list, num2: list):

Why is the purpose of such a design.

and why i am not allowed to define the type of the list

def multiply(num1: list[int], num2: list[int]):
Sree
  • 1,694
  • 1
  • 18
  • 29
  • See [Typing](https://docs.python.org/3/library/typing.html). You can write perfectly valid code without it and it's relatively recent in the language so there's plenty of code that doesn't use it. – roganjosh Apr 13 '19 at 10:52
  • possible duplicate: https://stackoverflow.com/questions/32557920/what-are-type-hints-in-python-3-5 – hiro protagonist Apr 13 '19 at 10:54
  • For last part of your question, you have to use List[int] from typing module to specify type of elements in various collections. – Tomáš Zahradníček Apr 13 '19 at 10:55
  • @TomášZahradníček I am getting back a error def multiply(num1: List[int], num2: list): NameError: name 'List' is not defined – Sree Apr 13 '19 at 10:56
  • @Sree `from typing import List` – gmds Apr 13 '19 at 10:57
  • @gmds what would be the difference between using list and List ?. – Sree Apr 13 '19 at 11:02
  • @Sree Well, the main thing is that you can't do `list[int]` as a type hint; it's a syntax error. Therefore, there's a special type, `typing.List`, that you import just for type hinting. – gmds Apr 13 '19 at 11:02

3 Answers3

6

For the execution of the script, type annotations are irrelevant (they are discarded by the interpreter).

But they are generally a good thing for code clarity. You can immediately see what types of parameters or return type a particular function/method is accepting or returning. Also, IDEs (PyCharm for example) usually highlight or warns when you try to pass different type to an annotated function, and can more easily infer types of variable you assign the result of annotated function to.

That being said, as interpreter doesn't care for type annotations, it will not stop you from passing a wrong type of parameter to a function (different than annotated). The same applies when you declare for example return type of a function to be a number but in the body of function you return a string. IDE can highlight it, but interpreter doesn't care.

3

From Documentation:

A type alias is defined by assigning the type to the alias. In this example, Vector and List[float] will be treated as interchangeable synonyms:

from typing import List
Vector = List[float]

def scale(scalar: float, vector: Vector) -> Vector:
    return [scalar * num for num in vector]

# typechecks; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])

So the point is you have to from typing import List, and then you can use List[int] or whatever type you want

But as for what is the purpose of this, it prevents many bugs specially when several people are working on a code base and want to use each other's functions. Or when you come back to a project after some time and don't remember anything

More explanation:

The type hinting is solely for making the code more readable and understandable for human eye. AFAIK the List or any other type defined in typing may have not even implemented any logic or data structure.

Amir
  • 1,885
  • 3
  • 19
  • 36
  • how different is List from list. – Sree Apr 13 '19 at 14:30
  • `list` is a built-in type. `List` is a type defined in `typing` which is recognized by `typing` for type hinting purposes. They have nothing to do with each other, except that they have the same name so when you see `List[int]` you understand that it expects a `list` of `int`s – Amir Apr 13 '19 at 14:59
3

Type hinting is very useful to make sure is the received parameter as you expected .. it's like a contract or a policy describes how your function want to deal with the parameters .. and typically the most case of it is with OOP.

Imagine that your function is depending on an other object and it knows that object contains a method called foo

 class MyObject:
     def foo():
       print("called")


 def my_method(obj: MyObject):
     obj.foo()

we're calling a foo method with confidence because we only accepts an object instantiated from MyObject class that we know for sure contains a foo method

hazem ali
  • 301
  • 2
  • 7