Introduction to python 04 -- object oriented, linked list, exception handling

Posted by velkymx on Thu, 13 Jan 2022 14:49:49 +0100

object-oriented

The core of process oriented programming is the process (pipeline thinking). The advantage is to develop along the execution steps, and the disadvantage is to move the whole body

Object oriented OOP is a program idea, which takes the object as the basic unit of the program, and an object contains data and a method of operating data

class

A collection of objects that describe the same properties and methods

class Class name():# Class names are generally capitalized
    pass

Instance variables and class variables

Defined in_ init_ _ Variables within are called instance variables

class Animal():
    # Construction method, which is automatically called when creating an object
    def __init__(self, name, age):
        # Instance variable
        self.name = name
        self.age = age
        print('xxx')


dog1 = Animal('dog1', 1)  # Animal() actually calls the init method
print(dog1.name, dog1.age)
dog2 = Animal('dog2', 2)
print(dog2.name, dog2.age)

Class variable, modify class variable and access class variable through class name

class Student:
    classroom = '101'  # Class variable
    address = 'anhui'

    def __init__(self, name, age):
        # Instance variable
        self.name = name
        self.age = age

    def print_age(self):
        print('%s %s' % (self.name, self.age))


student = Student('xiao', 22)
print(Student.address)

self

self represents the reference of the object that calls the method

