0% found this document useful (0 votes)
116 views18 pages

Chapter 16 (Oop) 1.intro Code:: Class Def

The document discusses object-oriented programming concepts in Python including: 1. Classes define objects and methods that act on those objects. A class defines attributes and behaviors of objects. 2. Instance methods act on object attributes and receive the object itself as the first argument (self). Class methods act on the class but receive the class as the first argument. 3. Class variables are shared among all instances of a class while instance variables are unique to each object instance.

Uploaded by

fake id
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
116 views18 pages

Chapter 16 (Oop) 1.intro Code:: Class Def

The document discusses object-oriented programming concepts in Python including: 1. Classes define objects and methods that act on those objects. A class defines attributes and behaviors of objects. 2. Instance methods act on object attributes and receive the object itself as the first argument (self). Class methods act on the class but receive the class as the first argument. 3. Class variables are shared among all instances of a class while instance variables are unique to each object instance.

Uploaded by

fake id
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 18

Chapter 16(oop)

1.intro: oop is just a style/way to write a code. It is very helpful to create a real world program.
code:
#objectives
#what is class
#how to create class
#what is INIT method or constructor
#what are ATTRIBUTES,INSTANCE VARIABLE
# how to create our object
class person:#def class
#any function define in class called as method
    def __init__(self,first_name,last_name,age):#first arguement in "init"  fu
nction is object . self is object and first_name,last_name,age are attributes
        #instance variables
        self.first_name=first_name# self.first_name, self.last_name,self.age a
re instance varibles
        self.last_name=last_name
        self.age=age

p1=person("Ankush","Singh",20)#p1,p2 is object
p2=person("Abhay","Kumar",21)
print(p1.first_name)#when we call p1 then self =p1

output:
Ankush

Kumar

small exercise:

code:
class laptop:
    def __init__(self,brand_name,model_name,price):
        self.brand_name = brand_name
        self.model_name = model_name
        self.price = price
        self.laptop_name= brand_name+" "+model_name
l1=laptop("dell","inspiron 15 3576",55000)
l2=laptop("hp","pavallion ",89000)
l3=laptop("acer","predator",59000)

print(l1.brand_name,l2.model_name)
print(l1.laptop_name)
output:
dell pavallion

dell inspiron 15 3576

2.Instance method:
code:
#instance or object method 
class person: 
    def __init__(self,first_name,last_name,age):#init object used to construct 
or create our object 
        self.first_name=first_name
        self.last_name=last_name
        self.age=age
    
    def full_name(self):#instance method here there is no need to pass more at
tributes  but only self
        return f"{self.first_name}  {self.last_name}"

p1=person("Ankush","singh",20)
p2=person("Nayan","Arora",20)
print(p1.full_name())
print(p2.first_name)

output:
Ankush singh

Nayan

Exercise: instance method


Code:
class laptop:
    def __init__(self,brand_name,model_name,price):
        self.brand_name = brand_name
        self.model_name = model_name
        self.price = price
        self.laptop_name= brand_name+" "+model_name

    def discount(self,n):
        return self.price- (self.price*n)/100
l1=laptop("dell","inspiron 15 3576",55000)
l2=laptop("hp","pavallion ",89000)
l3=laptop("acer","predator",59000)
print(l1.brand_name,l2.model_name)
print(l1.laptop_name)
print(l2.discount(10))

output:
dell pavallion

dell inspiron 15 3576

80100.0

3.class variable:
code:
#class variable:
#class circle
#area and circumference
class circle:
    pi=3.14#class variables
    def __init__(self,radius):
        self.radius=radius

    def calc_circumference(self):
        return 2*circle.pi*self.radius

c1=circle(4)
c2=circle(3)
print(c1.calc_circumference())
print(c2.calc_circumference())

output:
25.12

18.84

Class variable part 2


code: to give special discount

class laptop:
    discount=10 
    def __init__(self,brand_name,model_name,price):
        self.brand_name = brand_name
        self.model_name = model_name
        self.price = price
        self.laptop_name= brand_name+" "+model_name

    def apply_discount(self):
        discount_price=(self.discount/100)*self.price
        return self.price- discount_price
l1=laptop("dell","inspiron 15 3576",55000)
l2=laptop("hp","pavallion ",89000)
l3=laptop("acer","predator",59000)
l2.discount=20# to give  differnt discount  than class discount on special lap
top we use self.discount

