Python Forum
Better Understanding Of Object Orientation In Python
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Better Understanding Of Object Orientation In Python
#1
Hello all

As part of my journey to learn python I have slowly started getting to grips with Object Orientation.

I have 3 x questions which I was hoping someone could help me with.

1) How is OOP implemented in real life. For example I have a piece of code that creates patients, as shown below:-

class Patient():
    def __init__(self, Age, Illness):
        self.Age = Age
        self.Illness = Illness 
        
        print("Patient Object Created")
I can create several different patient objects, however, when I turn my computer off and back on again the patients objects are lost and I have to re-create the same patient objects. My gut feeling is that the correct process would be that once an object is created then the data is stored in a dataframe / outputted to an excel document which is saved. When I turn off my computer and back on again Python reads in the excel document as objects – would this thinking be correct and is this how developers implement OOP in real life applications?


2) Using the example below, If I have a patient class from which I create a patient object such as tom = patient(23, “broken arm”), if I then entered the line of code tom = patient(45, “broken leg”) are there 2 x different objects created in memory i.e. tom 23 broken arm and tom 45 broken leg or is the first tom object overwritten? and would you find out how many objects have been created and stored in memory from a specific class?

class Patient():
    def __init__(self, Age, Illness):
        self.Age = Age
        self.Illness = Illness 
        
        print("Patient Object Created")
        
tom = Patient(23,"broken arm")

tom = Patient(45,"broken leg")
3) Finally using the example below, my class only has 2 x attributes, Age and Illness. After creating an object in this case tom = Patient(23, “broken arm”), I can add other attributes such as hair_color for example tom.hair_color = "red", why is this allowed, it would seem correct and proper for all the attributes of an object to be defined in the class so what is the purpose of allowing attributes to be created in an object that are not part of the class?

class Patient():
    def __init__(self, Age, Illness):
        self.Age = Age
        self.Illness = Illness 
        
        print("Patient Object Created")
        


tom = Patient(23,"broken arm")

tom.hair_color = "red"
Thank you.
Reply
#2
The OOP parts of you questions are silly. There is no answer to how OOP is used in Python. I use OOP differently than another programmer because I see solutions differently and I work in a different problem space. I would never use classes the way you are using classes in your examples. That doesn't mean your thinking is wrong. OOP is a design tool that can be used many different ways.

If you want persistent objects you need to implement persistence. If you want a database of patients you should use a database. The code that uses the database can be designed using OOP principles or not. I don't think it matters. The database can be object oriented or not. I don't think that matters either.

Python garbage collection is based on reference counting. When you assign a Python object to a variable the reference count increases by 1. If you use the same variable to reference a different Python object the reference count decreases by one. When the reference count goes to zero the object is made available for garbage collection. The memory is reused to make other Python objects.

In your example with the two toms, the first object is de-referenced when you re-use the variable tom to reference a second object. The object's memory is made available to the heap for making new objects.

Python classes are really just wrappers around a dictionary with a dash of syntactic sugar. You can add attributes to a dictionary, so you can add attributes to a class. A class in C has attributes that are defined before an instance of that class is ever created. This is not true for Python. In Python only the methods and class variables are defined and each instance is free to have whatever attributes are assigned. Usually instances are assigned in the __init__ method, but they don't have to be. If you want all instances to have the same attributes and don't want the user to ever add attributes you can use __slots__ when you define your class.
Reply
#3
A bunch of odds and ends, some having to do with style. Variables in Python should be lower case, and if you are using a multi-word variable name then an underscore should be used. Age and Illness should be age and illness, and part of that standard is that classes are usually upper case - so Patient is correct. This helps with reading the code. Not critical, it will work, but good habits to get in to.

