Object oriented programming OOP

Python class

  • Inheritance: Inherits common attributes of the top-level class and implements them once in common cases to improve code reuse
  • Composition: composed of multiple component objects, through the cooperation of multiple objects to complete the corresponding instructions, each component can be written as a class to define its own properties and behavior
  • Difference from modules: Modules have only one instance in memory and can only be overloaded to get their latest code, whereas classes have multiple instances

Specific features of Python classes

  • Multiple instances
    • Classes are factories that produce object instances
    • Each time a class is called, a new object with its own namespace is created
    • Each object stores different data
  • Customize through inheritance
    • Redefine its properties outside of a class
    • Create a hierarchy of namespaces to define variable names used by objects created by the class
  • Operator overloading
    • Objects can be defined to respond to several operations on built-in types, depending on providing specific protocol methods

Python multiple instances

  • S1: Define class templates and create instance objects
## person.py
## Define the class template
class Person:
    Any argument in a Python function after the default first argument must have a default value
    def __init__(self,name,job=None,pay=0):
        self.name = name
        self.job = job
        self.pay = pay

    def __str__(self):
        return "the name[%s] - the job[%s] - the pay[%d]" % (self.name,self.job,self.pay)

Create an instance and test it
tom = Person("tom")
jack = Person("jack",job="market",pay=20)
print(tom)
print(jack)

>>> python person.py
the name[tom] - the job[None] - the pay[0]
the name[jack] - the job[market] - the pay[20]

# # summary:
1Default values and keyword arguments are used to create the instance2Tom and Jack technically belong to different object namespaces and each has a separate copy of the class created3Other Python files will also be importedprintInformation is also outputChange the location of the test code and add the following code at the bottom of the file
if __name__ == '__main__':
    tom = Person("tom")
    jack = Person("jack",job="market",pay=20)
    print(toml)
    print(jackl)

>>> python person.py
the name[toml] - the job[None] - the pay[0]
the name[jackl] - the job[market] - the pay[20]

>>> import person
## No outputCopy the code
  • S2: Add behavior methods
## Python OOP programming should also follow the nature of encapsulation, i.e. detail hiding, external access methods

Get last name in a non-OOP way
print(jack.name.split()[- 1])

The rule of OOP is to add methods
class Person:.def getLastName(self):
        return self.name.split()[- 1]

