Sõnastik

Valige vasakul üks märksõnadest ...

Programming in PythonClasses

Lugemise aeg: ~15 min

Many Python functions use the usual function syntax, like len("hello"). However, many other functions are called using a different syntax where an object comes first:

"hello".capitalize()

These functions are called methods. For example, capitalize is a string method. To understand how methods work in the language, it's helpful to see what they look like at the point of definition.

Suppose you want to write a program which keeps track of the albums you own. Each album is associated with several data, like the name of the album, the year it came out, the number of tracks, etc. You could store all these data by assigning them to different variables, but that becomes untidy very quickly. For example, you will frequently want to pass an album to a function, and you don't want that function to require a long list of parameters just because the album has a lot of data associated with it.

What you want is to be able to treat each album as its own Python object, with all its associated data stored inside. In other words, you want an Album type. You can do that with the class keyword (this block won't return anything):

class Album(object):
    def __init__(self, name, artist, year, length):
        self.name = name
        self.artist = artist
        self.year = year
        self.length = length

    def numYearsAgo(self, currentYear):
        "Return the number of years since album was released"
        return currentYear - self.year

A function defined in the block indented below class Album(object): is called a method of the class Album. The \_\_init\_\_ method has a special role: Python calls it whenever Album is called as a function to create an instance of the class Album.

A = Album("Abbey Road", "The Beatles", 1969, "47:23")
A

The first parameter, customarily called self, refers to the object being created. The four lines in the init method above assign values to attributes which may be accessed later using the dot syntax, like A.name or A.artist.

Dot syntax is also used to access other methods like numYearsAgo.

A.numYearsAgo(2019)

The object appearing before the dot is implicitly supplied as the first argument to the method. Therefore, A.numYearsAgo(2019) at call time corresponds to numYearsAgo(A, 2019) at the point of definition. In fact, you can use the latter syntax if you want, because methods are also accessible using dot syntax on the class name: Album.numYearsAgo(A, 2019).

Exercise
Confirm that "hello".capitalize() does give the same value as str.capitalize("hello").

Exercise
In the expression "".join("hello"), the method join has arguments.

Solution. There are two arguments: the first is the empty string, and the second is "hello".

Exercise
Implement a class called Fraction which represents a ratio of two positive integers. You should reduce the fraction in your \_\_init\_\_ method. Your Fraction type should include a method called \_\_add\_\_ which adds two fractions and an \_\_eq\_\_ which checks whether two fractions are equal. (These methods will be automatically used by the addition and equality operators.)

from  math import gcd
# add code here

def test_Fraction():
    assert Fraction(1,2) + Fraction(1,3) == Fraction(5,6)
    assert Fraction(2,4) + Fraction(4,8) == Fraction(3,3)
    return "Test passed!"

test_Fraction()

Solution. We divide by the gcd in the init method, and we define the other two methods according to the rules of arithmetic:

from math import gcd

class Fraction(object):
    def __init__(self, num, denom):
        d = gcd(num, denom)
        self.num = num//d
        self.denom = denom//d
  
    def __add__(self, other):
        return Fraction(self.num * other.denom + self.denom * other.num,
                       self.denom * other.denom)
     
    def __eq__(self, other):
        return self.num == other.num and self.denom == other.denom

def test_Fraction():
    assert Fraction(1,2) + Fraction(1,3) == Fraction(5,6)
    assert Fraction(2,4) + Fraction(4,8) == Fraction(3,3)
    return "Test passed!"

test_Fraction()
Bruno
Bruno Bruno