An Exploratory Object-Oriented Advancement. Magic Methods

Magic Methods

What does the u init_u method do in class methods?

When an object is created, the initialization settings for the created object are automatically invoked.

What is magic?

In python, methods such as u init_ that start and end a double-slide line are collectively called magic methods.

Note: When we encapsulate our own methods, do not use the method that begins or ends with a double underscore. Magic methods use python's own internal method.

Create singleton mode

When we create a class, we instantiate an object every time we call it, so what if we want this class to be instantiated only once?

class Demo(object):
    __instance = None

    def __new__(cls, *args, **kwargs):
        # Control the number of times a class creates objects by overriding the new method
        if cls.__instance is None:
            instance = super().__new__(cls)
            cls.__instance = instance

        return cls.__instance


deom1 = Demo()
deom2 = Demo()
# Print the memory addresses of demo1 and demo2, respectively
print(id(deom1), id(deom2))

Result:
1401905908320 1401905908320

By returning the results, we see that they are calling the same memory address

The usage scenario of the singleton mode in work, assuming that our class needs to create a lot of objects in work, different objects call the same internal methods, such as the log module. Usually we define the log module and call the log in different places, we need to call an object. In python, if we create objects through the class, then it isA log collector. If we create more than one, it will cause the log to be collected repeatedly.

import os
import logging
from logging.handlers import TimedRotatingFileHandler, BaseRotatingHandler
import colorama

colorama.init()


class Logger:
    __instance = None
    sh = logging.StreamHandler()

    def __new__(cls, path=None, level='DEBUG'):
        """
        :param path: report path
        :param args:
        :param kwargs:
        :return:
        """
        if not cls.__instance:
            cls.__instance = super().__new__(cls)
            log = logging.getLogger('apin-ui')
            log.setLevel(level)
            cls.__instance.log = log
        return cls.__instance

    def set_level(self, level):
        """Set the level of log output"""
        self.log.setLevel(level)

    def set_file_handle(self, level, path):
        if path:
            if not os.path.isdir(path):
                os.mkdir(path)
            fh = TimedRotatingFileHandler(os.path.join(path, 'apin-ui.log'), when='d',
                                          interval=1, backupCount=7,
                                          encoding="utf-8")
            fh.setLevel(level)
            self.log.addHandler(fh)
            # Define the output format of handler
            formatter = logging.Formatter("%(asctime)s | [%(levelname)s] | : %(message)s")
            fh.setFormatter(formatter)

    def debug(self, message):
        self.fontColor('\033[0;34m{}\033[0;34m{}\033[0;34m{}')
        self.log.debug(message)

    def info(self, message):
        self.fontColor('\033[0;32m{}\033[0;32m{}\033[0;32m{}')
        self.log.info(message)

    def warning(self, message):
        self.fontColor('\033[0;33m{}\033[0;43m{}\033[0;33m{}')
        self.log.warning(message)

    def error(self, message):
        self.fontColor('\033[0;31m{}\033[0;41m{}\033[0;31m{}')
        self.log.error(message)

    def exception(self, message):
        self.fontColor('\033[0;31m{}\033[0;41m{}\033[0;31m{}')
        self.log.exception(message)

    def critical(self, message):
        self.fontColor('\033[0;35m{}\033[0;45m{}\033[0;35m{}')
        self.log.critical(message)

    def fontColor(self, color):
        # Different log output colors
        formatter = logging.Formatter(color.format("%(asctime)s| ", "[%(levelname)s]", " | : %(message)s"))
        self.sh.setFormatter(formatter)
        self.log.addHandler(self.sh)


def print_info(msg):
    print('\033[0;32m{}'.format(msg))


def print_waring(msg):
    print('\033[0;33m{}'.format(msg))


def print_error(msg):
    print('\033[0;31m{}'.format(msg))


if __name__ == '__main__':
    logger = Logger()
    logger.debug('debu Level Log')
    logger.info('info Journal')
    logger.warning('warning Journal')
    logger.error('error Journal')
    logger.critical('CRITICAL Journal')

Context Manager

Have you ever thought about why the file with open method closes automatically when we open it in python?

Here we need to understand the concept of context manager:

The context manager is a python object that provides additional context information for the operation. This additional information takes the form of all callable forms in the use of the with statement to initialize the context and complete the with code block.

  • object.enter(self)
    Enter the context associated with the secondary object. If present, the with statement binds the return value of the method to the target specified in the as clause of the sentence.
  • object.exit(self, exc_type, exc_val, exc_tb)
    exc_type: Exception type
    exc_val: Outliers
    exc_tb: exception backtrace

Let's do a file operation manually:

class OpenFile(object):
    """Handwriting implements the context of file operations"""
    def __init__(self, filename, method):
        # Initialize open file
        self.file = open(filename, method)

    # When context is started, the open object is returned
    def __enter__(self):
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()

Keywords: Python

Added by ediehl on Sat, 25 Sep 2021 19:40:34 +0300