The answer to your first question is that you are not saving the objects. There are a lot of ways to save the objects in Python, and your choice would depend on how many of the objects you plan to have and how you plan to access. Python has a unique storage called "pickle" that you can use, but there are some issues so I don't recommend. CSV is a simple solution. JSON is another format. You can do as you mention, converting to an Excel spreadsheet, or you can choose a database - SQL or otherwise. If you are planning to use this for real patient information you will need to be careful about HIPAA compliance.

Second question, when you reassign a variable it does just that. Here is a youtube from PyCon 2015 that does an excellent job of explaining the whole reference thing. So,
tom = Patient(45, MI)
creates a Patient object with those values and assigns it to tom.
tom = Patient(35, OD)
creates a Patient object with those values and assigns to tom, which releases the prior object.
It can get weird.
tom = Patient(45,MI)
dick = tom
dick.age = 99
Believe it or not, tom's age is now 99, even though you did not explicitly change it. See that youtube for why.

Third answer - this allows flexibility in contrast to highly typed languages. Consider your patient example, and you wish to include a comment on some but not all patients. You don't need to waste space with an empty string in all of your patients if you only wanted to comment that loretta is the mother of your office nurse.

Also remember that a class can contain functions (methods) and while a dictionary _can_ do that, it is less common for them to do so.
Reply
#4
(Aug-29-2020, 02:43 PM)jefsummers Wrote: Also remember that a class can contain functions (methods) and while a dictionary _can_ do that, it is less common for them to do so.
Less common, but it is exactly how python stores methods for the class. Unless you define the class to use slots, Python classes contain a dictionary named __dict__. This dictionary contains all the class attributes; class variables and methods.

I think looking at what goes in __dict__ is very informative.
class Scope:
    one = 1

    def __init__(self):
        self.two = 2
        
    def three(self):
        self._three = 3

scope = Scope()
scope2 = Scope()
scope2.three()

print('Scope class:', [item for item in Scope.__dict__])
print('scope instance:', [item for item in scope.__dict__])
print('scope2 instance:', [item for item in scope2.__dict__])
Output:
Scope class: ['__module__', 'one', '__init__', 'three', '__dict__', '__weakref__', '__doc__'] scope instance: ['two'] scope2 instance ['two', '_three']
Classes have a __dict__ and so does every instance of the class. The class __dict__ and the instance __dict__ are different. Notice that the class __dict__ knows about the class variables ('one') and methods ('__init__', 'three'). The instance __dict__ only knows about instance variables. scope1 knows about 'two' which is an instance variable set in the __init__ method. scope2 also knows about '_three' which is an instance variable created when the three() method was called. I could also add an instance variable externally
scope.four=4
This would add an instance variable to the instance scope, but would not affect the class or any other instance.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Understanding venv; How do I ensure my python script uses the environment every time? Calab 1 2,239 May-10-2023, 02:13 PM
Last Post: Calab
  New to python/coding Need help on Understanding why this code isn't working. Thanks! mat3372 8 1,736 May-09-2023, 08:47 AM
Last Post: buran
  Understanding Python classes PythonNewbee 3 1,181 Nov-10-2022, 11:07 PM
Last Post: deanhystad
  python update binary object (override delivered Object properties) pierre38 4 1,745 May-19-2022, 07:52 AM
Last Post: pierre38
  Understanding Python super() for classes OmegaRed94 1 1,825 Jun-09-2021, 09:02 AM
Last Post: buran
  fpdf orientation not working properly KatMac 1 3,310 May-02-2021, 10:47 AM
Last Post: Pedroski55
  Understanding Python's Import Engine MysticaL 1 2,154 Feb-07-2020, 11:26 PM
Last Post: snippsat
  Help with understanding a python package pyhill00 4 3,013 Mar-21-2019, 12:42 AM
Last Post: Larz60+
  Understanding if Statements in Python Kathleen 1 2,418 Mar-05-2019, 07:55 PM
Last Post: Yoriz
  Understanding Scoping in Python yksingh1097 5 3,834 Aug-06-2018, 07:42 PM
Last Post: nilamo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020