Lecture 1



CSC 401 – Objects and classes - introYosef MendelsohnPython objectsAnything that contains a value in Python is an "object".A Python object has three properties:An identity (don't confuse with 'identifier')A typeA valueThe object’s identity is a unique integer ID assigned to the object. This ID is the object’s memory address. This identity is accessible using the built-in function: id().>>> a = 7>>> id(a)505493992>>> lst = [3, 4, 5]>>> id(lst)31078800>>> id(lst[0])505493928>>> id(lst[1])505493944>>> id(lst[2])505493960As you know, every value in Python has a data type. The type of an object is accessible using the built-in function: type()>>> type(lst)<class 'list'>>>> type(a)<class 'int'>>>> type('hello')<class 'str'>>>> type(None)<class 'NoneType'>The value is the data that the object represents.>>> a7>>> lst[3, 4, 5]ConstructorsWe are about to enter the world of "object oriented programming". As we get ready to create our own data types (called "classes"), it is useful to discuss / review an alternative way to create new instances of the various data types with which we are already familiar such as lists, integers, sets, and dictionaries.We are all familiar with creating a list by using the square brackets:>>> my_lst = []However, we can also generate a new list by invoking a function called: list()The fact that the name of the function is identical to the name of the data type is not a concidence. We will discuss this further, shortly.So we can rewrite the earlier line of code as:>>> my_lst = list()This function is an example of a special group of functions known as constructors. There are similar constructor functions for:Integers: int()num1 = int() #new int object with a default value #this default value depends on the type# for integers, the default value is 0 num2 = int(3) #new int object with a value of 3Strings: str()name = str('Jim')Sets: set()years = set( (1971,1972,1973) )Dictionaries: dict()etcAs you can see, constructor functions (typically just called 'constructors') can typically be passed certain parameters. These parameters are usually used to assign default values to the new object that is being created. Aside: Variable vs ObjectWe are very familiar with the idea of a variable. In many programming languages, there is a clear distinction between 'variables' and their more complex cousins, 'objects'. However, in Python, everything – even the most "simple" variable, is still considered to be an object. Therefore, you will frequently hear the terms used interchangably. Moving forward, though, we should start using the term "object" more frequently, since it is a more accurate description of the item we are working with. When a constructor is invoked with zero parameters, the function assigns a default value to its variable. For example the constructor for the integer constructor, int(), assigns a 0.>>> x1 = int(43) >>> x143>>> x2 = int() #default constructor>>> x20>>> lst1 = list([1, 2, 3])>>> lst1[1, 2, 3]>>> lst2 = list()>>> lst2[]Note: A constructor that takes zero parameters is given a special name, the"default constructor"For example, if we were to create a new string as follows:s = str()then we can say that we invoked the default constructor of the string class.TerminologyFunction vs MethodNote: A function and a method are essentially the same thing. However, we typically use the term method when we are referring to a method associated with a particular class. For example: print() is a function. However, print() compare the function with another familiar function: upper(). Note that is upper()is meant to work with a string:s = 'Hello, how are you's.upper() #returns 's' in upper caseTherefore, upper() should probably be called a ‘method’ as opposed to a ‘function’.Compare with the function len() which can be invoked on its own:len([3,4,5]) This means that len() is a function. Imagine you have the following objects: name = 'Bob Smith'nums = [2,3,4]len(lst) len() is a functionnums.append(5) append() is a method of the class 'list'nums.remove(2) remove() is a method of the class 'list'print(nums) print() is a functionfin = open('example.txt') open() is a functions.isupper() isupper() is a method of the class 'string'Every class is essentially a list of:class attributes class functions (which we call "methods")AttributesEach object of a type (i.e. each instance of a type) inherits the class attributes, that is, the variables and methods of that class. At the moment you don't understand what we mean by 'variables of a class', however, we will cover this shortly. However, you will be able to understand what we mean by 'methods of a class' as shown below.Suppose you have the following statement:s = 'hello, how are you?'Because s is an object of type string, it inherits all attributes defined in in the string class, Methods defined in class str include: upper, format, find, replace, and many others. You are already fairly familiar with some of these. In other words, because 's' is an object of the string class (str), it inherits all of the methods from that class and can therefore do things like:s.upper()s.format(…)s.find(…)etc Let's look at an object of type list: s = [3,4,5] #s is now an object of class listBecause s is now an object of type 'list', s now inherits all attributes available in the class list. So the object ‘s’ can now invoke list methods:s.append(-4)s.pop()s.clear()etcAs you know, the attributes for any class type can be seen using the help function. For example, let’s view the help for the ‘int’ class:>>> help(int)Help on class int in module builtins:class int(object) | int(x[, base]) -> integer | | Convert a string or number to an integer, if possible. A floating | point argument will be truncated towards zero (this does not include a | string representation of a floating point number!) When converting a | string, use the optional base. It is an error to supply a base when | converting a non-string. | | Methods defined here: | | __abs__(...) | x.__abs__() <==> abs(x) | | __add__(...) | x.__add__(y) <==> x+y | | __and__(...) | x.__and__(y) <==> x&yEtc.OperatorsIn learning about classes and object-oriented programming, we also need to reopen our discussion of operators (e.g. the '+' operator). There are some subtleties that we didn’t consider before but that will be important – especially so when we start writing our own classes.Methods with names such as __<name>__ (that is, two underscores, an identifier, and two more underscores) are special hooks that are called automatically when Python evaluates certain operators. This may not make a lot of sense just yet, but keep reading….These “double underscore” methods are pretty famous in Python. They even have their own nickname: “dunder methods”. They have another nickname as well: “magic methods”. If you recall, I once told you that some operators such as '+' are in fact functions. For example, the operator '+' is evaluated by Python behind the scenes by invoking a dunder method called: __add__()If an object inherits an __add__ method (that is, if this method exists inside the class), that method will be automatically invoked when the invoking object appears on the left side of a + expression.Okay, so that's pretty confusing. It will help to look at an example: Example:x = 3 #x is an object of type ‘int’y = x+5 For the second line, , behind the scenes, Python evaluates the x+5 statement as:x.__add__(5)So behind the scenes, y = x+5is invisibly converted by Python into:y = x.__add__(5)Restated: The moment an object of type int appears, and is followed by a '+' symbol, Python will search the 'int' class for a method called __add__ () and will invoke it.Every single object of type ‘int’ that we create, because of the fact that it is an 'int' gets to use the __add__()method.In object-oriented (OO) parlance, we say that every object of type int inherits the __add__() method.See below for some examples:>>> x = 3>>> y = 4>>> x + y #Python will search the class ‘int’ #for a method called __add__#It will invoke the method as: x.__add__(y) 7#In fact, let's try invoking it that way directly:>>> x.__add__(y) 7#as you can see, does the same thing If you type help(int), you will see among the list of methods the following: __add__(self, value) Return self+value.You will also see methods for other familiar operators including:__sub__() subtraction e.g. n1__sub__(n2)__mul__() multiply e.g. n1__mul__(n2)__pow__() ** (ie exponent) e.g. n1__pow__(n2)etcLet's try another one. In this example, suppose that 'x' is an object of ype 'int'. In the following method, we are asking Python to convert the integer value of x (which is 3) to a string. >>> str(x)'3'How did it do this? Answer: It involved one of these '__' (‘dunder’ or ‘magic’) methods. In this case, Python will search the 'int' class for a method called __str__ and will automatically invoke it. In fact, if you typed: x.__str__() you'd get the same result:>>> x.__str__()'3'More examples:>>> lst = list([2, 3, 4, 5, 6])>>> len(lst) #will search class 'list for __len__ 5>>> lst.__len__() #this will give the same result5>>> lst.__add__([4,5])[2, 3, 4, 5, 6, 4, 5]>>> lst[2, 3, 4, 5, 6]Exercises:Define three integers and use the __x__ notation to do absolute value, and the < (less than) operations. The magic/dunder methods corresponding to these are called: abs, and lt respectively. Note: If you want to look at the help for mathematical operators functions in the API, most are defined in the module 'operator'.Define three lists and use the __x__ notation for the operators contains, len, and getitem.Calling methodsAs you are well aware, when invoking methods of some object, it is common to write:obj.method(p1, p2, …)Where:obj is the objectmethod is the methodp1, p2, … etc. are the parameters.For example: s = "hello"s.upper()Or perhaps:s.index('e')Or suppose we have a list as follows:>>> lst = []we invoke methods on that object like so: >>> lst.append(4)>>> lst.append(-3)>>> lst[4, -3]In other words, we are quite familiar with the syntax: lst.append(4)However….It is very important that we understand that a method call in this (familiar) form:obj.method(param1, param2, etc)is transformed behind the scenes into the following form:className.method(obj, param1, param2, etc …)where className is the class associated with the object.For example, to append the number 4 to a list called lstNumbers:We will almost always write: lstNumbers.append(4)However behind the scenes, this command is always transformed into:list.append(lstNumbers, 4) In this example then, 'list' is the class name'append' is the method nameAnd very important to note is that the object on which we wanted to invoke our method 'lstNumbers' is simply passed as the first parameter to the 'append' function.>>> list.append(lstNumbers, -3)>>> lst[4, -3]>>>This information may not seem important right now, but it will become quite relevant when we start creating our own classes. Namespaces and classesWhen Python works with classes, behind the scenes, it is working with namespaces.Every instance creates its own namespace. We can see this by accessing the data variable directly, by specifying the name space.>>> y.data3>>> x.data'hello'When it comes to methods, Python automatically maps the invocation of a method by an instance of a class to a call to a function defined in the class namespace on the instance argument. This will be on the exam. Okay, of course it won't. …. Or will it???Alright, that last sentence is certainly a brutal mouthful of jargon and terminology. --- And no, it won't be on your exam. ---So let's try and break it down. Suppose we have an instance of a class, let's call it 'x': x = MyClass()Whene we invoke a method via that instance: x.setTo(3)The Python interpreter then always translates that statement to:MyClass.setTo(x,3)Here is a generalization of how it works: When we invoke a method like so:instanceName.methodName(arg1, arg2, …)this method call is always translated by the Python interpreter into:className.methodName(instanceName, arg1, arg2, …)Example:word = "hello"word.upper()Behind the scenes, this statement will be translated by Python into:str.upper(word)Another example:If you instantiate an object of type MyClass like so:y = MyClass()and you invoke:y.setTo(-14)The Python interpreter will translate the above line to:MyClass.setTo(y, -14)This explains the self variable that we keep seeing in the class definition. The self argument that we refer to inside the methods of our class refers to the instance that invoked the method. def setTo(self, value): self.data = value def get(self): return self.dataThe self.xxxx() prefix in front of instance methods refers to the instance namespace. For example, the 'x' inx.get()refers to the 'x' namespace. ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download