The other answers have done a good job at explaining duck typing and the simple answer by tzot:
Python does not have variables, like other languages where variables have a type and a value; it has names pointing to objects, which know their type.
However, one interesting thing has changed since 2010 (when the question was first asked), namely the implementation of PEP 3107 (implemented in Python 3). You can now actually specify the type of a parameter and the type of the return type of a function like this:
def pick(l: list, index: int) -> int:
return l[index]
Here we can see that pick takes 2 parameters, a list l and an integer index. It should also return an integer.
So here it is implied that l is a list of integers which we can see without much effort, but for more complex functions it can be a bit confusing as to what the list should contain. We also want the default value of index to be 0. To solve this you may choose to write pick like this instead:
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
Note that we now put in a string as the type of l, which is syntactically allowed, but it is not good for parsing programmatically (which we'll come back to later).
It is important to note that Python won't raise a TypeError if you pass a float into index, the reason for this is one of the main points in Python's design philosophy: "We're all consenting adults here", which means you are expected to be aware of what you can pass to a function and what you can't. If you really want to write code that throws TypeErrors you can use the isinstance function to check that the passed argument is of the proper type or a subclass of it like this:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
More on why you should rarely do this and what you should do instead is talked about in the next section and in the comments.
PEP 3107 does not only improve code readability but also has several fitting use cases which you can read about here.
Type annotation got a lot more attention in Python 3.5 with the introduction of PEP 484 which introduces a standard module typing for type hints.
These type hints came from the type checker mypy (GitHub), which is now PEP 484 compliant.
The typing module comes with a pretty comprehensive collection of type hints, including:
List,Tuple,Set,Dict- forlist,tuple,setanddictrespectively.Iterable- useful for generators.Any- when it could be anything.Union- when it could be anything within a specified set of types, as opposed toAny.Optional- when it might be None. Shorthand forUnion[T, None].TypeVar- used with generics.Callable- used primarily for functions, but could be used for other callables.
These are the most common type hints. A complete listing can be found in the documentation for the typing module.
Here is the old example using the annotation methods introduced in the typing module:
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
One powerful feature is the Callable which allows you to type annotate methods that take a function as an argument. For example:
from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
The above example could become more precise with the usage of TypeVar instead of Any, but this has been left as an exercise to the reader since I believe I've already filled my answer with too much information about the wonderful new features enabled by type hinting.
Previously when one documented Python code with for example Sphinx some of the above functionality could be obtained by writing docstrings formatted like this:
def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
As you can see, this takes a number of extra lines (the exact number depends on how explicit you want to be and how you format your docstring). But it should now be clear to you how PEP 3107 provides an alternative that is in many (all?) ways superior. This is especially true in combination with PEP 484 which, as we have seen, provides a standard module that defines a syntax for these type hints/annotations that can be used in such a way that it is unambiguous and precise yet flexible, making for a powerful combination.
In my personal opinion, this is one of the greatest features in Python ever. I can't wait for people to start harnessing the power of it. Sorry for the long answer, but this is what happens when I get excited.
An example of Python code which heavily uses type hinting can be found here.
Answer from erb on Stack OverflowThe other answers have done a good job at explaining duck typing and the simple answer by tzot:
Python does not have variables, like other languages where variables have a type and a value; it has names pointing to objects, which know their type.
However, one interesting thing has changed since 2010 (when the question was first asked), namely the implementation of PEP 3107 (implemented in Python 3). You can now actually specify the type of a parameter and the type of the return type of a function like this:
def pick(l: list, index: int) -> int:
return l[index]
Here we can see that pick takes 2 parameters, a list l and an integer index. It should also return an integer.
So here it is implied that l is a list of integers which we can see without much effort, but for more complex functions it can be a bit confusing as to what the list should contain. We also want the default value of index to be 0. To solve this you may choose to write pick like this instead:
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
Note that we now put in a string as the type of l, which is syntactically allowed, but it is not good for parsing programmatically (which we'll come back to later).
It is important to note that Python won't raise a TypeError if you pass a float into index, the reason for this is one of the main points in Python's design philosophy: "We're all consenting adults here", which means you are expected to be aware of what you can pass to a function and what you can't. If you really want to write code that throws TypeErrors you can use the isinstance function to check that the passed argument is of the proper type or a subclass of it like this:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
More on why you should rarely do this and what you should do instead is talked about in the next section and in the comments.
PEP 3107 does not only improve code readability but also has several fitting use cases which you can read about here.
Type annotation got a lot more attention in Python 3.5 with the introduction of PEP 484 which introduces a standard module typing for type hints.
These type hints came from the type checker mypy (GitHub), which is now PEP 484 compliant.
The typing module comes with a pretty comprehensive collection of type hints, including:
List,Tuple,Set,Dict- forlist,tuple,setanddictrespectively.Iterable- useful for generators.Any- when it could be anything.Union- when it could be anything within a specified set of types, as opposed toAny.Optional- when it might be None. Shorthand forUnion[T, None].TypeVar- used with generics.Callable- used primarily for functions, but could be used for other callables.
These are the most common type hints. A complete listing can be found in the documentation for the typing module.
Here is the old example using the annotation methods introduced in the typing module:
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
One powerful feature is the Callable which allows you to type annotate methods that take a function as an argument. For example:
from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
The above example could become more precise with the usage of TypeVar instead of Any, but this has been left as an exercise to the reader since I believe I've already filled my answer with too much information about the wonderful new features enabled by type hinting.
Previously when one documented Python code with for example Sphinx some of the above functionality could be obtained by writing docstrings formatted like this:
def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
As you can see, this takes a number of extra lines (the exact number depends on how explicit you want to be and how you format your docstring). But it should now be clear to you how PEP 3107 provides an alternative that is in many (all?) ways superior. This is especially true in combination with PEP 484 which, as we have seen, provides a standard module that defines a syntax for these type hints/annotations that can be used in such a way that it is unambiguous and precise yet flexible, making for a powerful combination.
In my personal opinion, this is one of the greatest features in Python ever. I can't wait for people to start harnessing the power of it. Sorry for the long answer, but this is what happens when I get excited.
An example of Python code which heavily uses type hinting can be found here.
Python is strongly typed because every object has a type, every object knows its type, it's impossible to accidentally or deliberately use an object of a type "as if" it was an object of a different type, and all elementary operations on the object are delegated to its type.
This has nothing to do with names. A name in Python doesn't "have a type": if and when a name's defined, the name refers to an object, and the object does have a type (but that doesn't in fact force a type on the name: a name is a name).
A name in Python can perfectly well refer to different objects at different times (as in most programming languages, though not all) -- and there is no constraint on the name such that, if it has once referred to an object of type X, it's then forevermore constrained to refer only to other objects of type X. Constraints on names are not part of the concept of "strong typing", though some enthusiasts of static typing (where names do get constrained, and in a static, AKA compile-time, fashion, too) do misuse the term this way.
Explicit parameter list in function documentation - Documentation - Discussions on Python.org
Why isn´t the parameter of the function of type list?
How could I use the list data type as a parameter in the Python function? - Stack Overflow
passing a list as function arguments
When I run the following code, I get an error the error: noneType object has no attribute 'append'
Why is this? I am handing in an empty list. How is this different from mylist = [], which works as expected.
(Damn, do I miss C already.)
def func(mylist, whatToPrint):
if len(mylist) == 1:
whatToPrint.append(list[0])
print(whatToPrint)
return 0
for i in range(len(mylist)):
tmp = mylist.copy()
tmp.pop(i)
func(tmp, whatToPrint.append(mylist[i]))
return 0
mylist = []
while True:
mylist.append(input())
if input("Last input? (Y/N)") == "Y":
break
func(mylist, [])
input("Close program with any key.")plants escape snatch angle bedroom liquid oatmeal library flag touch
This post was mass deleted and anonymized with Redact
In comments section of PyCharm's manual there's a nice hint from developer:
#: :type: dict of (str, C)
#: :type: list of str
It works for me pretty well. Now it makes me wonder what's the best way to document parametrized classes in Python :).
As pointed out in the PyCharm docs, a (legacy, pre-PEP-484) way of doing this is using square brackets:
list[Foo]: List of Foo elements
dict[Foo, Bar]: Dict from Foo to Bar
list of str, as suggested in the accepted answer, does not work as expected in PyCharm.
Starting with Python 3.5 and the implementation of PEP-484, you can also use type hints, which may be nicely supported by your IDE/editor. How this is easily done in PyCharm is explained here.
In essence, to declare a list return type using type-hinting (Python >=3.5), you may do something like this:
from typing import List
"""
Great foo function.
:rtype: list[str]
"""
def foo() -> List[str]:
return ['some string', 'some other string']
Here we declare (somewhat redundantly) that the function foo returns a list of strings, both in the type hint -> List[str] and in the docstring :rtype: list[str].
Other pre-declared types and more info can be found in the Python docs for typing.
You can do this using the splat operator:
some_func(*params)
This causes the function to receive each list item as a separate parameter. There's a description here: http://docs.python.org/tutorial/controlflow.html#unpacking-argument-lists
This has already been answered perfectly, but since I just came to this page and did not understand immediately I am just going to add a simple but complete example.
def some_func(a_char, a_float, a_something):
print a_char
params = ['a', 3.4, None]
some_func(*params)
>> a