Skip to content

Commit 94577a5

Browse files
committed
function annotation
1 parent c1e9e1b commit 94577a5

2 files changed

Lines changed: 494 additions & 5 deletions

File tree

.ipynb_checkpoints/not_so_obvious_python_stuff-checkpoint.ipynb

Lines changed: 269 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"metadata": {
33
"name": "",
4-
"signature": "sha256:ef925e4eaf58c6daf50a495a77d38aa0b02a365dfc972bb5c0174332360b5adb"
4+
"signature": "sha256:35f23d6f2bbaa131a262533ed080684ed53fc0260430780f248c09af8c645759"
55
},
66
"nbformat": 3,
77
"nbformat_minor": 0,
@@ -69,7 +69,8 @@
6969
"- [List slicing using indexes that are \"out of range](#out_of_range_slicing)\n",
7070
"- [Reusing global variable names and UnboundLocalErrors](#unboundlocalerror)\n",
7171
"- [Creating copies of mutable objects](#copy_mutable)\n",
72-
"- [Key differences between Python 2 and 3](#python_differences)"
72+
"- [Key differences between Python 2 and 3](#python_differences)\n",
73+
"- [Function annotations - What are those `->`'s in my Python code?](#function_annotation)"
7374
]
7475
},
7576
{
@@ -1807,6 +1808,7 @@
18071808
"source": [
18081809
"<br>\n",
18091810
"<br>\n",
1811+
"<a name='python_differences'></a>\n",
18101812
"## Key differences between Python 2 and 3\n",
18111813
"\n",
18121814
"There are some good articles already that are summarizing the differences between Python 2 and 3, e.g., \n",
@@ -2043,6 +2045,15 @@
20432045
"metadata": {},
20442046
"outputs": []
20452047
},
2048+
{
2049+
"cell_type": "markdown",
2050+
"metadata": {},
2051+
"source": [
2052+
"#### Handling exceptions\n",
2053+
"\n",
2054+
"Also the handling of excecptions has slightly changed in Python 3. Now, we have to use the `as` keyword!"
2055+
]
2056+
},
20462057
{
20472058
"cell_type": "code",
20482059
"collapsed": false,
@@ -2061,8 +2072,263 @@
20612072
"... except NameError as err:\n",
20622073
"... print(err, '--> our error msg')\n",
20632074
"... \n",
2064-
"name 'blabla' is not defined --> our error msg\n"
2075+
"name 'blabla' is not defined --> our error msg"
2076+
],
2077+
"language": "python",
2078+
"metadata": {},
2079+
"outputs": []
2080+
},
2081+
{
2082+
"cell_type": "markdown",
2083+
"metadata": {},
2084+
"source": [
2085+
"#### The `next()` function and `.next()` method\n",
2086+
"\n",
2087+
"Where you can use both function and method in Python 2.7.5, the `next()` function is all that remain in Python 3!"
2088+
]
2089+
},
2090+
{
2091+
"cell_type": "code",
2092+
"collapsed": false,
2093+
"input": [
2094+
"# Python 2\n",
2095+
">>> my_generator = (letter for letter in 'abcdefg')\n",
2096+
">>> my_generator.next()\n",
2097+
"'a'\n",
2098+
">>> next(my_generator)\n",
2099+
"'b'\n",
2100+
"\n",
2101+
"# Python 3\n",
2102+
">>> my_generator = (letter for letter in 'abcdefg')\n",
2103+
">>> next(my_generator)\n",
2104+
"'a'\n",
2105+
">>> my_generator.next()\n",
2106+
"Traceback (most recent call last):\n",
2107+
" File \"<stdin>\", line 1, in <module>\n",
2108+
"AttributeError: 'generator' object has no attribute 'next'"
2109+
],
2110+
"language": "python",
2111+
"metadata": {},
2112+
"outputs": []
2113+
},
2114+
{
2115+
"cell_type": "markdown",
2116+
"metadata": {},
2117+
"source": [
2118+
"<br>\n",
2119+
"<br>\n",
2120+
"<a name='function_annotation'></a>\n",
2121+
"## Function annotations - What are those `->`'s in my Python code?\n"
2122+
]
2123+
},
2124+
{
2125+
"cell_type": "markdown",
2126+
"metadata": {},
2127+
"source": [
2128+
"Have you ever seen any Python code that used colons inside the parantheses of a function definition?"
2129+
]
2130+
},
2131+
{
2132+
"cell_type": "code",
2133+
"collapsed": false,
2134+
"input": [
2135+
"def foo1(x: 'insert x here', y: 'insert x^2 here'):\n",
2136+
" print('Hello, World')\n",
2137+
" return"
2138+
],
2139+
"language": "python",
2140+
"metadata": {},
2141+
"outputs": [],
2142+
"prompt_number": 8
2143+
},
2144+
{
2145+
"cell_type": "markdown",
2146+
"metadata": {},
2147+
"source": [
2148+
"And what about the fancy arrow here?"
2149+
]
2150+
},
2151+
{
2152+
"cell_type": "code",
2153+
"collapsed": false,
2154+
"input": [
2155+
"def foo2(x, y) -> 'Hi!':\n",
2156+
" print('Hello, World')\n",
2157+
" return"
2158+
],
2159+
"language": "python",
2160+
"metadata": {},
2161+
"outputs": [],
2162+
"prompt_number": 10
2163+
},
2164+
{
2165+
"cell_type": "markdown",
2166+
"metadata": {},
2167+
"source": [
2168+
"Q: Is this valid Python syntax? \n",
2169+
"A: Yes!\n",
2170+
" \n",
2171+
" \n",
2172+
"Q: So, what happens if I *just call* the function? \n",
2173+
"A: Nothing!\n",
2174+
" \n",
2175+
"Here is the proof!"
2176+
]
2177+
},
2178+
{
2179+
"cell_type": "code",
2180+
"collapsed": false,
2181+
"input": [
2182+
"foo1(1,2)"
2183+
],
2184+
"language": "python",
2185+
"metadata": {},
2186+
"outputs": [
2187+
{
2188+
"output_type": "stream",
2189+
"stream": "stdout",
2190+
"text": [
2191+
"Hello, World\n"
2192+
]
2193+
}
20652194
],
2195+
"prompt_number": 9
2196+
},
2197+
{
2198+
"cell_type": "code",
2199+
"collapsed": false,
2200+
"input": [
2201+
"foo2(1,2) "
2202+
],
2203+
"language": "python",
2204+
"metadata": {},
2205+
"outputs": [
2206+
{
2207+
"output_type": "stream",
2208+
"stream": "stdout",
2209+
"text": [
2210+
"Hello, World\n"
2211+
]
2212+
}
2213+
],
2214+
"prompt_number": 11
2215+
},
2216+
{
2217+
"cell_type": "markdown",
2218+
"metadata": {},
2219+
"source": [
2220+
"**So, those are function annotations ... ** \n",
2221+
"- the colon for the function parameters \n",
2222+
"- the arrow for the return value \n",
2223+
"\n",
2224+
"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):"
2225+
]
2226+
},
2227+
{
2228+
"cell_type": "code",
2229+
"collapsed": false,
2230+
"input": [
2231+
"def is_palindrome(a):\n",
2232+
" \"\"\"\n",
2233+
" Case-and punctuation insensitive check if a string is a palindrom.\n",
2234+
" \n",
2235+
" Keyword arguments:\n",
2236+
" a (str): The string to be checked if it is a palindrome.\n",
2237+
" \n",
2238+
" Returns `True` if input string is a palindrome, else False.\n",
2239+
" \n",
2240+
" \"\"\"\n",
2241+
" stripped_str = [l for l in my_str.lower() if l.isalpha()]\n",
2242+
" return stripped_str == stripped_str[::-1]\n",
2243+
" "
2244+
],
2245+
"language": "python",
2246+
"metadata": {},
2247+
"outputs": []
2248+
},
2249+
{
2250+
"cell_type": "markdown",
2251+
"metadata": {},
2252+
"source": [
2253+
"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",
2254+
"\n",
2255+
"As it is stated in [PEP3107](http://legacy.python.org/dev/peps/pep-3107/#fundamentals-of-function-annotations):\n",
2256+
"\n",
2257+
"1. Function annotations, both for parameters and return values, are completely optional.\n",
2258+
"\n",
2259+
"2. Function annotations are nothing more than a way of associating arbitrary Python expressions with various parts of a function at compile-time.\n"
2260+
]
2261+
},
2262+
{
2263+
"cell_type": "markdown",
2264+
"metadata": {},
2265+
"source": [
2266+
"The nice thing about function annotations is their `__annotations__` attribute, which is dictionary of all the parameters and/or the `return` value you annotated."
2267+
]
2268+
},
2269+
{
2270+
"cell_type": "code",
2271+
"collapsed": false,
2272+
"input": [
2273+
"foo1.__annotations__"
2274+
],
2275+
"language": "python",
2276+
"metadata": {},
2277+
"outputs": [
2278+
{
2279+
"metadata": {},
2280+
"output_type": "pyout",
2281+
"prompt_number": 17,
2282+
"text": [
2283+
"{'y': 'insert x^2 here', 'x': 'insert x here'}"
2284+
]
2285+
}
2286+
],
2287+
"prompt_number": 17
2288+
},
2289+
{
2290+
"cell_type": "code",
2291+
"collapsed": false,
2292+
"input": [
2293+
"foo2.__annotations__"
2294+
],
2295+
"language": "python",
2296+
"metadata": {},
2297+
"outputs": [
2298+
{
2299+
"metadata": {},
2300+
"output_type": "pyout",
2301+
"prompt_number": 18,
2302+
"text": [
2303+
"{'return': 'Hi!'}"
2304+
]
2305+
}
2306+
],
2307+
"prompt_number": 18
2308+
},
2309+
{
2310+
"cell_type": "markdown",
2311+
"metadata": {},
2312+
"source": [
2313+
"**When are they useful?**"
2314+
]
2315+
},
2316+
{
2317+
"cell_type": "markdown",
2318+
"metadata": {},
2319+
"source": [
2320+
"Function annotations can be useful for a couple of things \n",
2321+
"- Documentation in general\n",
2322+
"- pre-condition testing\n",
2323+
"- [type checking](http://legacy.python.org/dev/peps/pep-0362/#annotation-checker)\n",
2324+
" \n",
2325+
"..."
2326+
]
2327+
},
2328+
{
2329+
"cell_type": "code",
2330+
"collapsed": false,
2331+
"input": [],
20662332
"language": "python",
20672333
"metadata": {},
20682334
"outputs": []

0 commit comments

Comments
 (0)