more.asciidoc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. [[more]]
  2. == More
  3. So far we have covered a majority of the various aspects of Python that you will use. In this
  4. chapter, we will cover some more aspects that will make our knowledge of Python more well-rounded.
  5. === Passing tuples around
  6. Ever wished you could return two different values from a function? You can. All you have to do is
  7. use a tuple.
  8. --------------------------------------------------
  9. >>> def get_error_details():
  10. ... return (2, 'details')
  11. ...
  12. >>> errnum, errstr = get_error_details()
  13. >>> errnum
  14. 2
  15. >>> errstr
  16. 'details'
  17. --------------------------------------------------
  18. Notice that the usage of `a, b = <some expression>` interprets the result of the expression as a
  19. tuple with two values.
  20. This also means the fastest way to swap two variables in Python is:
  21. --------------------------------------------------
  22. >>> a = 5; b = 8
  23. >>> a, b
  24. (5, 8)
  25. >>> a, b = b, a
  26. >>> a, b
  27. (8, 5)
  28. --------------------------------------------------
  29. === Special Methods
  30. There are certain methods such as the `__init__` and `__del__` methods which have special
  31. significance in classes.
  32. Special methods are used to mimic certain behaviors of built-in types. For example, if you want to
  33. use the `x[key]` indexing operation for your class (just like you use it for lists and tuples),
  34. then all you have to do is implement the `__getitem__()` method and your job is done. If you think
  35. about it, this is what Python does for the `list` class itself!
  36. Some useful special methods are listed in the following table. If you
  37. want to know about all the special methods,
  38. http://docs.python.org/2/reference/datamodel.html#special-method-names[see the manual].
  39. `__init__(self, ...)` ::
  40. This method is called just before the newly created object is returned for usage.
  41. `__del__(self)` ::
  42. Called just before the object is destroyed (which has unpredictable timing, so avoid using this)
  43. `__str__(self)` ::
  44. Called when we use the `print` statement or when `str()` is used.
  45. `__lt__(self, other)` ::
  46. Called when the _less than_ operator (&lt;) is used. Similarly, there are special methods for all
  47. the operators (+, >, etc.)
  48. `__getitem__(self, key)` ::
  49. Called when `x[key]` indexing operation is used.
  50. `__len__(self)` ::
  51. Called when the built-in `len()` function is used for the sequence object.
  52. === Single Statement Blocks
  53. We have seen that each block of statements is set apart from the rest by its own indentation
  54. level. Well, there is one caveat. If your block of statements contains only one single statement,
  55. then you can specify it on the same line of, say, a conditional statement or looping statement. The
  56. following example should make this clear:
  57. --------------------------------------------------
  58. >>> flag = True
  59. >>> if flag: print 'Yes'
  60. ...
  61. Yes
  62. --------------------------------------------------
  63. Notice that the single statement is used in-place and not as a separate block. Although, you can
  64. use this for making your program _smaller_, I strongly recommend avoiding this short-cut method,
  65. except for error checking, mainly because it will be much easier to add an extra statement if you
  66. are using proper indentation.
  67. === Lambda Forms
  68. A `lambda` statement is used to create new function objects. Essentially, the `lambda` takes a
  69. parameter followed by a single expression only which becomes the body of the function and the value
  70. of this expression is returned by the new function.
  71. Example (save as `more_lambda.py`):
  72. [source,python]
  73. --------------------------------------------------
  74. include::programs/more_lambda.py[]
  75. --------------------------------------------------
  76. Output:
  77. --------------------------------------------------
  78. include::programs/more_lambda.txt[]
  79. --------------------------------------------------
  80. .How It Works
  81. Notice that the `sort` method of a `list` can take a `key` parameter which determines how the list
  82. is sorted (usually we know only about ascending or descending order). In our case, we want to do a
  83. custom sort, and for that we need to write a function but instead of writing a separate `def` block
  84. for a function that will get used in only this one place, we use a lambda expression to create a
  85. new function.
  86. [[list_comprehension]]
  87. === List Comprehension
  88. List comprehensions are used to derive a new list from an existing list. Suppose you have a list of
  89. numbers and you want to get a corresponding list with all the numbers multiplied by 2 only when the
  90. number itself is greater than 2. List comprehensions are ideal for such situations.
  91. Example (save as `more_list_comprehension.py`):
  92. [source,python]
  93. --------------------------------------------------
  94. include::programs/more_list_comprehension.py[]
  95. --------------------------------------------------
  96. Output:
  97. --------------------------------------------------
  98. include::programs/more_list_comprehension.txt[]
  99. --------------------------------------------------
  100. .How It Works
  101. Here, we derive a new list by specifying the manipulation to be done (++2*i++) when some condition
  102. is satisfied (`if i > 2`). Note that the original list remains unmodified.
  103. The advantage of using list comprehensions is that it reduces the amount of boilerplate code
  104. required when we use loops to process each element of a list and store it in a new list.
  105. === Receiving Tuples and Dictionaries in Functions
  106. There is a special way of receiving parameters to a function as a tuple or a dictionary using the
  107. ++*++ or ++**++ prefix respectively. This is useful when taking variable number of arguments in the
  108. function.
  109. --------------------------------------------------
  110. >>> def powersum(power, *args):
  111. ... '''Return the sum of each argument raised to the specified power.'''
  112. ... total = 0
  113. ... for i in args:
  114. ... total += pow(i, power)
  115. ... return total
  116. ...
  117. >>> powersum(2, 3, 4)
  118. 25
  119. >>> powersum(2, 10)
  120. 100
  121. --------------------------------------------------
  122. Because we have a ++*++ prefix on the `args` variable, all extra arguments passed to the function are
  123. stored in `args` as a tuple. If a ++**++ prefix had been used instead, the extra parameters would be
  124. considered to be key/value pairs of a dictionary.
  125. === The assert statement
  126. The `assert` statement is used to assert that something is true. For example, if you are very sure
  127. that you will have at least one element in a list you are using and want to check this, and raise
  128. an error if it is not true, then `assert` statement is ideal in this situation. When the assert
  129. statement fails, an `AssertionError` is raised.
  130. --------------------------------------------------
  131. >>> mylist = ['item']
  132. >>> assert len(mylist) >= 1
  133. >>> mylist.pop()
  134. 'item'
  135. >>> assert len(mylist) >= 1
  136. Traceback (most recent call last):
  137. File "<stdin>", line 1, in <module>
  138. AssertionError
  139. --------------------------------------------------
  140. The `assert` statement should be used judiciously. Most of the time, it is better to catch
  141. exceptions, either handle the problem or display an error message to the user and then quit.
  142. [[decorator]]
  143. === Decorators
  144. Decorators are a shortcut to applying wrapper functions. This is helpful to "wrap" functionality
  145. with the same code over and over again. For example, I created a `retry` decorator for myself that
  146. I can just apply to any function and if any exception is thrown during a run, it is retried again,
  147. till a maximum of 5 times and with a delay between each retry. This is especially useful for
  148. situations where you are trying to make a network call to a remote computer:
  149. [source,python]
  150. --------------------------------------------------
  151. include::programs/more_decorator.py[]
  152. --------------------------------------------------
  153. Output:
  154. --------------------------------------------------
  155. include::programs/more_decorator.txt[]
  156. --------------------------------------------------
  157. .How It Works
  158. See:
  159. - http://www.ibm.com/developerworks/linux/library/l-cpdecor.html
  160. - http://toumorokoshi.github.io/dry-principles-through-python-decorators.html
  161. [[two_vs_three]]
  162. === Differences between Python 2 and Python 3
  163. See:
  164. - http://pythonhosted.org/six/["Six" library]
  165. - http://lucumr.pocoo.org/2013/5/21/porting-to-python-3-redux/[Porting to Python 3 Redux by Armin]
  166. - http://pydanny.com/experiences-with-django-python3.html[Python 3 experience by PyDanny]
  167. - https://docs.djangoproject.com/en/dev/topics/python3/[Official Django Guide to Porting to Python 3]
  168. - http://www.reddit.com/r/Python/comments/22ovb3/what_are_the_advantages_to_python_3x/[Discussion on What are the advantages to python 3.x?]
  169. === Summary
  170. We have covered some more features of Python in this chapter and yet we haven't covered all the
  171. features of Python. However, at this stage, we have covered most of what you are ever going to use
  172. in practice. This is sufficient for you to get started with whatever programs you are going to
  173. create.
  174. Next, we will discuss how to explore Python further.