<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Object Oriented Programming &#8211; Digitaldocblog</title>
	<atom:link href="https://digitaldocblog.com/tag/object-oriented-programming/feed/" rel="self" type="application/rss+xml" />
	<link>https://digitaldocblog.com</link>
	<description>Various digital documentation</description>
	<lastBuildDate>Sat, 13 Aug 2022 16:38:53 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://digitaldocblog.com/wp-content/uploads/2022/08/cropped-website-icon-star-500-x-452-transparent-32x32.png</url>
	<title>Object Oriented Programming &#8211; Digitaldocblog</title>
	<link>https://digitaldocblog.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Python Classes and Objects in Depth &#8211; A Complete Guide</title>
		<link>https://digitaldocblog.com/python/python-classes-and-objects-in-depth-a-complete-guide/</link>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Thu, 03 Mar 2022 13:00:00 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Object Oriented Programming]]></category>
		<guid isPermaLink="false">https://digitaldocblog.com/?p=147</guid>

					<description><![CDATA[We can think of Classes as blueprints for Objects. Various Object-instances can be created based on one Class blueprint and attributes as well as functionalities defined in the Class blueprint&#8230;]]></description>
										<content:encoded><![CDATA[
<p>We can think of Classes as blueprints for Objects. Various Object-instances can be created based on one Class blueprint and attributes as well as functionalities defined in the Class blueprint will be passed as Object-properties after the Object instance has been created. Classes are callable and whenever we call a Class we create an Object instance of that particular Class. We say that Objects instances will be created based on a certain Class or Objects are of type of a certain Class. </p>



<p>In Classes functions are called methods. The init-method <code>__init__()</code> in a Class is called whenever a Class is called to create an Object instance using <code>Class()</code>. The init-method define attributes, variables and set the Object instance to a defined initial state. Therefore the init-Method is called <em>constructor</em>. </p>



<h3 class="wp-block-heading">The Parameter self</h3>



<p>Let&#8217;s imagine a Class <em>Car</em> that has attributes like brand, color and horsepower. We define the init-method using <code>def __init__(self)</code> and define all attributes using <code>self.&lt;attribut&gt; = &lt;value&gt;</code> in the init-method. A peculiarity of Python is that the init-method has at least one parameter <em>self</em> which is always passed by default. </p>



<p>The parameter <em>self</em> ensure that each attribute and its values will be linked to the correct Object instance stored in a certain memory address space.</p>



<pre class="wp-block-code"><code> class Car:
	def __init__(self):
		self.brand = None
        self.color = None
        self.horsepower = None
	
car1 = Car()
print(car1)

#Print-Output
#&lt;__main__.Car object at 0x10e0ffc40&gt;

</code></pre>



<p>When an Object instance <em>car1</em> of the Class <em>Car</em> will be created using <code>car1 = Car()</code> the init-method within the Class-Definition will be called and the <em>self</em> parameter will be passed to the new Object instance <em>car1</em>. If we print the Object instance <em>car1</em> on the console using <code>print(car1)</code> we don&#8217;t see a list of attributes or something similar, but we see the specific location in memory where the Object instance <em>car1</em> has been stored. This memory address is stored in the <em>self</em> parameter.</p>



<p>To show the peculiarity of Python with the <em>self</em> parameter more clearly, please take a look at the following notation.</p>



<pre class="wp-block-code"><code>class Car:
    def __init__(self):
        self.brand = None
        self.color = None
        self.horsepower = None
        self.self = self #reference is stored in self


car1 = Car()
print(car1)
print(car1.self)
print(car1.brand)

#Print-Output
#&lt;__main__.Car object at 0x10e0ffc40&gt;
#&lt;__main__.Car object at 0x10e0ffc40&gt;
#None

</code></pre>



<p>Within the init-method the value of the <em>self</em> parameter is assigned to the attribute <em>self.self</em> using <code>self.self = self</code>. The output for <code>print(car1.brand)</code> is None as expected. <code>print(car1)</code> and <code>print(car1.self)</code> show exactly the same print output. The memory address ist stored in the parameter <em>self</em> and the Object instance <em>car1</em> is a reference to this memory address. </p>



<h3 class="wp-block-heading">The dot notation</h3>



<p>We can assign values to each attribute, access each value and print the value to the console using the dot notation <code>print(&lt;object-instance&gt;.&lt;attribute-name&gt;)</code>. </p>



<pre class="wp-block-code"><code>class Car:
	def __init__(self):
		self.brand = None
        self.color = None
        self.horsepower = None
        
car1 = Car()
car1.brand = "BMW"
car1.color = "red"
car1.horsepower = 120

car2 = Car()
car2.brand = "Audi"
car2.color = "blue"
car2.horsepower = 150

print(car1.brand)
print(car2.brand)

#Print-Output
#BMW
#Audi

</code></pre>



<p>We create the Object <em>car1</em> as an instance of the Class <em>Car</em>. <em>car1</em> is a BMW, is red, has 120 PS. And we create another Object <em>car2</em>. <em>car2</em> is an Audi, is blue, has 150 PS. <em>car1</em> and <em>car2</em> are Object Instances of the Class <em>Car</em>. It is also often said that <em>car1</em> and <em>car2</em> are Objects of type <em>Car</em>. We access the individual attributes of the objects with the dot notation and get a print output of the brand using <code>print(car1.brand)</code> and <code>print(car2.brand)</code>.</p>



<h3 class="wp-block-heading">Working with Object instances</h3>



<p>To make the code clearer the attribute values ​​can also be passed as parameters directly during object instantiation.</p>



<pre class="wp-block-code"><code>class Car:
	def __init__(self, brand, color, horsepower):
		self.brand = brand
        self.color = color
        self.horsepower = horsepower
        
car1 = Car("BMW", "red", 120)
car2 = Car("Audi", "blue", 150)

print(car1.brand)
print(car2.brand)

#Print-Output
#BMW
#Audi

</code></pre>



<p>Therefore the init-method must have beside the parameter <em>self</em> also the parameters brand, color and horsepower. When we create the Object instances <em>car1</em> and <em>car2</em> of the Class <em>Car</em> we pass the parameters in the brackets during the call of the Class <em>Car</em> .</p>



<p>As mentioned above, functions in Classes are called methods. We have already got to know one method, the init method <code>__init__()</code> that will be executed when an Object instance will be created.</p>



<p>Classes can have also methods designed by the developer himself as well. In our example we add the drive-Method to the Class <em>Car</em> as follows.</p>



<pre class="wp-block-code"><code>class Car:
    def __init__(self, brand, color, horsepower):
        self.brand = brand
        self.color = color
        self.horsepower = horsepower
        self.x = 0
        self.y = 0

    def drive(self):
        self.x += 10
        self.y += 15
		print("X and Y have been increased by 10 and 15")

car1 = Car("BMW", "red", 120)

print(car1.x)
print(car1.y)

car1.drive()

print(car1.x)
print(car1.y)

#Print-Output
#0
#0
#X and Y have been increased by 10 and 15
#10
#15	

</code></pre>



<p>Here we add 2 additional attributes to the constructor <em>self.x</em> and <em>self.y</em> and set both attributes initially to the value 0. The drive-method <code>drive()</code> is defined to increase the values <em>self.x</em> by 10 and <em>self.y</em> by 15 and to print a string to the console. In the above example you can see that the values of <em>self.x</em> and <em>self.y</em> are 0 when we print them to the console directly after the Object <em>car1</em> has been created. Then we call the drive-method on the Object instance <em>car1</em> using <code>car1.drive()</code> and <em>self.x</em> and <em>self.y</em> have been increase by 10 or 15 plus the string has been printed to the console.</p>



<h3 class="wp-block-heading">Inheritance</h3>



<p>There can be several classes in programs, including classes that are very similar and only differ in details. This is where the concept of <em>inheritance</em> comes into play. We want to write a program in which there are 3 classes of vehicles: there are cars, trucks and motorcycles.</p>



<p>We assume all vehicles have the attributes brand, color, and horsepower, but cars should have two drive wheels, trucks four, and motorcycles should have only one drive wheel. In addition, the vehicles have different drive-methods because they can move at different speeds.</p>



<pre class="wp-block-code"><code>class Car:
    def __init__(self, brand, color, horsepower):
        self.brand = brand
        self.color = color
        self.horsepower = horsepower
        self.drivewheels = 2
        self.x = 0
        self.y = 0

    def drive(self):
        self.x += 10
        self.y += 15
        print("Car accelerates by 10 and 15")

class Truck:
    def __init__(self, brand, color, horsepower):
        self.brand = brand
        self.color = color
        self.horsepower = horsepower
        self.drivewheels = 4
        self.x = 0
        self.y = 0

    def drive(self):
        self.x += 5
        self.y += 10
        print("Truck accelerates by 5 and 10")

class Motorcycle:
    def __init__(self, brand, color, horsepower):
        self.brand = brand
        self.color = color
        self.horsepower = horsepower
        self.drivewheels = 1
        self.x = 0
        self.y = 0

    def drive(self):
        self.x += 30
        self.y += 40
        print("Motorcycle accelerates by 30 and 40")

car1 = Car("BMW", "blue", 120)
truck1 = Truck("Volvo", "black", 270)
moto1 = Motorcycle("Yamaha", "green", 70)

print(car1.brand, car1.x, car1.y)
car1.drive()
print(car1.brand, car1.x, car1.y)

print(truck1.brand, truck1.y, truck1.y)
truck1.drive()
print(truck1.brand, truck1.y, truck1.y)

print(moto1.brand, moto1.x, moto1.y)
moto1.drive()
print(moto1.brand, moto1.x, moto1.y)

#Print-Output
#BMW 0 0
#Car accelerates by 10 and 15
#BMW 10 15
#Volvo 0 0
#Truck accelerates by 5 and 10
#Volvo 10 10
#Yamaha 0 0
#Motorcycle accelerates by 30 and 40
#Yamaha 30 40

</code></pre>



<p>We create 3 Object instances from <em>Car</em>, <em>Truck</em> and <em>Motorcycle</em> and have access to their attributes and to their individual drive-methods. Everything is working fine but most of the code is redundant. </p>



<p>Instead of duplicating the code in each Class, we can define a parent Class from which all Child classes inherit their properties. The parent Class in our example will be the Class <em>Vehicle</em>.</p>



<pre class="wp-block-code"><code>class Vehicle:
    def __init__(self, brand, color, horsepower):
        self.brand = brand
        self.color = color
        self.horsepower = horsepower
        self.x = 0
        self.y = 0

	def inheritedmethod(self):
		print("this method was inherited")

class Car(Vehicle):
    drivewheels = 2

    def drive(self):
        self.x += 10
        self.y += 15
        print("Car accelerates by 10 and 15")

class Truck(Vehicle):
    drivewheels = 4

    def drive(self):
        self.x += 5
        self.y += 10
        print("Truck accelerates by 5 and 10")

class Motorcycle(Vehicle):
    drivewheels = 1

    def drive(self):
        self.x += 30
        self.y += 40
        print("Motorcycle accelerates by 30 and 40")


car1 = Car("BMW", "blue", 120)
truck1 = Truck("Volvo", "black", 270)
moto1 = Motorcycle("Yamaha", "green", 70)

print(car1.brand, car1.x, car1.y, car1.drivewheels)
car1.drive()
print(car1.brand, car1.x, car1.y, car1.drivewheels)

print(truck1.brand, truck1.y, truck1.y, truck1.drivewheels)
truck1.drive()
print(truck1.brand, truck1.y, truck1.y, truck1.drivewheels)

print(moto1.brand, moto1.x, moto1.y, moto1.drivewheels)
moto1.drive()
print(moto1.brand, moto1.x, moto1.y, moto1.drivewheels)
moto1.inheritedmethod()

#Print-Output
#BMW 0 0 2
#Car accelerates by 10 and 15
#BMW 10 15 2
#Volvo 0 0 4
#Truck accelerates by 5 and 10
#Volvo 10 10 4
#Yamaha 0 0 1
#Motorcycle accelerates by 30 and 40
#Yamaha 30 40 1
#this method was inherited

</code></pre>



<p>The constructor <code>__init__()</code> of the parent-Class <em>Vehicle</em> contain the initial setup that is inherited to the child-Classes. The parent-Class <em>Vehicle</em> also inherit the method <code>inheritedmethod()</code> to each child-Class. Each Object instance created from a child-Class will have this initial setup. The child-Classes itself have no <code>__init__()</code> constructor in these examples. Each Object instance such as <em>car1</em>, <em>truck1</em> and <em>moto1</em> created from their child-Classes <em>Car</em>, <em>Truck</em> and <em>Motorcycle</em> can access all inherited properties from their common parent-Class <em>Vehicle</em> and their individual Class attributes <code>drivewheels</code> and the individual methods <code>drive()</code>.</p>



<p><strong>note:</strong> <em>I will explain Class-attributes later in the text</em></p>



<p>Inherited methods from the parent-Class can be overwritten in the child-Class.</p>



<pre class="wp-block-code"><code>class Vehicle:
    def __init__(self, brand, color, horsepower):
        self.brand = brand
        self.color = color
        self.horsepower = horsepower
        self.x = 0
        self.y = 0

    def inheritedmethod(self):
        print("this method was inherited")

class Car(Vehicle):
    drivewheels = 2

    def drive(self):
        self.x += 10
        self.y += 15
        print("Car accelerates by 10 and 15")

    def inheritedmethod(self):
        print("this method was inherited and! overwritten")

car1 = Car("BMW", "blue", 120)

print(car1.brand, car1.x, car1.y, car1.drivewheels)
car1.drive()
print(car1.brand, car1.x, car1.y, car1.drivewheels)
car1.inheritedmethod()

#Print-Output
#BMW 0 0 2
#Car accelerates by 10 and 15
#BMW 10 15 2
#this method was inherited and! overwritten

</code></pre>



<p>In order to overwrite an inherited method, the same method head is simply written down again in the child-Class and the code of the method body is then adapted accordingly.</p>



<h3 class="wp-block-heading">The super() method</h3>



<p>A reference to the parent-Class can be established using the <code>super()</code> method. This allows us to take methods from the parent-Class and add additional properties in the code of the method in the child-Class.</p>



<pre class="wp-block-code"><code>class Vehicle:
    def __init__(self, brand, color, horsepower):
        self.brand = brand
        self.color = color
        self.horsepower = horsepower
        self.x = 0
        self.y = 0

    def inheritedmethod(self):
        print("this method was inherited")

class Car(Vehicle):
    def __init__(self, brand, color, horsepower, drivewheels):
        super().__init__(brand, color, horsepower)
        self.drivewheels = drivewheels

    def drive(self):
        self.x += 10
        self.y += 15
        print("Car accelerates by 10 and 15")

    def inheritedmethod(self):
        super().inheritedmethod()
        print("this method was inherited and! overwritten")

class Truck(Vehicle):
    def __init__(self, brand, color, horsepower, drivewheels):
        super().__init__(brand, color, horsepower)
        self.drivewheels = drivewheels

    def drive(self):
        self.x += 5
        self.y += 10
        print("Truck accelerates by 5 and 10")
        
car1 = Car("BMW", "blue", 120, 2)
truck1 = Truck("Magirus Deuz", "grey", 177, 4)

print(car1.brand, car1.x, car1.y, car1.drivewheels)
car1.drive()
print(car1.brand, car1.x, car1.y, car1.drivewheels)
car1.inheritedmethod()

print(truck1.brand, truck1.y, truck1.y, truck1.drivewheels)
truck1.drive()
print(truck1.brand, truck1.y, truck1.y, truck1.drivewheels)
truck1.inheritedmethod()

#Print-Output
#BMW 0 0 2
#Car accelerates by 10 and 15
#BMW 10 15 2
#this method was inherited
#this method was inherited and! overwritten
#Magirus Deuz 0 0 4
#Truck accelerates by 5 and 10
#Magirus Deuz 10 10 4
#this method was inherited

</code></pre>



<p>We had no <code>__init__()</code> method so far in our child-Classes but we defined for each child-Class the specific Class attribute <code>drivewheels</code>. This approach works fine. To understand how the <code>super()</code> method works we code for each child-Class a specific <code>__init__()</code> method and provide all parameters plus the parameter <code>drivewheels</code>. This means the value for <code>drivewheels</code> will be passed when the Object-instance from the child-Class is created and we have more flexibility there. Finally, it is possible that cars for example can have 4 drive wheels instead of 2. Then we use the <code>super()</code> method to refer to the <code>__init__()</code> method in the parent-Class and  pass the properties required there and create the additional property <code>self.drivewheels = drivewheels</code> . In the child-Class <em>Car</em> we also use the <code>super()</code> method in the method <code>inheritedmethod</code> and add additional functionality (simple print command). We don’t do this in the child-Class Truck. Then we create the Object instances <em>car1</em> and <em>truck1</em> and access the properties and methods.</p>



<h3 class="wp-block-heading">Special attributes</h3>



<p>The attributes used so far are all 100 percent usable outside of the respective class definition. In the code below I have simplified the classes considerably to focus on the essentials. </p>



<pre class="wp-block-code"><code>class Vehicle:
    def __init__(self, brand, color, horsepower):
        self.brand = brand
        self.color = color
        self.horsepower = horsepower

class Car(Vehicle):
    def __init__(self, brand, color, horsepower, drivewheels):
        super().__init__(brand, color, horsepower)
        self.drivewheels = drivewheels

car1 = Car("BMW", "blue", 120, 2)

print(car1.brand)
car1.brand = "Audi"
print(car1.brand)

#Print-Output
#BMW
#Audi

</code></pre>



<p>We access the attribute <em>brand</em> and print the value <em>BMW</em> to the console. Then we change the value from <em>BMW</em> to <em>Audi</em> using the dot notation and overwrite the existing value. </p>



<p>Sometimes developers of a Class want to signal developers that attributes should only be used inside the Class and not outside. Developers can mark attributes with one underscore <code>_</code> or with two underscores <code>__</code> to show that attributes should not or can not be easily overridden.</p>



<pre class="wp-block-code"><code>class Vehicle:
    def __init__(self, brand, color, vmax):
        self._brand = brand
        self.__color = color
        self.vmax = vmax

class Car(Vehicle):
    def __init__(self, brand, color, vmax, drivewheels):
        super().__init__(brand, color, vmax)
        self.drivewheels = drivewheels

car1 = Car("BMW", "blue", 100, 2)

print(car1._brand)
car1._brand = "Audi"
print(car1._brand)

print(car1._Vehicle__color)
car1._Vehicle__color = "black"
print(car1._Vehicle__color)

#Print-Output
#BMW
#Audi
#blue
#black

</code></pre>



<p>In the example above we have the attribute <code>_brand</code> with one underscore. This shows the developer that <code>_brand</code> is a special attribute which is defined in the parent-Class <em>Vehicle</em> and inherited to the child-Class <em>Car</em> and should not be overwritten. However, overwriting is possible without any problems using the dot notation. The attribute <code>__color</code> is also defined in parent-Class <em>Vehicle</em> and inherited to child-Class <em>Car</em> but can not be overwritten using the standard dot notation. The value of the attribute <code>__color</code> can only be accessed using a different attribute name <code>_Vehicle__color</code>. Obviously the name of the attribute <code>__color</code> can only be accessed if we extend the attribute name at the beginning with <code>&lt;_parent-Classname&gt;&lt;__attribute-name&gt;.</code> This is called <em>Name Mangling</em>.</p>



<h3 class="wp-block-heading">Multiple inheritance</h3>



<p>So far we had a parent-Class and single inheritance of properties to a child-Class. But it is also possible to define more parent-Classes and inherit their properties to a child-Class. This is called <em>multiple inheritance</em>. With multiple inheritance we can create complex data structures. In the following code I define 3 parent-Classes <em>Person</em>, <em>Organisation</em>, <em>Building</em> and 2 child-Classes <em>Employee</em> and <em>Location</em>. </p>



<pre class="wp-block-code"><code>class Person:
    def __init__(self, userid, name, lastname, age):
        self.userid = userid
        self.name = name
        self.lastname = lastname
        self.age = age

class Organisation:
    def __init__(self, company, orgunit):
        self.company = company
        self.orgunit = orgunit

class Building:
    def __init__(self, country, postalcode, street, city):
        self.country = country
        self.postalcode = postalcode
        self.street = street
        self.city = city

class Employee(Person, Organisation):
    def __init__(self, userid, name, lastname, age, company, orgunit):
        Person.__init__(self, userid, name, lastname, age)
        Organisation.__init__(self,  company, orgunit)

class Location(Building, Organisation):
    def __init__(self, country, postalcode, street, city, company, orgunit):
        Building.__init__(self, country, postalcode, street, city)
        Organisation.__init__(self, company, orgunit)


employee1 = Employee("12345", "Parick", "Rottländer", 54, "Company 1", "OE123456")
employee2 = Employee("67890", "Carol", "Meier", 32, "Company 2", "OE678901")
location1 = Location("Germany", "81234", "First Street 20", "Munich", "Company 1", "OE123456")
location2 = Location("Italy", "I23345", "Second Street 100", "Verona", "Company 2", "OE678901")

print(employee1.name, employee1.orgunit)
print(employee2.name, employee2.orgunit)
print(location1.country, location1.city)
print(location2.country, location2.city)

#Print-Output
#Parick OE123456
#Carol OE678901
#Germany Munich
#Italy Verona

</code></pre>



<p>In the code example above we define the child-Class <em>Employee</em> with properties from the parent-Classes <em>Person</em> and <em>Organisation</em>. Child-Class <em>Building</em> is defined with properties from parent-Classes <em>Location</em> and <em>Organisation</em>. Therefore the child-Class <em>Employee</em> inherits properties from parent-Classes <em>Person</em> and <em>Organization</em> and the child-Class <em>Location</em> inherit properties from parent-Classes <em>Building</em> and <em>Organisation</em>. In each child-Class the first <code>__init__()</code> constructor define the complete setup of an Object instance. Then each inherited parent-Class <code>__init()__</code> constructor is overwritten using the dot notation <code>&lt;parent-Class&gt;.__init()__</code>. Then we create the object instances <em>employee1</em>, <em>employee2</em> and <em>location1</em> and <em>location2</em> passing all required attributes and have access to each of those attributes using the dot notation. </p>



<h3 class="wp-block-heading">Instance- and Class-attributes</h3>



<p>If attributes of a Class are defined within the <code>__init()__</code> method, these are <em>Instance-attributes</em> and are available as initial setup in each Object instance created from that Class. If we define attributes in a Class before the <code>__init()__</code> method then these are <em>Class-attributes</em>. </p>



<pre class="wp-block-code"><code>class Person:
    counter = 0
    def __init__(self, name, lastname, age):
        self.userid = "P" +"-" +str(Person.counter)
        self.name = name
        self.lastname = lastname
        self.age = age
        Person.counter += 1

class Organisation:
    def __init__(self, company, orgunit):
        self.company = company
        self.orgunit = orgunit

class Employee(Person, Organisation):
    def __init__(self, name, lastname, age, company, orgunit):
        Person.__init__(self, name, lastname, age)
        Organisation.__init__(self,  company, orgunit)

print(Person.counter)
employee1 = Employee("Parick", "Rottländer", 54, "Company 1", "OE123456")
print(employee1.userid)
print(Person.counter)
employee2 = Employee("Carol", "Meier", 32, "Company 2", "OE678901")
print(employee2.userid)
print(Person.counter)

#Print-Output
#0
#P-0
#1
#P-1
#2
</code></pre>



<p>In the Class <em>Person</em> I define the Class-attribute <em>counter</em> and set its value to 0. Within the <code>__init__()</code> method of the Class <em>Person</em> I access the Class-attribute <em>counter</em> using <code>str(Person.counter)</code> to create a unique userid. Whenever an Object instance of <em>Person</em> is created <code>Person.counter</code> increase by 1 (see the respective print-output).</p>



<h3 class="wp-block-heading">Modules</h3>



<p>In the examples above we write the code in one Python file with the ending <code>&lt;filename&gt;.py</code>. Each Python file is a Module itself and can be executed independently. But a developer must not code any method on his own he or she can use existing code from third parties by loading other modules into his Python file. After modules have been loaded methods and properties defined in those modules can be user in the code.</p>



<p>Python has numerous <a href="https://docs.python.org/3/py-modindex.html" title="Build-in Modules in Python">built-in modules</a>. All of them can be used for free by developers in the code. In the following examples I will use the build-in module <a href="https://docs.python.org/3/library/math.html" title="Math Build-in Python Module">math</a> because math contain the parameter <em>pi </em> that we need for the calculation of the area of a circle for a given radius.  </p>



<pre class="wp-block-code"><code>#objectMain.py

import math

class Circle:
    def __init__(self, radius):
        self.radius = radius

    #calculate area from given radius
    def area(self):
        return math.pi * self.radius ** 2

c1 = Circle(5)
print(c1.area())

#Print-Output
#78.53981633974483

</code></pre>



<p>In the file <code>objectMain.py</code> we first <code>import math</code> and define the Class <em>Circle</em>. Then we pass the parameter <em>radius</em> in the <code>__init()__</code> constructor. The instance attribute <em>self.radius</em> receive the given value <em>radius</em> when an Object instance is created with a given radius value. The <code>area()</code>method use the parameter <em>pi</em> from the math Module and return the calculated area for the given radius.  </p>



<p>But we can also develop methods on our own separately in separate Python files and make them available as modules. We can then either import the entire module or just individual methods from the module. I define a method <code>radius()</code> in a separate module <code>objectModuleCalc.py</code> to calculate the radius from a given area. </p>



<pre class="wp-block-code"><code>#objectModuleCalc.py

import math

#calculate radius from given area
def radius(area):
    return math.sqrt(area/math.pi)

</code></pre>



<p>To use the method <code>radius()</code> in my  <code>objectMain.py</code> file I must import the module from the <code>objectModuleCalc.py</code> file using <code>import &lt;filename&gt;</code>. </p>



<pre class="wp-block-code"><code>#objectMain.py

import math
import objectModuleCalc

class Circle:
    def __init__(self, radius):
        self.radius = radius

    #calculate area from given radius
    def area(self):
        return math.pi * self.radius ** 2

c1 = Circle(5)
print(c1.area())

print(objectModuleCalc.radius(78.54))

#Print-Output
#78.53981633974483
#5.000005846084075

</code></pre>



<p>After the import I can access the method <code>radius()</code> in the imported module using the dot notation<code>&lt;filename&gt;.&lt;method&gt;</code>. </p>



<p>Another way to import the Module from the <code>objectModuleCalc.py</code> file is using an alias <code>import &lt;filename&gt; as &lt;alias&gt;</code>. </p>



<pre class="wp-block-code"><code>#objectMain.py

import math
import objectModuleCalc as calc

class Circle:
    def __init__(self, radius):
        self.radius = radius

    #calculate area from given radius
    def area(self):
        return math.pi * self.radius ** 2

c1 = Circle(5)
print(c1.area())

print(calc.radius(78.54))

#Print-Output
#78.53981633974483
#5.000005846084075

</code></pre>



<p>After the import I can access the code in the imported module using the dot notation<code>&lt;alias&gt;.&lt;method&gt;</code>.</p>



<p>In the example above you see that the method <code>area()</code> can only be used when an object instance has been created. The method is used on the Object instance using <code>c1.area()</code>. </p>



<h3 class="wp-block-heading">Static Methods</h3>



<p>With <em>static methods</em> we can use a method defined in a class without having created an Object instance. We have no Class reference and no Object reference. We use the Function Decorator <code>@staticmathod</code> before the method definition.  </p>



<pre class="wp-block-code"><code>#objectMain.py

import math

class Circle:
    def __init__(self, radius):
        self.radius = radius

    #calculate area from given radius
    @staticmethod
    def area(radius):
        return math.pi * radius ** 2

print(Circle.area(5))

#Print-Output
#78.53981633974483

</code></pre>



<p>Static methods have no reference to the Class and no reference to the Object instance once it has been created. Therefore we can not access any attributes defined in the Class like Class-attributes or the Instance-attribute <code>self.radius</code>. This is the reason why we must pass a separate parameter <code>radius</code> into the method <code>area()</code>. The value of the parameter <em>radius</em> can then be used by the variable <em>radius</em> within the method <code>area()</code> when we call the method using <code>&lt;Classname&gt;.&lt;method&gt;(&lt;parameter&gt;)</code>. </p>



<h3 class="wp-block-heading">Class methods</h3>



<p>With <em>Class methods</em> we can use a method defined in a Class also without having created an Object instance. We use the Function Decorator <code>@classmethod</code> before the method definition. </p>



<pre class="wp-block-code"><code>#objectMain.py

import math

class Circle:
    counter = 0
    def __init__(self, radius):
        self.radius = radius
        Circle.counter += 1

    #calculate area from given radius
    @staticmethod
    def area(radius):
        return math.pi * radius ** 2

    #print the current counter value
    @classmethod
    def printcounter(cls):
        print("Actual value of counter is: " +str(cls.counter))

Circle.printcounter()
c1 = Circle(5)
Circle.printcounter()

#Print-Output
#Actual value of counter is: 0
#Actual value of counter is: 1

</code></pre>



<p>I define the Class method <code>printcounter(cls)</code>. The parameter <em>cls</em> is the Class reference to ensure that also Class-attributes like <em>counter</em> can be used within the Class-method. The Class-method is called using <code>&lt;Classname&gt;.&lt;class-method-name&gt;</code>. In the Class <em>Circle</em> we define the Class-attribute <em>counter</em> ant set it to the value of 0. The <code>__init__()</code> constructor create an Object instance of type <em>Circle</em> when we call <code>Circle()</code> . Each time we create an Object instance, the counter value of the Class <em>Circle</em> is incremented by 1. We define the Class-method <code>printcounter(cls)</code> and pass the parameter <em>cls</em> to establish the Class reference. Then we can access the Class attribute counter in the <code>printcounter(cls)</code> method using <code>cls.counter</code>. We call the Class method using <code>&lt;Classname&gt;.&lt;classmethod&gt;</code> and see in the print output that the counter value increased by 1 after we created the Object instance <em>c1</em>.</p>



<p><strong>note:</strong> <em>In the <code>__init__()</code> constructor above we still use the parameter <code>radius</code> and we pass a value for <code>radius</code> when we create an Object instance from Class Circle. This does not really make sense in this example because we do not use it as we the method <code>area()</code> is defined as static method and there we pass a separate radius value with the method call. Because we will need passing the radius in the text below I decided to keep the <code>__init__()</code> constructor as it is to avoid confusion.</em> </p>



<p>The Class method <code>printcounter(cls)</code> above return a <code>print()</code> function. So when we call the method  <code>printcounter(cls)</code> we get a print output at the console. </p>



<p>A Class-method can also return an Object instance. Therefore I define another Class-method <code>radius(cls, area)</code> in the code below. This Class-method has 2 parameters: <em>cls</em> is the Class parameter and stand for the Class reference to ensure that also Class-attributes can be used within the Class method and <em>area</em> to pass the given area value to calculate the radius.</p>



<pre class="wp-block-code"><code>#objectMain.py

import math

class Circle:
    counter = 0
    def __init__(self, radius):
        self.radius = radius
        Circle.counter += 1

    #calculate area from given radius
    @staticmethod
    def area(radius):
        return math.pi * radius ** 2

    #print the current counter value
    @classmethod
    def printcounter(cls):
        print("Actual value of counter is: " +str(cls.counter))

    #calculate radius from given area
    @classmethod
    def radius(cls, area):
        r = math.sqrt(area / math.pi)
        return Circle(r)

Circle.printcounter()
c1 = Circle(5)
print(type(c1))
print(c1.radius)
Circle.printcounter()
c2 = Circle.radius(78)
print(type(c2))
print(c2.radius)
Circle.printcounter()

#Print-Output
#Actual value of counter is: 0
#&lt;class '__main__.Circle'&gt;
#5
#Actual value of counter is: 1
#&lt;class '__main__.Circle'&gt;
#4.982787485166879
#Actual value of counter is: 2

</code></pre>



<p>The Class method <code>radius()</code>here is the same method we defined above in a separate module. Here we use <code>radius()</code> to calculate the radius <em>r</em> for a given area value that we pass with the method call. The Class method <code>radius()</code>  return an Object instance of type <em>Circle</em> passing the calculated radius using <code>return Circle(r)</code>. After we create the Object instance <em>c1</em> using <code>c1 = Circle(5)</code> we see in the print output above that <em>c1</em>  is of type <em>Circle</em> <code>class '__main__.Circle </code>.  We can access the passed radius value using the dot notation <code>c1.radius</code>. Then we call the Class-method <code>Circle.radius(cls, area)</code> with the area parameter 78 and assign the return value to the variable <em>c2</em> using <code>c2 = Circle.radius(78)</code>. As we expected <em>c2</em> is also of type <code>class '__main__.Circle </code> . We can access the calculated radius value using <code>c2.radius</code>. In the print output you also see that the counter increased from 0 to 2 meaning that 2 Object instances <em>c1</em> and <em>c2</em> both of type <em>Circle</em> have been created. </p>



<p>A Class-method can return an Object instance of type of the calling class. Therefore I define a new child-Class <em>Rim</em>. <em>Rim</em> inherits all properties of the parent-Class <em>Circle</em> using <code>Rim(Circle)</code> and <em>Rim</em> has no <code>__init__()</code> constructor. Instead we use <em>pass</em> so that we can create an Object instance of <em>Rim</em> and all properties come from the parent-Class <em>Circle</em>. </p>



<pre class="wp-block-code"><code>#objectMain.py

import math

class Circle:
    counter = 0
    def __init__(self, radius):
        self.radius = radius
        Circle.counter += 1

    #calculate area from given radius
    @staticmethod
    def area(radius):
        return math.pi * radius ** 2

    #print the current counter value
    @classmethod
    def printcounter(cls):
        print("Actual value of counter is: " +str(cls.counter))

    #calculate radius from given area
    @classmethod
    def radius(cls, area):
        r = math.sqrt(area / math.pi)
        return cls(r)

class Rim(Circle):
    pass

Circle.printcounter()
c2 = Circle.radius(78)
print(type(c2))
print(c2.radius)

Circle.printcounter()
r1 = Rim.radius(120)
print(type(r1))
print(r1.radius)

Circle.printcounter()

#Print-Output
#Actual value of counter is: 0
#&lt;class '__main__.Circle'&gt;
#4.982787485166879
#Actual value of counter is: 1
#&lt;class '__main__.Rim'&gt;
#6.180387232371033
#Actual value of counter is: 2

</code></pre>



<p>The Class method <code>radius()</code> in the parent-Class <em>Circle</em> has changed a bit: The method return not necessarily an Object instance of type <em>Circle</em> but an Object instance of the calling Class <code>return cls(r)</code>.  Then we call the Class method <code>Circle.radius(cls, area)</code> with the area parameter 78 and assign the return value to the variable <em>c2</em> using <code>c2 = Circle.radius(78)</code>. As expected <em>c2</em> is of type <code>class '__main__.Circle </code> . When we call the Class method using <code>Rim.radius(cls, area)</code> with the area parameter 120 and assign the return value to the variable <em>r1</em> using <code>r1 = Rim.radius(120)</code> we see that <em>r1</em> is of type <code>class '__main__.Rim </code>.</p>



<h3 class="wp-block-heading">Property attributes and setters</h3>



<p>In the text above we have already dealt with attributes that begin with one underscore <code>_</code> or double underscores <code>__</code> and thus indicate that these attributes should be touched carefully from the outside or even cannot be changed at all in the case when we use double underscores. </p>



<p>Here we want to deal again with accessing attributes and changing their values. To show the problem I use the Class Circle and the method <code>area()</code> that is defined within the Class <em>Circle</em> to calculate the area value for the given radius that we pass when we create an Object instance <em>c1</em>using <code>c1 = Circle(&lt;radius&gt;)</code>.</p>



<pre class="wp-block-code"><code>import math

class Circle:
    def __init__(self, radius):
        self.radius = radius

    # calculate area from given radius
    def area(self):
        return math.pi * self.radius ** 2

c1 = Circle(5)
print(c1.radius)
print(c1.area())
c1.radius = -10
print(c1.radius)

#Print-Output
#5
#78.53981633974483
#-10
#print(c1.area())
#314.1592653589793

</code></pre>



<p>In the code above you see that we are able to change the value of radius from outside to <em>-10</em> using <code>c1.radius = -10</code>. This doesn&#8217;t make much sense, even if the value of the area is calculated correctly because <code>self.radius ** 2</code> in the <code>area()</code> method.</p>



<p>Then we define the instance attribute <code>self._radius</code> in the <code>__init__()</code> constructor. The radius value passed when we create the Object instance will be assigned to <code>self_radius</code> using <code>self_radius = radius</code> . The underscore shows that the attribute should be touched carefully from the outside.</p>



<pre class="wp-block-code"><code>import math

class Circle:
    def __init__(self, radius):
        self._radius = radius

    # calculate area from given radius
    def area(self):
        return math.pi * self._radius ** 2

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, radius):
        if radius &gt;= 0:
            self._radius = radius

c1 = Circle(5)

print(c1.radius)
print(c1.area())

c1.radius = -10
print(c1.radius)
print(c1.area())

c1.radius = 10
print(c1.radius)
print(c1.area())

c1._radius = -10
print(c1.radius)
print(c1.area())

#Print-Output
#5
#78.53981633974483
#5
#78.53981633974483
#10
#314.1592653589793
#-10
#314.1592653589793

</code></pre>



<p>First we define a Property attribute using the Property Decorator <code>@Property</code>. The Property attribute definition is a method that return <code>self_radius</code> when we call <code>radius</code>. This mean when we can call <code>&lt;Object-Instance&gt;.radius</code> instead of <code>&lt;Object-Instance&gt;._radius</code> when we want to access the Property attribute. Then we define a Property setter using <code>@&lt;Property-attribute&gt;.setter</code>, in this case we use <code>@radius.setter</code>. The Property setter definition is a method that set <code>self._radius = radius</code> only in case radius is greater or equal to 0. In the following we create the Object instance <em>c1</em>  with given radius of 5 and access the given radius using <code>c1.radius</code>. As you see in the print output we are able to change the value to <em>10</em>. Even if we are not able to change the value to <em>-10</em> when we use <code>c1.radius = -10</code> we are still able to change the value to <em>-10</em> using <code>c1._radius = -10</code>.</p>



<p>We define the instance attribute <code>self.__radius</code> in the <code>__init__()</code> constructor. The radius value passed when we create the Object instance will be assigned to <code>self__radius</code> using <code>self__radius = radius</code>. The double underscore <code>__</code> shows that the attribute can not be touched from the outside.</p>



<pre class="wp-block-code"><code>class Circle:
    def __init__(self, radius):
        self.__radius = radius

    # calculate area from given radius
    def area(self):
        return math.pi * self.__radius ** 2

    @property
    def radius(self):
        return self.__radius

    @radius.setter
    def radius(self, radius):
        if radius &gt;= 0:
            self.__radius = radius

c1 = Circle(5)
print(c1.radius)
print(c1.area())

c1.radius = -10
print(c1.radius)
print(c1.area())

c1.radius = 10
print(c1.radius)
print(c1.area())

c1.__radius = -10
print(c1.radius)
print(c1.area())

#Print-Output
#5
#78.53981633974483
#5
#78.53981633974483
#10
#314.1592653589793
#10
#314.1592653589793

</code></pre>



<p>The Property attribute definition is a method that now return <code>self__radius</code> when we call <code>radius</code>. The Property setter definition is now a method that set <code>self.__radius = radius</code> only in case radius is greater or equal to 0. We create the Object instance <em>c1</em>  with given radius of 5 and access the given radius using <code>c1.radius</code>. As you see in the print output we are able to change the value to <em>10</em> but we are not able to change the value to <em>-10</em> when we use <code>c1.radius = -10</code> and <code>c1.__radius = -10</code>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
