"Python Core Technologies and Actual Warfare" Object-oriented: from the analogy of life!

Object-oriented: From the analogy of life!

1.Object, have you found it?

  • The most basic concepts in object-oriented programming. To make it easier for you to understand the abstract concepts, I'll give you an analogy first. In biology class, we learned "Borderline Subjects and Genus"Concepts, the core idea is that scientists differentiate different types of animals, plants and microorganisms according to their similarities for easy research. The same is true in life, and we are used to classifying things around us:
  • Cats and dogs are animals;
  • Lines and circles are graphics of planar geometry.
  • Harry Potter and Song of Ice and Fire (Game of Power) are both fictions.
  • Naturally, the same kind of things have similar characteristics:
  • Animals move;
  • Planar graphics have area and perimeter.
  • Novels also have various elements such as the author and general plot.
  • So what does it mean to go back to our Python? Here, let's first look at the most basic Python object-oriented application code. Don't be frightened by its length. You don't need to immediately understand all the code. Follow the rhythm and I'll dissect it for you a little bit.
class Document():
    def __init__(self, title, author, context):
        print('init function called')
        self.title = title
        self.author = author
        self.__context = context # Attributes starting with u are private attributes

    def get_context_length(self):
        return len(self.__context)

    def intercept_context(self, length):
        self.__context = self.__context[:length]

# The constructor is called first.
harry_potter_book = Document('Harry Potter', 'J. K. Rowling', '... Forever Do not believe any thing is capable of thinking independently ...')
print(harry_potter_book.title)
print(harry_potter_book.author)
print(harry_potter_book.get_context_length())

harry_potter_book.intercept_context(10)
print(harry_potter_book.get_context_length())
print(harry_potter_book.__context) # Private properties cannot be accessed directly.

########## output ##########
init function called
Harry Potter
J. K. Rowling
77
10

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-b4d048d75003> in <module>()
     22 print(harry_potter_book.get_context_length())
     23 
---> 24 print(harry_potter_book.__context)

AttributeError: 'Document' object has no attribute '__context'
  • With this code in mind, let me briefly explain a few concepts.
  • Class: A collection of similar things corresponding to Python's class.
  • Object: An object in a collection that corresponds to an object generated by a class, such as harry_potter_book in code.
  • Property: A static feature of the object, such as title, author, and u context in the code above.
  • Function: A dynamic capability of an object, such as the intercept_context() function in the code above.
  • Of course, this statement is neither rigorous nor sufficient, but if you don't know object-oriented programming at all, they can give you a quick, intuitive understanding. Classes, a collection of objects with the same properties and functions.
  • Code parsing just now: You can see that the class Document defines the Document class, and then you can see that it has three functions, which are the three functions of the Document class.
  • Where init denotes a constructor, that is, a function that is called automatically when an object is generated. We can see that when this line of code, harry_potter_book = Document(...), is executed, the'init function called'string is printed, while get_context_length() and intercept_context ()For normal functions of classes, we call them to do something with the properties of the object.
  • The class Document also has three attributes, title, author, and u context, which represent the title, author, and content, respectively, and are passed in through the constructor. The code is intuitive here, and we can see that intercept_context modifies the u context attribute of the object harry_potter_book.
  • The only thing to emphasize here is that if an attribute starts with (note that there are two), we default to this attribute being private. Private attributes are attributes that you don't want to be accessed or modified outside the class's functions. So you can see that title s and author s are free to print, but print(harry_potter_book. u context) will cause an error.

2. Teacher, can you give more force?

  • In engineering practice, as complexity continues to increase, you may think of some issues:
  • How do I define constants in a class that each object can access without rebuilding?
  • What can I do to be more elegant if a function does not involve accessing and modifying the properties of this class and is somewhat inappropriate to put outside?
  • Since a class is a collection of similar objects, can it not be a collection of similar classes?
  • The first two are good solutions, but they involve some common code specifications. Here's a code sample. Again, you don't have to finish the code in one breath and learn at my pace.
class Document():
    
    WELCOME_STR = 'Welcome! The context for this book is {}.'
    
    def __init__(self, title, author, context):
        print('init function called')
        self.title = title
        self.author = author
        self.__context = context
    
    # Class Functions
    @classmethod
    def create_empty_book(cls, title, author):
        return cls(title=title, author=author, context='nothing')
    
    # Member function
    def get_context_length(self):
        return len(self.__context)
    
    # Static function
    @staticmethod
    def get_welcome(context):
        return Document.WELCOME_STR.format(context)

empty_book = Document.create_empty_book('What Every Man Thinks About Apart from Sex', 'Professor Sheridan Simove')

print(empty_book.get_context_length())
print(empty_book.get_welcome('indeed nothing'))

