mirror of
https://github.com/rasbt/python_reference.git
synced 2024-11-27 22:11:13 +00:00
function annotation
This commit is contained in:
parent
c1e9e1b9a6
commit
94577a54ce
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"metadata": {
|
||||
"name": "",
|
||||
"signature": "sha256:ef925e4eaf58c6daf50a495a77d38aa0b02a365dfc972bb5c0174332360b5adb"
|
||||
"signature": "sha256:35f23d6f2bbaa131a262533ed080684ed53fc0260430780f248c09af8c645759"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
|
@ -69,7 +69,8 @@
|
|||
"- [List slicing using indexes that are \"out of range](#out_of_range_slicing)\n",
|
||||
"- [Reusing global variable names and UnboundLocalErrors](#unboundlocalerror)\n",
|
||||
"- [Creating copies of mutable objects](#copy_mutable)\n",
|
||||
"- [Key differences between Python 2 and 3](#python_differences)"
|
||||
"- [Key differences between Python 2 and 3](#python_differences)\n",
|
||||
"- [Function annotations - What are those `->`'s in my Python code?](#function_annotation)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1807,6 +1808,7 @@
|
|||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='python_differences'></a>\n",
|
||||
"## Key differences between Python 2 and 3\n",
|
||||
"\n",
|
||||
"There are some good articles already that are summarizing the differences between Python 2 and 3, e.g., \n",
|
||||
|
@ -2043,6 +2045,15 @@
|
|||
"metadata": {},
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Handling exceptions\n",
|
||||
"\n",
|
||||
"Also the handling of excecptions has slightly changed in Python 3. Now, we have to use the `as` keyword!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
|
@ -2061,11 +2072,266 @@
|
|||
"... except NameError as err:\n",
|
||||
"... print(err, '--> our error msg')\n",
|
||||
"... \n",
|
||||
"name 'blabla' is not defined --> our error msg\n"
|
||||
"name 'blabla' is not defined --> our error msg"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### The `next()` function and `.next()` method\n",
|
||||
"\n",
|
||||
"Where you can use both function and method in Python 2.7.5, the `next()` function is all that remain in Python 3!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"# Python 2\n",
|
||||
">>> my_generator = (letter for letter in 'abcdefg')\n",
|
||||
">>> my_generator.next()\n",
|
||||
"'a'\n",
|
||||
">>> next(my_generator)\n",
|
||||
"'b'\n",
|
||||
"\n",
|
||||
"# Python 3\n",
|
||||
">>> my_generator = (letter for letter in 'abcdefg')\n",
|
||||
">>> next(my_generator)\n",
|
||||
"'a'\n",
|
||||
">>> my_generator.next()\n",
|
||||
"Traceback (most recent call last):\n",
|
||||
" File \"<stdin>\", line 1, in <module>\n",
|
||||
"AttributeError: 'generator' object has no attribute 'next'"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='function_annotation'></a>\n",
|
||||
"## Function annotations - What are those `->`'s in my Python code?\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Have you ever seen any Python code that used colons inside the parantheses of a function definition?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"def foo1(x: 'insert x here', y: 'insert x^2 here'):\n",
|
||||
" print('Hello, World')\n",
|
||||
" return"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 8
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"And what about the fancy arrow here?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"def foo2(x, y) -> 'Hi!':\n",
|
||||
" print('Hello, World')\n",
|
||||
" return"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 10
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Q: Is this valid Python syntax? \n",
|
||||
"A: Yes!\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"Q: So, what happens if I *just call* the function? \n",
|
||||
"A: Nothing!\n",
|
||||
" \n",
|
||||
"Here is the proof!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"foo1(1,2)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"Hello, World\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 9
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"foo2(1,2) "
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"Hello, World\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 11
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**So, those are function annotations ... ** \n",
|
||||
"- the colon for the function parameters \n",
|
||||
"- the arrow for the return value \n",
|
||||
"\n",
|
||||
"You probably will never make use of them (or at least very rarely). Usually, we write good function documentations below the function as a docstring - or at least this is how I would do it (okay this case is a little bit extreme, I have to admit):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"def is_palindrome(a):\n",
|
||||
" \"\"\"\n",
|
||||
" Case-and punctuation insensitive check if a string is a palindrom.\n",
|
||||
" \n",
|
||||
" Keyword arguments:\n",
|
||||
" a (str): The string to be checked if it is a palindrome.\n",
|
||||
" \n",
|
||||
" Returns `True` if input string is a palindrome, else False.\n",
|
||||
" \n",
|
||||
" \"\"\"\n",
|
||||
" stripped_str = [l for l in my_str.lower() if l.isalpha()]\n",
|
||||
" return stripped_str == stripped_str[::-1]\n",
|
||||
" "
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"However, function annotations can be useful to indicate that work is still in progress in some cases. But they are optional and I see them very very rarely.\n",
|
||||
"\n",
|
||||
"As it is stated in [PEP3107](http://legacy.python.org/dev/peps/pep-3107/#fundamentals-of-function-annotations):\n",
|
||||
"\n",
|
||||
"1. Function annotations, both for parameters and return values, are completely optional.\n",
|
||||
"\n",
|
||||
"2. Function annotations are nothing more than a way of associating arbitrary Python expressions with various parts of a function at compile-time.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The nice thing about function annotations is their `__annotations__` attribute, which is dictionary of all the parameters and/or the `return` value you annotated."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"foo1.__annotations__"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 17,
|
||||
"text": [
|
||||
"{'y': 'insert x^2 here', 'x': 'insert x here'}"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 17
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"foo2.__annotations__"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 18,
|
||||
"text": [
|
||||
"{'return': 'Hi!'}"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 18
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**When are they useful?**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Function annotations can be useful for a couple of things \n",
|
||||
"- Documentation in general\n",
|
||||
"- pre-condition testing\n",
|
||||
"- [type checking](http://legacy.python.org/dev/peps/pep-0362/#annotation-checker)\n",
|
||||
" \n",
|
||||
"..."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"metadata": {
|
||||
"name": "",
|
||||
"signature": "sha256:ce4b364bfb6414a1b40e25c6ed5320cec6bdbb11d75ce3e44632fe27504ace7e"
|
||||
"signature": "sha256:35f23d6f2bbaa131a262533ed080684ed53fc0260430780f248c09af8c645759"
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
|
@ -69,7 +69,8 @@
|
|||
"- [List slicing using indexes that are \"out of range](#out_of_range_slicing)\n",
|
||||
"- [Reusing global variable names and UnboundLocalErrors](#unboundlocalerror)\n",
|
||||
"- [Creating copies of mutable objects](#copy_mutable)\n",
|
||||
"- [Key differences between Python 2 and 3](#python_differences)"
|
||||
"- [Key differences between Python 2 and 3](#python_differences)\n",
|
||||
"- [Function annotations - What are those `->`'s in my Python code?](#function_annotation)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2109,6 +2110,228 @@
|
|||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<br>\n",
|
||||
"<br>\n",
|
||||
"<a name='function_annotation'></a>\n",
|
||||
"## Function annotations - What are those `->`'s in my Python code?\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Have you ever seen any Python code that used colons inside the parantheses of a function definition?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"def foo1(x: 'insert x here', y: 'insert x^2 here'):\n",
|
||||
" print('Hello, World')\n",
|
||||
" return"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 8
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"And what about the fancy arrow here?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"def foo2(x, y) -> 'Hi!':\n",
|
||||
" print('Hello, World')\n",
|
||||
" return"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"prompt_number": 10
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Q: Is this valid Python syntax? \n",
|
||||
"A: Yes!\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"Q: So, what happens if I *just call* the function? \n",
|
||||
"A: Nothing!\n",
|
||||
" \n",
|
||||
"Here is the proof!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"foo1(1,2)"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"Hello, World\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 9
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"foo2(1,2) "
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"stream": "stdout",
|
||||
"text": [
|
||||
"Hello, World\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 11
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**So, those are function annotations ... ** \n",
|
||||
"- the colon for the function parameters \n",
|
||||
"- the arrow for the return value \n",
|
||||
"\n",
|
||||
"You probably will never make use of them (or at least very rarely). Usually, we write good function documentations below the function as a docstring - or at least this is how I would do it (okay this case is a little bit extreme, I have to admit):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"def is_palindrome(a):\n",
|
||||
" \"\"\"\n",
|
||||
" Case-and punctuation insensitive check if a string is a palindrom.\n",
|
||||
" \n",
|
||||
" Keyword arguments:\n",
|
||||
" a (str): The string to be checked if it is a palindrome.\n",
|
||||
" \n",
|
||||
" Returns `True` if input string is a palindrome, else False.\n",
|
||||
" \n",
|
||||
" \"\"\"\n",
|
||||
" stripped_str = [l for l in my_str.lower() if l.isalpha()]\n",
|
||||
" return stripped_str == stripped_str[::-1]\n",
|
||||
" "
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"However, function annotations can be useful to indicate that work is still in progress in some cases. But they are optional and I see them very very rarely.\n",
|
||||
"\n",
|
||||
"As it is stated in [PEP3107](http://legacy.python.org/dev/peps/pep-3107/#fundamentals-of-function-annotations):\n",
|
||||
"\n",
|
||||
"1. Function annotations, both for parameters and return values, are completely optional.\n",
|
||||
"\n",
|
||||
"2. Function annotations are nothing more than a way of associating arbitrary Python expressions with various parts of a function at compile-time.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The nice thing about function annotations is their `__annotations__` attribute, which is dictionary of all the parameters and/or the `return` value you annotated."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"foo1.__annotations__"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 17,
|
||||
"text": [
|
||||
"{'y': 'insert x^2 here', 'x': 'insert x here'}"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 17
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"foo2.__annotations__"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"metadata": {},
|
||||
"output_type": "pyout",
|
||||
"prompt_number": 18,
|
||||
"text": [
|
||||
"{'return': 'Hi!'}"
|
||||
]
|
||||
}
|
||||
],
|
||||
"prompt_number": 18
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**When are they useful?**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Function annotations can be useful for a couple of things \n",
|
||||
"- Documentation in general\n",
|
||||
"- pre-condition testing\n",
|
||||
"- [type checking](http://legacy.python.org/dev/peps/pep-0362/#annotation-checker)\n",
|
||||
" \n",
|
||||
"..."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
|
|
Loading…
Reference in New Issue
Block a user