## External call
print(jack.getLastName()Copy the code
  • S3: Operator overloading
The above test instance object needs to call the corresponding property name to print out each time, overriding the __str__ method to display information about an object property
class Person:.def __str__(self):
        list = []
        for k,v in self.__dict__.items():       Get the property information of the instance object dynamically, instead of hardcoding the property names and values directly
            list.append("%s -- %s" % (k,v))
        str =  ",".join(list)
        return "Person[%s]" % str

Print out all object properties above
>>> print(tom)
Person[pay -- 0,name -- tom,job -- None]Copy the code
  • S4: Customize behavior by subclass
## Extend the parent method, not rewrite or modify the parent method
class Person:.def giveRaise(self,percent):
        self.pay = self.pay * (1 + percent)

class Manager(Person):
     def giveRaise(self,percent,bouns=10.):
        ## Call the method of the class and pass in the self argument
        Person.giveRaise(self,percent + bouns)      

For Python, the parent method is usually called through the class. Methods (self,parameters) to display the call, like in other programming languages such as Java, call the parent class through super. Method to display the call, that's the difference

# # polymorphism
p1 = Person("p1",job="dev",pay=11000)
p2 = Manager("p2",job="dev",pay=11000)
>>> print(p1.giveRaise(10.))        
>>> print(p2.giveRaise(10.))
Person[name -- p1,job -- dev,pay -- 12100.000000000002]
Person[name -- p2,job -- dev,pay -- 13200.0]

# # summary:
1Python's polymorphism differs slightly from that of other programming languages in that it overwrites the corresponding method of the top-level class as long as the method name is the same, regardless of the number or type of arguments2The reason is that Python's properties and behavior are traversed by the search tree to get the most recent property or method3Python parameter types are known at assignment time; there are no predefined typesCopy the code
  • S5: Custom constructors
Customize the Manager class to make it specialized
class Manager(Person):
    def __init__(self,name,pay = 0):
        Person.__init__(self,name,job = "manager",pay = pay)

>>> tom = Manager("tomk",pay=11000)
>>> print(tom)
Person[pay -- 13200.0,name -- tomk,job -- manager]Copy the code
  • S6: Use introspective tools (similar to “reflection” in other programming languages)

    • Problem description 1: The Manager prints the information displayed as Person, and then should actually display the information for the Manager
    • Problem description 2: If the Manager adds properties to init, it will not be able to display the new properties from the printed information if it is hard coded
## Solution to Problem 1: The link between an instance object and the class that created it via the instance.__class__ property, in turn, provides access to the superclass via a __name__ or __bases__ sequence p1 = Person(" P1 ",job="dev",pay=11000) p2 = Manager("p2",pay=11000) >>> print(p1.__class__.__name__) Person >>> print(p1.__class__.__bases__) (<class 'object'>,) > > > print (p2) magic __class__) __name__) Manager > > > print (p2) magic __class__) __bases__) (< class '__main__. A Person' >,) problem # # 2 solutions: >>> print(p1) person [job -- dev,name -- p1,pay P1.age = 10 p1.maths = "maths" >>> print(p1) Person[pay -- 11000,hobby -- maths,age -- 10,job -- Class Person: def get_all_attrs(self): attrs = [] for key,value in self.__dict__.items(): attrs.append("%s==%s" % (key,value)) return ",".join(attrs) def __str__(self): return "%s[%s]" % (self.__class__.__name__,self.get_all_attrs()) >>> print(p1) Person[hobby==maths,name==p1,job==dev,pay==11000,age==10] >>> print(p2) Manager[name==p2,pay==11000,job==manager] ## Display all properties of class and instance objects using dir method >>> dir(p2) ## Too long without copyCopy the code
  • S7: Object persistence
    • Pickle: Serialization between arbitrary Python objects and bytes
    • DBM: Implements a key-accessible file system to store strings
    • Shelve: Use the above two modules to store Python objects in a file, that is, the key to store pickled objects in a DBM file
## pickle

Serialize the object to a file

f1 = open("pickle.db","wb+")

Dump (p1,f1) ## Open ("pickle.db","wb+") will cause pickles to throw an EOFError: Ran out of input

f1.close()



Serialize the object to a string

string = pickle.dumps(p1)



## Read from file

f = open("pickle.db","rb")

p = pickle.load(f)



## Reads from a string

p_obj = pickle.loads(string)



## dbm

# # storage

db = dbm.open("dbm","c")

db[k1] = v1

db.close()



# # to read

db = dbm.open("dbm","c")

for key in db.keys():

    print("key[%s] -- %s" % (key,db[key]))



## shelve

import shelve

db = shelve.open("persondb")    ## filename

for object in [p1,p2]:

    db[object.name] = object

Db.close () ## must be closed



Read from db file

Db = shelve.open(" personDB ") ## DB has the same methods as dictionaries, except that shelve needs to be opened and closed

for key in db.keys():

    print("from db[%s]" % db[key])Copy the code

Python overloads operators

  • Double underline naming method (__X__) is a special hook
  • Such methods are called automatically when an instance appears in a built-in operation
  • Class overrides most operations of built-in types
  • Operator override methods do not have a default and are not required
  • Operators allow classes to integrate with Python’s object model items
Overloading class built-in methods, usually applied to math class objects to calculate the need to overload the operator
class OverrideClass(ClassObject):
    def __init__(self,data):
        self.data = data

    def __add__(self, other):
        return OverrideClass(self.data + other)

    def __str__(self):
        return "[OverrideClass.data[%s]]" % self.data

    def mul(self,other):
        self.data *= other

# # call
t = OverrideClass("9090")     ## Calls the __init__ method
t2 = t+"234"                  ## calls the __add__ method, which generates the new object
print t2                      ## Calls the __str__ method

t2.mul(3)
print(t2.data)Copy the code

Python attribute inheritance search,object.attribute

  • Find the first instance object of the attribute
  • And then all the classes above that object__init__The attributes defined in the method search for attributes, from bottom to top, left to right, which belong to the inherited search tree
  • Finally, the class attributes of the object are defined, and the search method is also a bottom-up, left-to-right traversal search

Write the kind of tree

  • Each class statement generates a new class object
  • Each time the class is invoked, a new instance object is generated
  • The instance object is automatically connected to the class that created it
  • The way a class is connected to a superclass, listing the superclass in parentheses in the class’s header. The order from left to right determines the order in the tree
Name = "M1 name" print("M1 class") class M2: def __init__(self): self.name = "m2 name" print("M2 class") class M3(M1,M2): pass class M4(M2,M1): >>> a = M3() >>> print(a.name) M1 class M1 name # search tree: M4 M2 M1 >>> b = M4() >>> print(b.name) M2 class name ## a.name First look up the properties of the current instance object, which are defined in a special __init__ method, 1.1 therefore looks for the recently defined __init__ method from the search tree M3 -> M1 -> M2. 1.2 Returns if the __init__ method has a defined attribute name, otherwise proceed to the next step of lookup 2. If it is not found in the object attribute, the value of the attribute will be searched from the search tree of the class, i.e. M3 -> M1 -> M2. 2.1 If it is not found, an exception will be thrownCopy the code

Python OOP summary

  • Instance creation – Populates the properties of the instance
  • Behavior methods – Encapsulate logic in class methods
  • Operator overloading — custom behavior that provides its own built-in methods for externally called programs
  • Custom behavior – Redefine subclass methods to specialize them
  • Custom constructors – Add constructor logic specialization for subclasses

If you like, you can follow my personal public account and continue to share engineer technology daily