print(l1.brand_name)
print(l1.laptop_name)
print(l1.apply_discount())
print(l2.apply_discount())
#how to know how many variables our object has 
print(l2.__dict__) 

code:
dell

dell inspiron 15 3576

49500.0

71200.0

{'brand_name': 'hp', 'model_name': 'pavallion ', 'price': 89000, 'laptop_name': 'hp pavallion ', 'discount': 20}

Exercise: count the object in class


Code:
#count the instance or object in class
class Person:
    count_instance=0
    def __init__(self,first_name,last_name,age):
        Person.count_instance+=1
        self.first_name=first_name
        self.last_name=last_name
        self.age=age

p1=Person("ankush","singh",20)#when we create object init func. or constructor 
call
#suppose if we create one obejct or instance then 1 time init call , if  3 obj
ect then 3 times call init func.
p2=Person("rohit","singh",24)
p3=Person("mohit","singh",25)
print(Person.count_instance)

output:
3

4.Class method:
Code:
class Person:
    count_instance=0 #class variable or class attributes
    def __init__(self,first_name,last_name,age):#self represent the object
        Person.count_instance+= 1
        self.first_name=first_name
        self.last_name=last_name
        self.age=age

    @classmethod
    def count_instance(cls):
        return f" you have {cls.count_instance} instance of {cls.__name__} cla
ss"

p1=Person("ankush","singh",20)#when we create object init func. or constructor 
call
#suppose if we create one obejct or instance then 1 time init call , if  3 obj
ect then 3 times call init func.
p2=Person("rohit","singh",24)
p3=Person("mohit","singh",25)
print(Person.count_instance())

output:
you have 3 instance of Person class

5 class method as constructor:


Code:
#class method as a constructor
class Person:
    count_instance=0 #class variable or class attributes
    def __init__(self,first_name,last_name,age):#self represent the object
        Person.count_instance+= 1
        self.first_name=first_name
        self.last_name=last_name
        self.age=age
    @classmethod
    def from_string(cls,string):
        first,last,age=string.split(",")
        return cls(first,last,age)

p1=Person("ankush","singh",20)#when we create object init func. or constructor 
call
#suppose if we create one obejct or instance then 1 time init call , if  3 obj
ect then 3 times call init func.
p2=Person("rohit","singh",24)#this is simple to create obejct 
p3=Person("mohit","singh",25)
# suppose if we want to create the object from diiferrnt method
#p3=Person("ankit,singh,29")#from string we use class method as constructor to 
ceate our object
p4=Person.from_string("ankit,singh,29")
print(p4.first_name)

output:

Ankit

6.static method :
Code:
#static method: we use static method decorator 
class Person:
    count_instance=0 #class variable or class attributes
    def __init__(self,first_name,last_name,age):#self represent the object
        Person.count_instance+= 1
        self.first_name=first_name
        self.last_name=last_name
        self.age=age

    @staticmethod
    def hello(): #it have no relation with class but it may have logical relat
ion with class
        return "hello,static method called"

p1=Person("ankush","singh",20)
p2=Person("rohit","singh",24)
p3=Person("mohit","singh",25)
print(Person.hello())

output:
hello,static method called

7.encapsulation,abstraction,naming convention,name mangling:


Code:
#encapsulation:means to encapsulate all the method or function and useful data 
or variables in a single entity or class
class Phone:
    def __init__(self,brand,model_name,price):
        self.brand=brand
        self.model_name=model_name
        self.__price=price

    def full_name(self):
        return f"{self.brand} {self.model_name}"

    def calling(self,phone_number):
        return f"calling {self.brand} {phone_number}"

p1=Phone("redmi","redmi4",10000)
p2=Phone("apple","iphone 10R",80000)

print(p2.calling(9711414984))
#abstraction:
#suppose we have one list and we want to sort that list 
l=[25,6,3,4,7889,977]
l.sort()#we sort using sort function but we dpnt know its implementaton how it
s sort we just sort by sort functions so this is abstraction . Abstraction mea
ns to hiding the real implementation or complexity of any function (like sort,
append )from the user
print(l)
#namingconvention:
#_name like self._price=price# convention of private name(means dont change th
is name in code but it can do because in python all are public)
#__name__#called "dunder"(magic)method
#name mangling: __name(python change the name of this attribute)
#it change and give _classname__attribute name like as we do in price in this 
code
#print(p1._price)#it gives error  give AttributeError: 'Phone' object has no a
ttribute '_price' but we have this attribute .this is done because of name man
gling(python change the name of this attributes)
print(p1.__dict__)
print(p1._Phone__price)