########## output ##########
init function called
7
Welcome! The context for this book is indeed nothing.
  • First, in Python classes, you can do this simply by declaring and assigning values side by side with functions, such as WELCOME_STR in this code. A common practice is to use all uppercase to represent constants, so we can use self.WELCOME_STR in classes or Entity.WELCOME_STR outside of classes to express this string.
  • For the second question, we put forward three concepts: class function, member function and static function. They are actually very well understood. The impact of the first two is dynamic, and they can access or modify the properties of objects; while static function has no relationship with classes, the most obvious feature is that the first parameter of static function has no special characteristics.
  • Specifically, these functions can be used. Generally speaking, static functions can be used to do simple, independent tasks that are easy to test and optimize the code structure. Static functions can also be represented by adding @staticmethod to the line before the function, and there are examples in the code. This actually uses the concept of decorators, which will be explained in more detail in later chapters.
  • The first parameter of a class function is usually cls, which means a class must be passed in. The most common function of a class function is to implement different init constructors. For example, in the code above, we use the create_empty_book class function to create a new book object whose context must be'nothing'. Code like this is clearer than what you construct directly. Similarly, class functions need an adorner @classmethod to declare.
  • The member function is the function of our most normal class. It does not require any decorator declaration. The first parameter self represents a reference to the current object. It can be used to query/modify the properties of the class and other functions.

3.Inheritance is the dream of every rich second generation

  • Next, let's look at the third question, since a class is a collection of similar objects, can it not be a collection of similar classes?
  • The answer is yes, of course. Classes can be described as a collection of anything as long as they are well abstracted. Of course, you have to define it carefully and precisely, or you will cause a third mathematical crisis XD if you do not carefully.
  • Class inheritance, as its name implies, refers to a class that has both the characteristics of another class and the unique features that are different from another class. The first class here is called a subclass and the other is called a parent class, and the features are actually the attributes and functions of the class.
class Entity():
    def __init__(self, object_type):
        print('parent class init called')
        self.object_type = object_type
    
    def get_context_length(self):
        raise Exception('get_context_length not implemented')
    
    def print_title(self):
        print(self.title)

class Document(Entity):
    def __init__(self, title, author, context):
        print('Document class init called')
        Entity.__init__(self, 'document')
        self.title = title
        self.author = author
        self.__context = context
    
    def get_context_length(self):
        return len(self.__context)
    
class Video(Entity):
    def __init__(self, title, author, video_length):
        print('Video class init called')
        Entity.__init__(self, 'video')
        self.title = title
        self.author = author
        self.__video_length = video_length
    
    def get_context_length(self):
        return self.__video_length

harry_potter_book = Document('Harry Potter(Book)', 'J. K. Rowling', '... Forever Do not believe any thing is capable of thinking independently ...')
harry_potter_movie = Video('Harry Potter(Movie)', 'J. K. Rowling', 120)

print(harry_potter_book.object_type)
print(harry_potter_movie.object_type)

harry_potter_book.print_title()
harry_potter_movie.print_title()

print(harry_potter_book.get_context_length())
print(harry_potter_movie.get_context_length())

#################### output ####################
Document class init called
parent class init called
Video class init called
parent class init called
document
video
Harry Potter(Book)
Harry Potter(Movie)
77
120
  • We also combine code to learn these concepts. In this code, Document and Video are similar, with properties such as title, author, and content. We can abstract a class called Entity from it to be the parent of both.
  • The first thing to note is the constructor. Each class has a constructor. Inherited classes do not automatically call the parent class's constructor when they generate objects, so you must explicitly call the parent class's constructor in the init() function. Their order of execution is the child class's constructor - > the parent class's constructor.
  • Next, you need to be aware of the parent get_context_length() function. If you use Entity to directly generate objects and call the get_context_length() function, raise error interrupts the execution of the program. This is a good way to write it, called a function override, so that the subclass must rewrite the get_context_length() function once to overwrite the original function.
  • Finally, you need to be aware of the print_title() function, which is defined in the parent class, but objects in the subclass can use it to print titles without any resistance, which also reflects the advantages of inheritance: reducing duplicate code and reducing the system's entropy value (that is, complexity).
  • At this point, you have a more detailed understanding of inheritance, and object-oriented programming can also be said to have started. Of course, if you want to reach a higher level, a lot of practice in programming and more detailed knowledge are essential.
  • Finally, I'd like to expand on abstract functions and classes for you. I'll also use a piece of code to help explain them.
from abc import ABCMeta, abstractmethod

class Entity(metaclass=ABCMeta):
    @abstractmethod
    def get_title(self):
        pass

    @abstractmethod
    def set_title(self, title):
        pass

class Document(Entity):
    def get_title(self):
        return self.title
    
    def set_title(self, title):
        self.title = title

document = Document()
document.set_title('Harry Potter')
print(document.get_title())

entity = Entity()

########## output ##########

Harry Potter

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-266b2aa47bad> in <module>()
     21 print(document.get_title())
     22 
---> 23 entity = Entity()
     24 entity.set_title('Test')

TypeError: Can't instantiate abstract class Entity with abstract methods get_title, set_title

Tags: Python crawler

Posted on Thu, 14 Oct 2021 13:17:41 -0400 by Destruction