OPS435 Python Lab 7
- Object-oriented programming is one level of complexity higher than simply structured programming as you've experienced in languages such as Bash or C. In this second lab on objects we're going to look at slightly more complex issues that come up when using them.
- In previous labs, you have been advised to make notes and use online references. This also relates to learning about object oriented programming to help becoming "overwhelmed" with the volume of information in this lab.
- Below is a table with links to useful online Python reference sites (by category). You may find these references useful when performing assignments and labs.
|Scope||Notes on Python Variable Scope|
INVESTIGATION 1: Classes and Objects
In the last lab we created a class named Student and a couple of objects of type Student which were named student1 and student2. Let's spend some more time on that distinction.
A class is a type, a description of a thing, the definition of what it should look like. An object is an instance of a class, an individual described by a class, a specific thing with properties defined by a class. Here are some examples of what might be types and what might be objects of those types:
|Class||Objects of that class|
|IPAddress||192.168.1.3, 192.168.1.10, 10.0.0.50, 188.8.131.52|
|Person||Andrew Oatley-Willis, Murray Saul, Andrew Smith|
|BMWModel||BMW2Series, BMW3Series, BMW4Series, BMWXSeries, BMWMSeries, BMWiSeries|
|Car||Andrew's silver Civic with VIN 1234567890, John's blue Subaru with VIN 0987654321, Evan's Black BMWMSeries with VIN 4567981230|
The exact definition of the type and what you would expect to store in objects of that type is up to you - the programmer. You want to design your classes so that you can manage data in your application as easily as possible.
Notes about the mechanics of implementing classes:
- Inside a program typically a class name starts with a capital letter and object names, as typical variable names, start with a lowercase letter.
- Just as you can define a function in a separate file from where you use it - you can define a class in a separate file. In fact it's even more common with classes since you're more likely to need to use them in multiple places.
- The names of the files are by convention all lowercase and short - but that's just because programmers are lazy typists. Feel free to give the files longer names so you can tell what they are without opening them.
For this investigation create the classes and objects from the table above. No test script is provided for this section because the design of the classes is left up to you. Store the data that you think might be relevant for that type. Implement at least two methods in each class (the constructor plus one other).
As you try to design the classes you will quickly realise that there is a potentially infinite number of properties (components) and methods that any class can have. What you choose to include in your class definition should be guided by what you intend to do with it. For example if the tire tread depth in the cars is important in your application - you should include it in your Car class. But if you don't care about when the last oil change was or you don't have the means of obtaining that information - there's no point in adding that to the description of the Car class.
In your main code - create some objects (perhaps the ones from the table plus whatever properties you came up with) and call the methods on those objects.
You may find that when you have more than one or two objects of a type - it will be easier to store them in a Python list instead of having separate variables for each of them. Again - which makes more sense depends entirely on what you do with your objects in your application in any particular situation.
To get you started, here's a template for a file you should name lab7a.py
#!/usr/bin/env python3 # Store one IPv4 address class IPAddress: # You probably want to construct it as a string, but you may want to store it as the four octets separately: def __init__(self, address): # Is this address from a private subnet? e.g. starting with 192.168. or 10. def isPrivate(): # Store information about a person, perhaps someone you'll be adding as a user to a system: class Person: # Store information about different models from a specific manufacturer. Perhaps how many seats they have and how much fuel they use and the price range: # Doesn't have to be BMW, pick any car or bike manufacturer: class BMWModel: # Store information about a specific car that someone owns. # Spend some time thinking why this class is different than the one above, and whether it has to be different: class Car:
INVESTIGATION 2: Scope
Scope means where in the code a variable is accessible from, and how long that variable exists.
In this lab we will look at the types of scope you're most likely to run into and which are most likely to cause trouble for you. We will not be explicitly looking at class scope, nested functions, built-in variables, constants, and mutability.
In Python any variable that is created inside a function has local scope. That means that it is accessible by any code inside that function, and is not accessible by any code outside the function. In other languages this concept is related to block scope but that does not exist in python. Every block inside a function has the same scope.
Try the following code. Have each in a separate Python file, iPython would cause way too many complications for this lab.
lab7b.py - local scope:
#!/usr/bin/env python3 def function1(): # This variable 'a' is completely unrelated to the variable 'a' in function2(): a = 'Andrew 1' print(a) def function2(): # This variable 'a' is completely unrelated to the variable 'a' in function1(): a = 'Andrew 2' print(a) # Note that you cannot make any of the following print() functions work because neither of # the variables '''a''' exist in this scope (outside the function where they were defined): a = 'Andrew 500' print(a) function1() print(a) function2() print(a) function1() function2()
Sometimes you want to have a variable accessible from anywhere in your program, including inside and outside any functions. Here's an example:
#!/usr/bin/env python3 def function1(): print(authorName) def function2(): print(authorName) authorName = 'Andrew' print(authorName) function1() print(authorName) function2() print(authorName)
Note that the same thing is printed over and over because the authorName variable is defined outside a function which makes it global which makes it accessible from anywhere.
Python has one weird quirk when it comes to global scope: if you assign something to a variable inside a function - it will assume you want to create a new variable in that function's local scope. That will hide the global variable inside the function unless you declare it explicitly as global:
#!/usr/bin/env python3 def function1(): authorName = 'Andrew 1' print(authorName) def function2(): global authorName authorName = 'Andrew 2' print(authorName) authorName = 'Andrew' print(authorName) function1() print(authorName) function2() print(authorName)
Note that the function1() call does not modify the global authorName variable but function2() does.
As an exercise: modify the example above so that it would print the following, by changing only the scope of some variables. Save the program as lab7c.py:
Andrew Andrew 1 Andrew 1 Andrew 2 Andrew 1
Every object can have variables that exist for that object only. You create and access those variables with the self. notation. Note that these are not class variables. Each object has its own set of instance variables. You will have seen that when you created objects in the Classes and Objects section above.
LAB 7 SIGN-OFF (SHOW INSTRUCTOR)
- Have Ready to Show Your Instructor:
- ✓ Output of running your scripts for this lab and
- ✓ Output of:
cat lab7a.py lab7b.py lab7c.py