output:
calling apple 9711414984

[3, 4, 6, 25, 977, 7889]


{'brand': 'redmi', 'model_name': 'redmi4', '_Phone__price': 10000}

10000

8.setter and property decorator:

Code:
#setter and property decorator:setter decorator is use just after property dec
orator and from property decorator we can call function as instance varibles 
# some problem 
#1problem: if we give negative price then in output we want 0 because practica
lly -price is not possible we over come this problem by using max func
class Phone:
    def __init__(self,brand,model_name,price):
        self.brand=brand
        self.model_name=model_name
        self._price=max(price,0)
        self.complete_spec=f"{self.brand} {self.model_name} and {self._price}"

    def full_name(self):
        return f"{self.brand} {self.model_name}"

    def calling(self,phone_number):
        return f"calling {self.brand} {phone_number}"

p1=Phone("Xiaomi","redmi4",-10000)
p2=Phone("apple","iphone 10R",80000)
print(p1.brand)
print(p1.model_name)
print(p1._price)
print(p1.complete_spec)

#2nd problem
#if we change the price p1._price=9000 in the above code then we get output th
is
#output
#Xiaomi
#redmi4
#9000 this price change but in complete spec old price is shown this can be fi
x by using instance method or making another function 
#Xiaomi redmi4 and 10000#

class Phone:
    def __init__(self,brand,model_name,price):
        self.brand=brand
        self.model_name=model_name
        self._price=max(price,0)
    
    @property#from property decorator we can call function as instance varible
s
    def complete_spec(self):
        return f"{self.brand} {self.model_name} and {self._price}"
    
    def full_name(self):
        return f"{self.brand} {self.model_name}"

    def calling(self,phone_number):
        return f"calling {self.brand} {phone_number}"

p1=Phone("Xiaomi","redmi4",10000)
p2=Phone("apple","iphone 10R",80000)
print(p1.brand)
print(p1.model_name)
p1._price=1000
print(p1._price)
#print(p1.complete_spec())#but if we want to call complete_spec()function as i
nstance variable we use "property decorator"
print(p1.complete_spec)
#3rd problem
#p1._price=-9000 if we negative price then output is
#Xiaomi
#redmi4
#-9000
#Xiaomi redmi4 and -9000 we can overcome this problem by using "setter decorat
or"
#we use setter decorator to set the price and setter decorator is use just aft
er decorator

class Phone:
    def __init__(self,brand,model_name,price):
        self.brand=brand
        self.model_name=model_name
        self._price=max(price,0)
    
    @property#from property decorator we can call function as instance varible
s
    def complete_spec(self):
        return f"{self.brand} {self.model_name} and {self._price}"
    
    @property
    def price(self):
        return self._price

    @price.setter
    def price(self,new_price):
        self._price=max(new_price,0)

    def full_name(self):
        return f"{self.brand} {self.model_name}"

p1=Phone("Xiaomi","redmi4",10000)
p2=Phone("apple","iphone 10R",80000)
print(p1.brand)
print(p1.model_name)
p1._price=-777
print(p1.price)
print(p1.complete_spec)

Output:
Xiaomi

redmi4

Xiaomi redmi4 and 0

Xiaomi

redmi4

1000

Xiaomi redmi4 and 1000

Xiaomi

redmi4

Xiaomi redmi4 and 0

9.inheritance intro:
Code:
class Phone:#base class/parent class
    def __init__(self,brand_name,model_name,price):
        self.brand_name=brand_name
        self.model_name=model_name
        self.price=max(price,0)

    def full_name(self):
        return f"{self.brand_name}  {self.model_name}"
    
    def make_a_call(self,number):
        return f"calling {number}"
#and we want to make a new have all method of phone class and also have new at
tributes . so for this we will inherit phone class in smart phone class

class Smartphone(Phone):#child class,derived class
    def __init__(self,brand_name,model_name,price,ram,internal_memory,rear_cam
era):
        #Phone.__init__(self,brand_name,model_name,price)#uncommon way
        super().__init__(brand_name,model_name,price)
        self.ram=ram
        self.internal_memory=internal_memory
        self.rear_camera=rear_camera

nokia=Phone("nokia","1100",1200)
samsung=Smartphone("samsung","j2",10000,"4gb","64gb","20 mp")
print(nokia.price)
print(samsung.full_name())
print(samsung.rear_camera)
print(help(Smartphone))

