Dive into Python.

Few chapter wise pickings from Dive into Python by Mark Pilgrim.

Objects in Python

  • Everything in Python is an object. Strings are objects. Lists are objects. Functions are objects. Even modules are objects. Almost everything has attributes and methods. All functions have a built-in attribute __doc__, which returns the doc string defined in the function’s source code.
  • Different programming languages define “object” in different ways. In some, it means that all objects must have attributes and methods; in others, it means that all objects are subclassable. In Python, the definition is looser; some objects have neither attributes nor methods, and not all objects are subclassable. But everything is an object in the sense that it can be assigned to a variable or passed as an argument to a function.
  •  

    Dictionaries in Python

  • Dictionaries are unordered.
  • Within a single dictionary, the values don’t all need to be the same type
  • del lets you delete individual items from a dictionary by key.
  • clear deletes all items from a dictionary.
  • The set of empty curly braces signifies a dictionary without any items.
  •  

    List in Python

  • list is an ordered set of elements enclosed in square brackets.
  • Negative List Indices li[-n] == li[len(li) – n].
  • Reading the list from left to right, the first slice index specifies the first element you want, and the second slice index specifies the first element you don’t want. The return value is everything in between.
  • li[:n] will always return the first n elements, and li[n:] will return the rest, regardless of the length of the list.
  • li[:] is shorthand for making a complete copy of a list.
  •  

    Index in Python

  • Index finds the first occurrence of a value in the list and returns the index.
  • If the value is not found in the list, Python raises an exception. This is notably different from most languages, which will return some invalid index. While this may seem annoying, it is a good thing, because it means your program will crash at the source of the problem, rather than later on when you try to use the invalid index.
  •  

    +, *, += with lists in Python

    >>> li = [‘a’, ‘b’, ‘mpilgrim’]
    >>> li = li + [‘example’, ‘new’]
    
    >>> li
    [‘a’, ‘b’, ‘mpilgrim’, ‘example’, ‘new’]
    >>> li += [‘two’]
    
    >>> li
    [‘a’, ‘b’, ‘mpilgrim’, ‘example’, ‘new’, ‘two’]
    >>> li = [1, 2] * 3
    
    >>> li
    [1, 2, 1, 2, 1, 2]
    

     

    + and extend() in Python

  • The + operator returns a new (concatenated) list as a value, whereas extend only alters an existing list. This means that extend is faster, especially for large lists.
  •  

    Tuple in Python

  • A tuple is an immutable list. A tuple can not be changed in any way once it is created.
  •  

    Classes in Python

  • Classes can (and should) have doc strings too, just like modules and functions
  • __init__ is called immediately after an instance of the class is created. It would be tempting but incorrect to call this the constructor of the class. It’s tempting, because it looks like a constructor (by convention, __init__ is the first method defined for the class), acts like one (it’s the first piece of code executed in a newly created instance of the class), and even sounds like one (“init” certainly suggests a constructor-ish nature). Incorrect, because the object has already been constructed by the time __init__ is called, and you already have a valid reference to the new instance of the class. But __init__ is the closest thing you’re going to get to a constructor in Python, and it fills much the same role.
  • The first argument of every class method, including __init__, is always a reference to the current instance of the class. By convention, this argument is always named self. In the __init__ method, self refers to the newly created object; in other class methods, it refers to the instance whose method was called. Although you need to specify self explicitly when defining the method, you do not specify it when calling the method; Python will add it for you automatically.
  • __init__ methods can take any number of arguments, and just like functions, the arguments can be defined with default values, making them optional to the caller. In this case, filename has a default value of None, which is the Python null value.
  •  

    When to use self and __init__

  • When defining your class methods, you must explicitly list self as the first argument for each method, including __init__. When you call a method of an ancestor class from within your class, you must include the self argument. But when you call your class method from outside, you do not specify anything for the self argument; you skip it entirely, and Python automatically adds the instance reference for you. I am aware that this is confusing at first; it’s not really inconsistent, but it may appear inconsistent because it relies on a distinction (between bound and unbound methods) that you don’t know about yet.
  • If you forget everything else, remember this one thing, because I promise it will trip you up: __init__ methods are optional, but when you define one, you must remember to explicitly call the ancestor’s __init__ method (if it defines one). This is more generally true: whenever a descendant wants to extend the behavior of the ancestor, the descendant method must explicitly call the ancestor method at the proper time, with the proper arguments.