Writing a Method in Class Book

As you saw in Chapter 7, Using Methods, there are two ways to call a method. One way is to access the method through the class, and the other is to use object-oriented syntax. These two calls are equivalent:

 >>>​​ ​​str.capitalize(​​'browning'​​)
 'Browning'
 >>>​​ ​​'browning'​​.capitalize()
 'Browning'

We’d like to be able to write similar code involving class Book. For example, we might want to be able to ask how many authors a Book has:

 >>>​​ ​​Book.num_authors(ruby_book)
 3
 >>>​​ ​​ruby_book.num_authors()
 3

To get this to work, we’ll define a method called num_authors inside Book. Here it is:

 class​ Book:
 """Information about a book."""
 
 def​ num_authors(self) -> int:
 """Return the number of authors of this book.
  """
 
 return​ len(self.authors)

Book method num_authors looks just like a function except that it has a parameter called self, which refers to a Book. Assuming this class is defined in the file book.py, we can import it, create a Book object, and call num_authors in two different ways:

 >>>​​ ​​import​​ ​​book
 >>>​​ ​​ruby_book​​ ​​=​​ ​​book.Book()
 >>>​​ ​​ruby_book.title​​ ​​=​​ ​​'Programming Ruby'
 >>>​​ ​​ruby_book.authors​​ ​​=​​ ​​[​​'Thomas'​​,​​ ​​'Fowler'​​,​​ ​​'Hunt'​​]
 >>>​​ ​​book.Book.num_authors(ruby_book)
 3
 >>>​​ ​​ruby_book.num_authors()
 3

Let’s take a close look at the first call on method num_authors:

 >>>​​ ​​book.Book.num_authors(ruby_book)

The book part says to look in the imported module. In that module is class Book. Inside Book is method num_authors. The argument to the call, ruby_book, is passed to parameter self.

Python treats the second call on num_authors exactly as it did the first; the first call is equivalent to this one:

 >>>​​ ​​ruby_book.num_authors()

The second version is much more common because it lists the object first; we think of that version as asking the book how many authors it has. Thinking of method calls this way can really help develop an object-oriented mentality.

In the ruby_book example, we assigned the title and list of authors after the Book object was created. That approach isn’t scalable; we don’t want to have to type those extra assignment statements every time we create a Book. Instead, we’ll write a method that does this for us as we create the Book. This is a special method and is called __init__. We’ll also include the publisher, ISBN, and price as parameters of __init__:

 from​ typing ​import​ List, Any
 
 class​ Book:
 """Information about a book, including title, list of authors,
  publisher, ISBN, and price.
  """
 
 def​ __init__(self, title: str, authors: List[str], publisher: str,
  isbn: str, price: float) -> None:
 """Create a new book entitled title, written by the people in authors,
  published by publisher, with ISBN isbn and costing price dollars.
 
  >>> python_book = Book( ​​
  'Practical Programming', ​​
  ['Campbell', 'Gries', 'Montojo'], ​​
  'Pragmatic Bookshelf', ​​
  '978-1-6805026-8-8', ​​
  25.0)
  >>> python_book.title
  'Practical Programming'
  >>> python_book.authors
  ['Campbell', 'Gries', 'Montojo']
  >>> python_book.publisher
  'Pragmatic Bookshelf'
  >>> python_book.ISBN
  '978-1-6805026-8-8'
  >>> python_book.price
  25.0
  """
 
  self.title = title
 # Copy the authors list in case the caller modifies that list later.
  self.authors = authors[:]
  self.publisher = publisher
  self.ISBN = isbn
  self.price = price
 
 def​ num_authors(self) -> int:
 """Return the number of authors of this book.
 
  >>> python_book = Book( ​​
  'Practical Programming', ​​
  ['Campbell', 'Gries', 'Montojo'], ​​
  'Pragmatic Bookshelf', ​​
  '978-1-6805026-8-8', ​​
  25.0)
  >>> python_book.num_authors()
  3
  """
 
 return​ len(self.authors)

Notice that we can include doctests for methods just as we do for functions. Notice also that we do not specify the type of the first parameter of a method, since its type is always the class in which it is defined.

This module contains a single (complicated) statement: the class definition. When Python executes this module, it creates a class object and assigns it to variable Book:

images/oop/book2.png

Method __init__ is called whenever a Book object is created. Its purpose is to initialize the new object; this method is sometimes called a constructor. Here are the steps that Python follows when creating an object:

  1. It creates an object at a particular memory address.
  2. It calls method __init__, passing in the new object into the parameter self.
  3. It produces that object’s memory address.

Let’s try it out in the shell:

 >>>​​ ​​import​​ ​​book
 >>>​​ ​​python_book​​ ​​=​​ ​​book.Book(
 ...​​ ​​'Practical Programming'​​,
 ...​​ ​​[​​'Campbell'​​,​​ ​​'Gries'​​,​​ ​​'Montojo'​​],
 ...​​ ​​'Pragmatic Bookshelf'​​,
 ...​​ ​​'978-1-6805026-8-8'​​,
 ...​​ ​​25.0)
 >>>​​ ​​python_book.title
 'Practical Programming'
 >>>​​ ​​python_book.authors
 ['Campbell', 'Gries', 'Montojo']
 >>>​​ ​​python_book.publisher
 'Pragmatic Bookshelf'
 >>>​​ ​​python_book.ISBN
 '978-1-6805026-8-8'
 >>>​​ ​​python_book.price
 25.0

The following image shows the memory model that results from this code:

images/oop/book6.png

Let’s trace method call python_book.num_authors(). (As a reminder, this is equivalent to Book.num_authors(python_book).) Python first finds the object that python_book refers to and calls its method num_authors. There are no explicit arguments, so Python only passes in the Book object that python_book refers to, assigning that object to the self parameter:

images/oop/book7.png

The return statement, return len(self.authors), is then executed. The expression, len(self.authors), is a function call. Python evaluates the argument, self.authors, by finding the object that self refers to and then, in that object, finds instance variable authors. This is a list, and the length of that list is the value that Python returns, as shown here:

images/oop/book8.png

With constructors, methods, and instance variables in hand, we can now create classes that look and work like those that come with Python itself.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.212.217