output:
1200

samsung j2

20 mp

Help on class Smartphone in module __main__:

class Smartphone(Phone)

| Smartphone(brand_name, model_name, price, ram, internal_memory, rear_camera)

| Method resolution order:

| Smartphone

| Phone

-- More --

10.multilevel inheritance and method resolution order(mro) :


code:
# we can inherit mpre than ine class frombase class or parent class
#multilevel inheritance" anfmethod resolution order(mro) this is the process b
y which python search our instances variables and method
class Phone:#base class/parent class
    def __init__(self,brand_name,model_name,price):
        self.brand_name=brand_name
        self.model_name=model_name
        self.price=max(price,0)

    def full_name(self):
        return f"{self.brand_name}  {self.model_name}"
    
    def make_a_call(self,number):
        return f"calling {number}"

#and we want to make a new have all method of phone class and also have new at
tributes . so for this we will inherit phone class in smart phone class

class Smartphone(Phone):#child class,derived class
    def __init__(self,brand_name,model_name,price,ram,internal_memory,rear_cam
era):
        #Phone.__init__(self,brand_name,model_name,price)
        super().__init__(brand_name,model_name,price)
        self.ram=ram
        self.internal_memory=internal_memory
        self.rear_camera=rear_camera

class Flagship(Smartphone):
    def __init__(self,brand_name,model_name,price,ram,internal_memory,rear_cam
era,processor,front_camera):
        super().__init__(brand_name,model_name,price,ram,internal_memory,rear_
camera)
        self.front_camera=front_camera
        self.processor=processor

nokia=Phone("nokia","1100",1200)
samsung=Smartphone("samsung","j2",10000,"4gb","64gb","20 mp")
oneplus=Flagship("oneplus","5",45667,"6gb","128gb","44mp","2.1 ghz","18mp")
print(f"processor is {oneplus.processor},front camera is {oneplus.front_camera
}")
print(help(Flagship))#mro 

output:
processor is 2.1 ghz,front camera is 18mp

Help on class Flagship in module __main__:

class Flagship(Smartphone)

| Flagship(brand_name, model_name, price, ram, internal_memory, rear_camera, processor,


front_camera)

| Method resolution order:

| Flagship
| Smartphone

-- More --

12.method overrideing nad built in function ( “insubclass “and “ininstance):


Code: #method over riding and built in function:
# we have full_name method or function in Phone class in this code and if we m
ake one more each in smartphones nd Flagship class and when object of flagship
clas call this full_name then flagship class full_name method is call instead 
of Phone class because first flagship class object check flagship instance var
iable and method because of mro   
class Phone:#base class/parent class
    def __init__(self,brand_name,model_name,price):
        self.brand_name=brand_name
        self.model_name=model_name
        self.price=max(price,0)

    def full_name(self):
        return f"{self.brand_name}  {self.model_name}"
    
    def make_a_call(self,number):
        return f"calling {number}"

#and we want to make a new have all method of phone class and also have new at
tributes . so for this we will inherit phone class in smart phone class

class Smartphone(Phone):#child class,derived class
    def __init__(self,brand_name,model_name,price,ram,internal_memory,rear_cam
era):
        #Phone.__init__(self,brand_name,model_name,price)
        super().__init__(brand_name,model_name,price)
        self.ram=ram
        self.internal_memory=internal_memory
        self.rear_camera=rear_camera

class Flagship(Smartphone):
    def __init__(self,brand_name,model_name,price,ram,internal_memory,rear_cam
era,processor,front_camera):
        super().__init__(brand_name,model_name,price,ram,internal_memory,rear_
camera)
        self.front_camera=front_camera
        self.processor=processor

    def full_name(self): 
        return f"{self.brand_name}  {self.model_name} {self.front_camera} and 
{self.processor}"

nokia=Phone("nokia","1100",1200)
samsung=Smartphone("samsung","j2",10000,"4gb","64gb","20 mp")
oneplus=Flagship("oneplus","5",45667,"6gb","128gb","44mp","2.1 ghz","18mp")
print(oneplus.full_name())
#buit in functio:
#isinstance: it is used when we want to want to any object is belong to this c
lass or not, it gives true or false
print(isinstance(oneplus,Smartphone))#actually this is obect of flagship class 
but it flagship class inherit smartphone and phone class then this object is a
lso of samrtphone and phone class
print(isinstance(samsung,Flagship))#it give false
#is subclass function 
print(issubclass(Smartphone,Flagship))#smartphone class is not subclass of fla
gship but it is a subclass of phone
print(issubclass(Flagship,Smartphone))#flagship is subclass of smartphone and 
phone class then it give true
print(issubclass(Flagship,Phone))

