I didn’t do as much As I thought I would today, as I was installing tightvnc on the Raspberry Pi. I then tried out acessing my RasPi on my Mac, Pc, and even my iPad mini. I wasn’t nuts enough t try it on my iPhone — yet. I did download the app though.
This should speed up the programming development side of things. Now, we are exploring classes.
Importing a Class
In our last installment, we learned how to make classes in Python. So we have something fresh to work with, open a new window and add this class:
#PSPythonStuff.py class PSPythonStuff: def __init__(self,a,b): self.a = a self.b = b self.penguin = 0 def myPythonFunction(self,a,b): return a+b*b def montyPythonFunction(self): return self.a+self.b*self.b def montyPenguinFunction(self): return self.a + self.penguin * self.penguin
Save it as PSPythonStuff.py. We created four functions in the class:
- A constructor for the class
- A function which computes a value all from parameters
- A function which computes a value all from attributes
- Another function which computes a value from attributes
In XCode, I am used to getting a custom class into another implementation file by using something like this:
In Python we obviously don’t have a header declaring types for everything. Instead we open the implementation file, which needs to be in the same directory as the file loading it. If the class file, called a module contains multiple classes we can select the classes we want to load, and skip the ones we don’t. We can load all classes in the module like this:
from PSPythonStuff import *
Now open a new window and let’s test this. Type in the following code:
#class_demo_2 from PSPythonStuff import * my_instance = PSPythonStuff(5,25) print(my_instance.myPythonFunction(5,25)) print(my_instance.montyPythonFunction()) my_instance.a = 4 print(my_instance.montyPythonFunction()) print(my_instance.montyPenguinFunction())
Save this as class_demo_2.py and run this code. If all goes correctly you should get the numbers
630 630 629 4
printed on your console. Besides using functions of the class, we also re-assigned an attribute with a new value.
The Disturbing Attribute
Go back to the PSPythonStuff.py module. Remove the following line of code:
self.penguin = 0
Now go back to class_Demo_2 module, and run it again. It should be no big surprise what happens:
return self.a + self.penguin * self.penguin AttributeError: 'PSPythonStuff' object has no attribute 'penguin'
penguin as an attribute and it is not defined anywhere. Add the following to just above the last print line in the module
my_instance.penguin = 25
your code should now look like this:
#class_demo_2 from PSPythonStuff import * my_instance = PSPythonStuff(5,25) print(my_instance.myPythonFunction(5,25)) print(my_instance.montyPythonFunction()) my_instance.a = 4 print(my_instance.montyPythonFunction()) my_instance.penguin = 25 print(my_instance.montyPenguinFunction())
Save and run your code. The console gives the following
630 630 629 629
That this works disturbs me. It is as disturbing as someone grafting a third arm on, then playing the guitar with it minutes later. It should not run and the Python interpreter should have a hissy fit about adding an attribute to a class outside of the class definition. But that would be Xcode freaking out, not Python. Python apparently doesn’t care if you pull this. It puts a lot of responsibility on the programmer. Here’s where it gets us into trouble. There might be an attribute in one instance of a class that isn’t in another. Trying to reference that attribute could cause a fatal error.
I’m sure Python has its reasons for this, but coming from a much more structured environment it scares the willies out of me what bugs will lie in the code I’ll write.