|
1 | 1 | { |
2 | 2 | "metadata": { |
3 | 3 | "name": "", |
4 | | - "signature": "sha256:ef925e4eaf58c6daf50a495a77d38aa0b02a365dfc972bb5c0174332360b5adb" |
| 4 | + "signature": "sha256:35f23d6f2bbaa131a262533ed080684ed53fc0260430780f248c09af8c645759" |
5 | 5 | }, |
6 | 6 | "nbformat": 3, |
7 | 7 | "nbformat_minor": 0, |
|
69 | 69 | "- [List slicing using indexes that are \"out of range](#out_of_range_slicing)\n", |
70 | 70 | "- [Reusing global variable names and UnboundLocalErrors](#unboundlocalerror)\n", |
71 | 71 | "- [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)" |
73 | 74 | ] |
74 | 75 | }, |
75 | 76 | { |
|
1807 | 1808 | "source": [ |
1808 | 1809 | "<br>\n", |
1809 | 1810 | "<br>\n", |
| 1811 | + "<a name='python_differences'></a>\n", |
1810 | 1812 | "## Key differences between Python 2 and 3\n", |
1811 | 1813 | "\n", |
1812 | 1814 | "There are some good articles already that are summarizing the differences between Python 2 and 3, e.g., \n", |
|
2043 | 2045 | "metadata": {}, |
2044 | 2046 | "outputs": [] |
2045 | 2047 | }, |
| 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 | + }, |
2046 | 2057 | { |
2047 | 2058 | "cell_type": "code", |
2048 | 2059 | "collapsed": false, |
|
2061 | 2072 | "... except NameError as err:\n", |
2062 | 2073 | "... print(err, '--> our error msg')\n", |
2063 | 2074 | "... \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 | + } |
2065 | 2194 | ], |
| 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": [], |
2066 | 2332 | "language": "python", |
2067 | 2333 | "metadata": {}, |
2068 | 2334 | "outputs": [] |
|
0 commit comments