output:

oneplus 5 18mp and 2.1 ghz

True

False

False

True

True

13.multilple inheritance:
code:
#multiple inheritance
class A:
    def  class_a_method(self):
        return " i am just a class A method"

    def hello(self):
        return " hello from class A"

class B:
    def class_b_method(self):
        return " i am just a class B method"

    def hello(self):
        return " hello from class B"

class C(A,B):# class C have all method and attributes of class A and class B
    pass

#how to create instance or object of class A and B
instance_a=A()
instance_c=C()
print(instance_c.class_a_method())
print(instance_c.class_b_method())
print(instance_c.hello())#it call class A hello instead of class B because of 
mro if we write C(B,A) then class b hello print because it will first check cl
ass C then class B instance variable and method then if it didnot find in clas
sB then it will go in class A due to mro.
print(help(C)) 
#print(C.mro())
#print(C.__mro__)

output:

i am just a class A method

i am just a class B method

hello from class A

Help on class C in module __main__:

class C(A, B)

| Method resolution order:

| C

| A

| B

| builtins.object

-- More --

14. Specialmagic methods/dunder method:


code:#repr and str used one at a time
#dunder method:it is start with __method name__ like a init method
#__str__:string  and it is commonly used ,__repr__: representation and it is m
ostly used by developer and it return something wich is object . So if you wan
t to print the object through netho used repr method and if we both use simult
aneously then str callinstead of repr.
#  __len__:length
class Phone:
    def __init__(self,brand,model_name,price):
        self.brand=brand
        self.model_name=model_name
        self.__price=price

    def phone_name(self):
        return f"{ self.brand} {self.model_name}"

        #str,repr
    def __str__(self):
        return f"{self.brand} {self.__price} {self.model_name}"
   # def __repr__(self):
       # return f"{self.brand} {self.__price} {self.model_name}"

my_phone=Phone("nokia","1100",1000)
print(my_phone)
# we can call it repr and str like a function
print(str(my_phone))
#print(repr(my_phone))

output:
nokia 1000 1100
nokia 1000 1100
code: when both str and repr used simultaneously then in output we get return of str
function if we write print(my_phone)
#dunder method:it is start with __method name__ like a init method
#__str__:string  and it is commonly used ,__repr__: representation and it is m
ostly used by developer and it return something wich is object . So if you wan
t to print the object through netho used repr method and if we both use simult
aneously then str callinstead of repr.
#  __len__:length
class Phone:
    def __init__(self,brand,model_name,price):
        self.brand=brand
        self.model_name=model_name
        self.__price=price

    def phone_name(self):
        return f"{ self.brand} {self.model_name}"

        #str,repr
    def __str__(self):#for normal user
        return f"{self.brand} {self.__price}"
    
    def __repr__(self):#for developer to do debuugging
        return f"Phone (\"{self.brand}\" {self.__price} \"{self.model_name}\")
"
    
    def __len__(self):
        #return len(self.model_name) or return len(price) it give error
        return len(self.__repr__())# we meausre only length of method or funct
ion not unstance variable in init method

my_phone=Phone("nokia","1100",1000)
print(my_phone)#str is call when we both use str and repr
# we can call it repr and str like a function
print(str(my_phone))
print(repr(my_phone))#if we copy the output of repr then it give object
print(len(my_phone))
output:
nokia 1000

nokia 1000

Phone ("nokia" 1000 "1100")

27

14.operatoroverloading:

code:
#operator overloading and polymorphism

class Phone:
    def __init__(self,brand,model_name,price):
        self.brand=brand
        self.model_name=model_name
        self.price=price

    def __add__(self,other):#self for 1st phone and other for 2nd phone
        return self.price + other.price

my_phone=Phone("nokia","1100",1000)
my_phone2=Phone("nokia","1200",1400)
#suppose if we want to add ,multiply ,sub and more thing the price of both pho
ne ant this is done by using operator overloading
print(my_phone+my_phone2)

output:
2400

Polymorphism: means many form like :


2+3=5
“abc”+”def’=”abcdef” then = + operator have many form if we use it in integer then it add integer anf if we
use it on string it concatenate the string so +operator show polyphormism

Operator overloading and method overriding is a ex of polymorphosm

You might also like