Advanced Python Programming for Faceted objects (inheritance, polymorphism, privatization, exception catching, class attributes, and class methods

1. The single inheritance

## Encapsulation, inheritance, and polymorphism
# # 1. Encapsulation
1Content is encapsulated in one place, another place to call the encapsulated content2, use the initialization constructor, or use self to get wrapped content
# # 2. Inheritance Subclasses inherit the properties and content of their parent classCopy the code

1.1 Example of Single Inheritance

class Animal:
    def eat(self):
        print('Dinner time')
        pass

 def drink(self):  print('Drink water')  pass   class Dog(Animal):  def wwj(self):  ## Subclass-specific implementation  print('The little dog barks.')  pass  class Cat(Animal):  def mmj(self):  ## Subclass-specific implementation  print('Kitty meows')  pass  d1 = Dog() d1.eat()  d2 = Cat() d2.eat()  Conclusion: Object-oriented inheritance can greatly improve efficiency and reduce repetitive code Copy the code

2. Multiple inheritance

class Shenxian:
    def fly(self):
        print('Gods can fly')
    pass

class Monkey:  def chitao(self):  print('Monkeys like to eat peaches')  pass  class Sunwukong(Shenxian,Monkey):  pass  swk = Sunwukong() swk.fly() swk.chitao()  Copy the code

2.1 Note that methods have the same name:

If multiple parent classes have the same method, which one should be called
class D(object):
    def eat(self):
        print('D.eat')
    pass
 class C(object):  def eat(self):  print('C.eat')  pass   class B(D):  pass  class A(B,C):  pass  a = A() a.eat print(A.__mro__) ## Displays the class inheritance order <class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class 'object'> The order of execution should be toALook inside, look for the first parent,AIf not, goBFind,,BClass does not have,CNot in the class. GoDClass to find;Copy the code

2.2 Succinct inheritance of cases

class Grandfather(a):
    def eat(self):
        print('The way to eat')
        pass
    pass
 class Father(Grandfather):  pass  class Son(Father):  pass  son = Son() print(Son.__mro__)  ## <class '__main__.Son'>, ## <class '__main__.Father'>, ## <class '__main__.Grandfather'>, ## <class 'object'>  Copy the code

2.3 Override superclass methods

class Grandfather(a):
    def eat(self):
        print('The way to eat')
        pass
    pass
 class Father(Grandfather):  ## overrides the parent method  def eat(self):  print('Dad always eats seafood')  pass  class Son(Father):  pass  son = Son() print(Son.__mro__)  ## Define the same methods as the parent class, which can be implemented to override and override the parent class Copy the code

2.4 Override initialization methods

class Grandfather(a):
    def __init__(self,name):
        self.name = name
        pass
    def eat(self):
 print('The way to eat')  pass  pass  class Father(Grandfather):  def __init__(self):  pass  ## overrides the parent method  def eat(self):  print('Dad always eats seafood')  pass  class Son(Father):  pass  son = Son() print(Son.__mro__) Copy the code

2.5 Calling the parent class initialization method

class Father:
    def __init__(self,name):
        self.name = name
        pass

 ## overrides the parent method  def eat(self):  print('Dad always eats seafood')  pass  class Son(Father):  def __init__(self,name):  Father.__init__(self,name) ## Call the method of the parent class, which can have the name attribute  # # or  ## super.__init__(name) ## can also be written like this  self.age = 90 ## Add new instance methods  self.sex = 'male'  pass  pass  son = Son('hello')  Copy the code

2.6 Calling methods of the parent Class

class Father:
    def __init__(self,name):
        self.name = name
        pass

 ## overrides the parent method  def eat(self):  print('Parent eating method')  pass  class Son(Father):  def __init__(self,name):  Father.__init__(self,name) ## Call the method of the parent class, which can have the name attribute  # # or  ## super.__init__(name) ## can also be written like this  self.age = 90 ## Add new instance methods  self.sex = 'male'  pass  pass   def __str__(self):  print('{}'.format(self.name))  pass   def eat(self):  super().eat() Call the method of the parent class  print('Subclass eating method')  pass  son = Son('Jayne hide and hide') son.eat()  ## Eating method of the parent class ## Subclass eating method Copy the code

3 polymorphic

The same behavior can be implemented differently for different subclasses

3.1 In order to achieve polymorphism, there must be two premises

1. Inheritance: Occurs between parent and child classes

Override: A subclass overrides a method of its parent class

3.1 Case Demonstration

class Animal:
    Basic class # #
    def say(self):
        print('Animal')
        pass
 pass  class Duck(Animal):  ## Subclasses derive classes  def say(self):  print('Ducks')  pass  pass  class Dog(Animal):  ## Subclasses derive classes  def say(self):  print('Puppies')  pass  pass  ## duck1 = Duck() ## duck1.say()  ## dog = Dog() ## dog.say()   def commonIvoke(obj):  ## unified call  obj.say()  ## loop unified call listObj = [Duck(),Dog()] for item in listObj:  commonIvoke(item)  ## When the type of the definition is different from that of the call, it is called polymorphic. Copy the code

3.2 Benefits of polymorphism

1. Increase the flexibility of the program

2. Increase the extensibility of the program

4. Class attributes and instance attributes

## Class properties: Properties owned by class objects, which are shared by all instance objects of class objects and accessible to both.
## Instance properties: Properties owned by instance objects that can only be accessed by instance objects.

class Student:
    # # class attribute
 name = 'Tell me Jayne to hide.'  def __init__(self,age):  self.age = age  pass  pass  lm = Student(18)  Access class attributes through instance objects print(lm.name) print(lm.age)  Access through class objects print(Student.name) print(Student.age)  # # to summarize ## Class properties: Both class objects and instance objects are accessible ## Instance properties: Can only be accessed by instance properties  All instance objects point to the same class of objects ## Instance object to modify class attributes cannot be modified Class objects can be modified. Class attributes can be modified  Copy the code

Class attributes and static methods

## Decorator @classmethod
class Person:
    country = 'china'

    Class methods are qualified with classMethod
 @classmethod  def get_country(cls):  return cls.country ## Access class attributes  pass  @classmethod  def change_country(cls):  cls.country = 'America'  pass  ## Reference by class object print(Person.get_country()) print(Person.change_country()) print(Person.get_country()) Copy the code

5.1 Static Methods

class Person:
    country = 'china'

    Class methods are qualified with classMethod
 @classmethod
 def get_country(cls):  return cls.country ## Access class attributes  pass  @classmethod  def change_country(cls):  cls.country = 'America'  pass  @staticmethod  def get_data(a):  return Person.country  pass  ## Reference by class object print(Person.get_country()) print(Person.change_country()) print(Person.get_country()) print(Person.get_data()) Copy the code

Static methods are not normally accessed through instance objects

Because static methods primarily store logical methods, they have no interaction with classes and instances, that is, they do not involve the operation of methods and properties in a class

Efficient use of resources

5.2 Finding the current system time

import time
class sys_time:
    def __init__(self,hour,min,second):
        self.hour = hour
        self.min  =min
 self.second = second   @staticmethod  ## Standalone features  def show_time(a):  return time.strftime('%H:%M:%S',time.localtime()) print(sys_time.show_time()) # # 15:15:44  Copy the code

5.3 summarize

1. The first argument to a class method is the class object, and CLS references the properties and methods of the class object

2. The first parameter of the instance method is the instance attribute. If the same instance attribute or method exists, the instance attribute has the highest priority

3. Static methods do not need additional parameters, if need to reference attributes. Can be referenced by a class object or an instance object. You must use the @staticMethod decorator

Privatization of 6.

6.1 Privatization Attributes

## Private attributes start with __ and are declared private and cannot be used or accessed directly outside the class.

class Person(object):
    def __init__(self):
        self.__name = 'Tell me Jayne to hide.' # # privatisation
 self.age = '21'  pass  def __str__(self):  return The age of '{} is {}'.format(self.__name,self.age)  person = Person() ## print(person.__name) ## print(person) ## Can be accessed ## Call me Jen hide hide age is 21  ## Private property, cannot be inherited by subclasses Copy the code

6.2 Privatization Methods

class A(object):
    def __eat(self):
        print('eat')
        pass
    pass
  def run(self):  print('running')  pass  pass  b = A() b.__eat() # # error b.run() # # running Copy the code

7. The property method

Attribute function

class A(object):
    def __init__(self):
        self.__name = 18

    def __eat(self):
 return self.__name  pass  pass   def run(self):  print('running')  pass  pass   age = property(__eat, run)   b = A() print(b.age) # # error b.run() # # running Copy the code

7.1 @age.setter ## Modify the property

class A(object):
    def __init__(self):
        self.__name = 18

    def __eat(self):
 return self.__name  pass  pass   def run(self):  print('running')  pass  @property ## Add attribute identifier  def age(self):  return self.__name  pass  @age. Setter ## modify property  def age(self,params):  self.age = params  pass  pass  p1 = A() print(p1.age) # # 18 p1.age = 16 print(p1.age) Copy the code

8. __new__ method

Creates and returns an instance object, if __new__ is called only once. New is the magic method that inherits from object’s new class.

8.1 Precautions

 1.__new__ is the first method of an instantiation call 2.__new__ must have at least one argument, CLS, which represents the class to be instantiated. This argument is provided by the Python interpreter at instantiation time, and the other arguments are passed directly to the __init__ method 3.__new__ determines whether to use this __init__ method, because __new__ can call the constructor of another class or return an instance object as an instance of the class. If __new__ does not return an instance, __init__ will not be called 4.In the __init__ method, you cannot call your own __new__ method,returnCls__new__ (CLS), otherwise an error is reported.Copy the code
class A(object):
    def __init__(self):
        print('__init__ executed ')
        pass
    pass
  def __new__(cls,*args,**kwargs):  return super().__new__(cls,*args,**kwargs)  pass  pass  a = A() print(a)  __init__ performed<__main__.A object at 0x00000291F97D5160>  __init__ is only displayed when __new__ is returned Copy the code

9. Singleton mode

9.1 To ensure that only one instance of a class exists, use __new__

class DataBaseClass(object):
    def __new__(cls,*args,**kwargs):
        ## cls._instance = cls.__new__(CLS) ## Cannot use its own new method
        if not hasattr(cls,'_instance') :            cls._instance = super().__new__(cls,*args,**kwargs)
 return cls._instance  pass  pass  db1 = DataBaseClass() db2 = DataBaseClass() db3 = DataBaseClass() print(id(db1)) print(id(db2)) print(id(db3))  All three points to the same memory address # # 1852298514784 # # 1852298514784 # # 1852298514784  Copy the code

10 Error and exception handling

try:
    ## A block of code that can go wrong
except:
     ## Code block executed after error
else:
 ## No error code block finally:  ## Execute with or without errors Copy the code

10.1 Error and Exception Handling Examples

try:
    ## A block of code that can go wrong
    li = [1.2.3]
    ## print(li[10])
    print(1/0)
 except IndexError as msg:  ## Code block executed after error  print(msg)  except ZeroDivisionError as msg:  ## Code block executed after error  print(msg)  else:  ## No error code block  print('There is no mistake.') finally:  ## Execute with or without errors  print('Wrong')   Multiple different types of exceptions can be caught with a single try Copy the code

10.2 Handling all Errors with Exception

try:
    print(b)
except Exception as result:
    print(result)
else:
 print('Wrong') finally:  print('Wrong')  Copy the code

10.3 Capture at the appropriate level

def A(s):
    return s/int(s)
    pass


def B(s):  return A(s)/2  pass   def main(a):  try:  B(0)  except Exception as result:  print(result)  main() Copy the code

Catch errors in the right places

division by zero

10.4 Abnormal Operating Mechanism

1The interpreter looks for the appropriate exception catching type2, continuously passed to the upper layer, no exception handling is found, will exitCopy the code

11. Customize the exception type

class ToolongException(Exception):
    def __init__(self, len):
        self.len = len

    def __str__(self):
 return 'The length of the input is'+str(self.len)+'Length. I'm out of length.'  def name_test(a):  name = input('Enter a name')  try:  if len(name)>5:  raise ToolongException(len(name))  else:  print(name)  except ToolongException as result:  print(result)  else:  print('There is no mistake.')   name_test()  The input length of ## is 13 lengths, exceeding the length  Copy the code

12 Add attributes and methods dynamically


import types

class Student:
    def __init__(self, name, age):
 self.name = name  self.age = age  pass  pass   def __str__(self):  return '{} turns {} today '.format(self.name, self.age)  pass  pass   zhz = Student('Jayne hide and hide'.25) zhz.wight = 60   def dymicMethod(self):  print('{} weight is {}'.format(self.name,self.wight))  pass  ## Add attributes dynamically print(zhz.wight)  ## Class adds attributes Student.pro = 'Computer Science' ## Instances are accessible print(zhz.pro)  ## Dynamically add instance method ## import types zhz.printInfo = types.MethodType(dymicMethod,zhz) zhz.printInfo()  ## Jayne weighs 60  Copy the code

Dynamically bind class methods

import types

class Student:
    def __init__(self, name, age):
        self.name = name
 self.age = age  pass  pass   def __str__(self):  return '{} turns {} today '.format(self.name, self.age)  pass  pass   zhz = Student('Jayne hide and hide'.25) zhz.wight = 60   def dymicMethod(self):  print('{} weight is {}'.format(self.name,self.wight))  pass  ## Dynamically bind class methods @classmethod def classTest(cls):  print('Class method')  pass  Bind static methods dynamically @staticmethod def staticTest(a):  print('Static method')  pass Copy the code

13.1. Adding attributes dynamically

print(zhz.wight)
Copy the code

13.2. Adding attributes to a class

Student.pro = 'Computer Science'
## Instances are accessible
print(zhz.pro)
Copy the code

13.3. Dynamically add instance methods

## import types
zhz.printInfo = types.MethodType(dymicMethod,zhz)
zhz.printInfo()
Copy the code

13.4. Dynamically binding class methods

Student.testMethod = classTest
Student.testMethod()
Copy the code

13.5. Dynamically binding class method instance calls

zhz.testMethod()
Copy the code

13.6. Dynamically bind static methods

Student.statictest = staticTest
Student.statictest()
Copy the code

13.7. Dynamically bind static method instance calls

zhz.statictest()
Copy the code

14. _slots_ attribute

class Student(object):
    __slots__ = ('name'.'age'.'score')

    def __str__(self):
        return "{}, {}".format(self.name, self.age)
 xw = Student() xw.name = 'Tell me Jayne to hide.' xw.age = 25 ## print(xw.__dict__) ## {'name': 'age': 25}  xw.s11 = '1212'  # # # # error print(xw)  Copy the code

The subclass does not declare slots. It does not inherit the parent class’s __slots__, so the subclass can assign attributes at will

The subclass declares the scope of the subclass plus the parent class

15. Topic Exercise 1

15.1 What are the methods and functions of Python New?

This method is used to create instance objects, only if you inherit from object.

15.2 What is the Singleton Mode and What Scenarios does it Apply to?

A class is required to have one and only one instance and to provide global access points. Log inserts into logger, site counter, permission verification module, Window explorer, system recycle bin, database connection pool

15.3 Can privatization methods and privatization attributes be inherited in subclasses?

Can’t the

15.4 What is an exception in Python?

An exception occurred during the execution of a program.

15.5 How do I Handle Exceptions in Python?

Handle each exception according to the type of exception

15.6 What is the general format for exception handling in Python that can be described using pseudocode?

## try:
Normal operation
## except:
# # # #...
## else:
# # # #... ## finally:  # # # #... Copy the code

15.7 Functions of __slots__

Limit random input of attributes to save memory space

15.8 What is the role of privatization attributes?

Data protection, encapsulation of the embodiment

15.9 Do I Modify Private Attributes Outside a Class?

You can’t modify it directly. You can do it using a property

15.10 If only specified attributes or methods of a class can be modified externally, how can I limit this?

Privatize attributes

16. Question Exercise 2

16.1 Define a Person class with initialization methods and private attributes such as the person name and age

Provide the function to obtain user information, provide the method to set the private attribute, set the age between 0 and 120 years old, if not in this range, cannot be set successfully

class Person:
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
        pass
 pass   def GetUserInfo(self):  return "The age of {} is {}".format(self.__name,self.__age)  pass  pass   def __str__(self):  return "The age of {} is {}".format(self.__name,self.__age)   def setAge(self,age):  if age>0 and age<120:  self.__age = age  else:  pass  person = Person('Jayne hide and hide'.19) print(person.GetUserInfo()) ## Jayne's age is 19  print(person.setAge(30)) print(person.GetUserInfo()) ## Jayne's age is 30  Copy the code

16.2 Write a singleton pattern

class DataBaseClass(object):
    def __new__(cls,*args,**kwargs):
        ## cls._instance = cls.__new__(CLS) ## Cannot use its own new method
        if not hasattr(cls,'_instance') :            cls._instance = super().__new__(cls,*args,**kwargs)
 return cls._instance  pass  pass  db1 = DataBaseClass() db2 = DataBaseClass() db3 = DataBaseClass() print(id(db1)) print(id(db2)) print(id(db3))  Copy the code

16.3 Create a class that defines two private attributes and provides a method to get the attributes. Use the property property to provide the call to the caller

class Student:
    def __init__(self, name, score):
        self.__name = name
        self.___score = score

 @property  def name(self):  return self.__name   @name.setter  def name(self, name):  self.__name = name   def __str__(self):  return self   def __call__(self, *args, **kwargs):  print(self.name)  pass  pass  xm = Student('Jayne hide and hide'.98) xm.__call__()  xm.name() Copy the code

16.4 Create an Animal class. Take a cat object and bind a run method to cat and a color attribute to the class

import types
class Animal:
    pass

def run(self):
 print('the cat')  cat = Animal() cat.run = types.MethodType(run,cat) cat.run()  Animal.color = 'red' print(cat.color)  def info(a):  print('ok')  Animal.info = info Animal.info() Copy the code