Summary of Python Engineering

A top-down summary of how to write an industrial-grade Python project.

1. Project structure

Top level structure:

folder:

  • model can be a custom class in the project;
  • Utils are some engineering tools, such as log, tracker
  • log stores the recorded log

py file:

  • run: main file, the top-level logic of the project;
  • settings: constants in the run file (used as settings);

Two, package (package)

__init__.py role:

  • When there is __init__.py in the folder, it means that the current folder is a package, and multiple modules under it form a whole.
  • Obfuscated import:

    from Root.Pack1 import *

    The modules in * in the fuzzy import are defined by __all__. Another function of __init__.py is to define __all__ in the package for fuzzy import, such as __init__.py:

    __all__ = ["Pack1Class","Pack1Class1"]

          or

__all__ = [ ' file1 ' , ' file2 ' ]    # There are file1.py, file2.py under package1

With the help of __init__.py: import the class name in the subfile into the package name

For example, the websocket package: websocket.WebSocketApp, when importing, you can see all the class names written in the __init__.py file

 The content of the websocket package __init__.py file:

in the websocket package _app.py

 

3. Class

How to write callback (callback function):

  • 1. At the declaration, write the formal parameters used to hook the external function in the form with default parameters, such as on_message=None:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def __init__(self, url, header=None,
             on_open=None, on_message=None, on_error=None,
             on_close=None, on_ping=None, on_pong=None,
             on_cont_message=None,
             keep_running=True, get_mask_key=None, cookie=None,
             subprotocols=None,
             on_data=None):
    """
    url: websocket url.
    header: custom header for websocket handshake.
    on_open: callable object which is called at opening websocket.
      this function has one argument. The argument is this class object.
    on_message: callable object which is called when received data.
     on_message has 2 arguments.
     ...
    """

 

  • 2. The calling function needs to be defined in the class to check whether the external function can be used normally:
1
2
3
4
5
6
7
8
9
def _callback(self, callback,*args):
    if callback:
        try:
            callback(self,*args)
        except Exception as e:
            _logging.error("error from callback {}: {}".format(callback, e)
            if _logging.isEnabledForDebug():
                _, _, Also= sys.exc_info()
                traceback.print_tb(tb)

 

  • 3. When calling, call the external function API through the defined _callback
1
self._callback(self.on_message, data)  

 

Bind a new property to self:

Since Python is a dynamic language, it is free to bind new properties. But in the method of the class, you need to use hasattr to check whether it already exists to prevent multiple bindings. 

1
2
if not hasattr(self,'flop_strategy'):
    self.flop_strategy= FlopStrategy()

  

  

 

Related: Summary of Python Engineering