class Student:
    classroom = '101'  # Class variable
    address = 'anhui'

    def __init__(self, name, age):
        # Instance variable
        print(self)
        self.name = name
        self.age = age

    def print_age(self):
        print('%s %s' % (self.name, self.age))

    def study(self, course):
        print(self) # self is the caller of the current study
        print('I'm studying%s' % course)
        self.func() # self represents an instance object

    def func(self):
        print('func')


student1 = Student('xiao', 22)
student2 = Student('xiao', 22)
print(student1)
student1.study('Algebra')


# self will be different in different positions, and so will the relative value and cls
class Father():
    def get_some(self):
        print(self)


class Son(Father):
    pass


f = Father()
f.get_some()
s = Son()
s.get_some()

result:
<__main__.Father object at 0x0000025CE655C548>
<__main__.Son object at 0x0000025CE655C348>

Class method

Class method

# Class is called by class, decorated with classmethod, and at least one CLS (similar to self) parameter is passed in
# Like class variables, class methods are shared
class Studnet():
    def __init__(self):
        pass

    @classmethod  # Decorator
    def c_func(cls):
        print('Class method',cls)


print(Studnet)
Studnet.c_func()

# Can instance methods and instance variables be called in class methods?
No, because instance variables and instance methods can only be accessed through the object name, but there is no object name inside the class method
# Can class methods and class variables be called in instance methods

Static method

# It does not belong to an instance or a class. It is just a common method defined in the class and modified by staticmethod
class Studnet():
    def __init__(self):
        pass

    def study(self):  # Example method
        self.c_func()
        print('Learn to die if you can't learn')

    @classmethod  # Decorator
    def c_func(cls):
        # cls.study(cls)
        print('Class method', cls)

    @staticmethod
    def func():
        print('static state')


print(Studnet)
Studnet().study()
Studnet.c_func()
Studnet.func()

Object association

1. Pass an object of one class as a method of another class

2. Take the object of a class as another default parameter (_ init _)

Encapsulation, inheritance, polymorphism

python is not polymorphic. Encapsulation is the implementation of a class. Methods and attributes are placed in the class

The object-oriented features are similar to java. Inheritance: the inherited is the parent class and the inherited is the subclass. The subclass can obtain all the variables and methods of the parent class and realize method reuse

class Father():  # Parent class
    address = 'NJ'

    def __init__(self):
        self.var = 'xxx'
        print('Parent class construction method')

    def hobby(self):
        print("go to the gym")

    @classmethod
    def class_method(cls):
        print('father Class method')

    @staticmethod
    def static_method():
        print('father Static method')


class Son(Father):  # Subclass
    pass


son = Son()
print(son.var)  # The child class inherits the parent class instance variable
son.hobby()  # Subclasses can inherit parent class instance methods
print(son.address)  # Subclasses can inherit class variables from the parent class
son.class_method()  # Subclasses can inherit the class methods of the parent class
son.static_method()  # Subclasses can inherit the static methods of the parent class


result:
Parent class construction method
xxx
 go to the gym
NJ
father Class method
father Static method

derive

class Father():
    def hobby(self):
        print('go to the gym')


class Son(Father):
    def hobby(self):  # No partial rewrite is a complete rewrite
        super().hobby()  # Partial rewrite
        print("Roll code")


s = Son()
s.hobby()

Multi parent class

# There is inheritance priority, the higher the priority
class Father1():
    def hobby(self):
        print('Brother Lu Tie1')


class Father2():
    def hobby(self):
        print('Brother Lu Tie2')


class Son(Father1, Father2):
    def hobby(self):
        super().hobby()
        print("Roll code")


son = Son()
son.hobby()

result:
Brother Lu Tie1
 Roll code

type and isinstance

# Type has been used before and will not be repeated. It is the type of the returned object
# Differences between isinstance and type:
# Type does not consider a subclass as a parent type, and does not consider inheritance
# isinstance will think that the subclass is a parent type and consider the inheritance relationship
print(isinstance(son, int)) //False
print(isinstance(son, Son)) //True
print(isinstance(son, Father1)) //True

new method and self

Think about where the value of the parameter self comes from?

class stu():
    def __init__(self):
        print('init method')
    
    # Override the method of the parent class
    def __new__(self):
        print('new method')

s = stu() # Objects are not created, only output__ new__ Medium method
# Note that after you create an object in python, it is called automatically___ init__ Method assigns attributes to the object. If the init method is not called, the object creation fails
class stu():
    def __init__(self):
        print('init method')
    
    # Override the method of the parent class
    def __new__(self): 
        print('new method')
        # The first parameter self of all instance methods is returned
        return super().__new__(self) # self assignment

s = stu() # Object created successfully

# example
class Classroom(object):
    count = 0

    @classmethod
    def show_count(cls):
        print("The current number is%s" % cls.count)

    @classmethod
    def add_count(cls):
        cls.count += 1

    def __new__(cls, *args, **kwargs):
        Classroom.add_count()  # cls cannot be used, in which case the subclass itself is used
        return super().__new__(cls)

class Student(Classroom):
    pass

s1 = Student()
s2 = Student()
s3 = Student()
Classroom.show_count()

Results: the current number is 3

Member protection and access restrictions

In fact, in inheritance, subclasses can inherit all methods and variables of the parent class. python does not have the so-called public, private and protection, but it can simulate private

Two underscores are private

Mandatory access, underscore + class name + private member

reflex

class Teacher():
    age = 22

    def __init__(self):
        self.name = 'xiao'

    def study(self):
        print('study')


r1 = hasattr(Teacher, 'age')  # Judge whether the member variable / method exists in this class
print(r1) # True

t = Teacher()
r2 = getattr(Teacher, 'study')  # Get the member variables / methods of this class
r2(t) # study

Singleton mode

Normally, a new space will be opened up without creating an object, so the key is that the new method is to change

class Singleton():

    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, 'instance'):
            # cls.instance refers to itself, but the subclass is not a singleton
            # Class name instance is a specially specified class, so subclasses are also singletons
            Singleton.instance = super().__new__(cls)
        return Singleton.instance


class Sig(Singleton):
    pass


s1 = Singleton()
s2 = Singleton()
print(id(s1), id(s2))

ss1 = Sig()
ss2 = Sig()
print(id(ss1), id(ss2))

Linked list

Pay attention to the idea. To generate a data structure such as a linked list, you need to build nodes one by one. Each node needs to have its own value (item) and next pointing to the next node

How to insert a node? First, when creating a node, we must have a head, obtain a node, and take the obtained node as the head node, thus forming head - > node1 (item, next)

Next, how to insert the second node? At this time, obtain a node again, point the next of the obtained node to the previous node, and then insert the obtained node as the head node

For traversal, first of all, we know that if the head can be moved, each moving bit points to a node, but the head cannot be moved, and the previous node will be recycled after moving

Therefore, assign head to a variable instead of head to move and output

For blank judgment, it is to judge the direction of the header node

...

class Node:
    def __init__(self, item):
        self.item = item
        self.next = None


class Link:
    def __init__(self):
        self.head = None  # Point to the first node

    def addHead(self, item):
        """
        Insert node
        :param item:
        :return:
        """
        node = Node(item)  # Get a node
        node.next = self.head  # Point the next of the obtained node to the previous node
        self.head = node  # Take the obtained node as the head node

    def travel(self):
        """
        Traversal node
        :return:
        """
        cur = self.head
        while cur is not None:
            print(cur.item)
            cur = cur.next

    def isEmpty(self):
        """
        Linked list space determination
        :return:
        """
        return self.head is None

    def length(self):
        """
        Length of linked list
        :return:
        """
        count = 0  # Record the number of nodes
        cur = self.head
        while cur is not None:
            count += 1
            cur = cur.next
        return count

    def insertNode(self, item, pos):
        """
        New node insertion pos Location
        :param item:
        :param pos:
        :return:
        """
        node = Node(item)
        cur = self.head
        pre = None
        if pos == 0:
            self.head = node
            node.next = cur
            return
        for i in range(pos):
            pre = cur
            cur = cur.next

        pre.next = node
        node.next = cur

    def removeNode(self, item):
        """
        Delete from linked list item Represented node
        :param item:
        :return:
        """
        cur = self.head
        pre = None
        if self.head.item is item:  # Delete first node
            self.head = cur.next
            return
        while cur is not None:
            if cur.item is item:
                pre.next = cur.next
                return
            else:
                pre = cur
                cur = cur.next

    def append(self, item):
        """
        Add a new node to the end of the linked list
        :param item:
        :return:
        """
        node = Node(item)
        if self.isEmpty():  # Judge whether it is empty. If it is empty, it is directly used as the header node
            self.head = node
        else:
            pre = None  # pre points to a node in front of cur
            cur = self.head
            while cur is not None:
                pre = cur
                cur = cur.next
            pre.next = node


link = Link()
link.addHead(1)
link.addHead(2)
link.addHead(3)
link.addHead(4)
link.addHead(5)
link.travel()
print(link.isEmpty())
print(link.length())
print("======" * 10)
link.append(6)
link.travel()
print("======" * 10)
link.insertNode('xxx', 0)
link.travel()
print("======" * 10)
link.removeNode('xxx')
link.travel()

exception handling

The exception code will not be processed later. try can be followed by multiple exceptions

print('start')
try:
    1 / 0
except ZeroDivisionError as i:
    print(i)

print('end')

Actively throw exception: raise

sex = int(input('please input a number: '))
try:
    if sex == 1:
        print('xx')
    elif sex == 0:
        print('yy')
    else:
        print('zz')
        raise ValueError('illegal input')
except ValueError:
    print('xx')

Topics: Python linked list