Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the method of Python Debug debugging

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

The main content of this article is to explain "what is the method of Python Debug debugging", interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Next let the editor to take you to learn "what is the method of Python Debug debugging"!

A journal is a must.

If you don't set logging when you write your application, you'll eventually regret it. The absence of any logs in the application makes troubleshooting very difficult. Fortunately, in Python, setting up a basic logger is very simple:

Import logging logging.basicConfig (filename='application.log', level=logging.WARNING, format='[% (asctime) s] {% (pathname) SV% (lineno) d}% (levelname) s -% (message) s, datefmt='%H:%M:%S') logging.error ("Some serious error occurred.") Logging.warning ('Function you are using is deprecated.')

This is all the files you need to start logging, and it looks like this, you can find the path to the file using logger. Getloggerclass () .root.handlers [0] .baseFilename):

[12:52:35] {: 1} ERROR-Some serious error occurred. [12:52:35] {: 1} WARNING-Function you are using is deprecated.

This setting seems good enough (and usually is), but having well-configured, formatted, readable logs can make your job easier. One way to improve and extend the configuration is to use .ini or .yaml files read by logger. For example, what can you do in the configuration:

Version: 1 disable_existing_loggers: true formatters: standard: format: "[% (asctime) s] {% (pathname) s handlers% (lineno) d}% (levelname) s -% (message) s" datefmt:'% HV% MV% handlers: console: # handler which will log into stdout class: logging.StreamHandler level: DEBUG formatter: standard # Use formatter defined above stream: ext://sys.stdout File: # handler which will log into file class: logging.handlers.RotatingFileHandler level: WARNING formatter: standard # Use formatter defined above filename: / tmp/warnings.log maxBytes: 10485760 # 10MB backupCount: 10 encoding: utf8 root: # Loggers are organized in hierarchy-this is the root logger config level: ERROR handlers: [console File] # Attaches both handler defined above loggers: # Defines descendants of root logger mymodule: # Logger for "mymodule" level: INFO handlers: [file] # Will only use "file" handler defined above propagate: no # Will not propagate logs to "root" logger

Configurations that use this extension in python code will be difficult to navigate, edit, and maintain. Saving the content in a YAML file makes it easier to set and adjust multiple loggers with very specific settings, such as those above.

Having the configuration in the file means that we need to load. The easiest way to do this is with the YAML file:

Import yaml from logging import config with open ("config.yaml", 'rt') as f: config_data = yaml.safe_load (f.read ()) config.dictConfig (config_data)

Python logger does not actually support YAML files directly, but it supports dictionary configuration, which can be easily created from YAML using YAML .safe _ load. If you prefer to use the old .ini file, I just want to point out that for new applications, the dictionary configs is recommended based on the documentation.

_ _ repr__ readable log

Make simple improvements to the code to make it more debugable by adding the _ _ repr__ method to the class. If you are not familiar with this method-all it does is return a string representation of an instance of the class. The best practice for using the _ _ repr__ method is to output text that can be used to recreate the instance. For example:

Class Circle: def _ init__ (self, x, y, radius): self.x = x self.y = y self.radius = radius def _ repr__ (self): return f "Rectangle ({self.x}, {self.y}, {self.radius})". C = Circle (100,80,30) repr (c) # Circle (100,80,30)

It's also a good idea to execute the _ _ str__ method when _ _ repr__, calls print (instance). With these two methods, you can get a lot of information by printing your variables.

The _ _ missing__ method for dictionaries

If you need to implement a custom dictionary class for some reason, you may encounter errors caused by keyerror when trying to access keys that don't actually exist. To avoid looking around the code for which key (key) is missing, you can implement a special _ _ miss__ method that is called every time KeyError is proposed.

Class MyDict (dict): def _ _ missing__ (self, key): message = f'{key} not present in the dictionarykeeper' Logging.warning (message) return message # Or raise some error instead

The above implementation is very simple, only returning and logging messages with missing keys, but you can also record other valuable information to understand what went wrong in the code.

Debug a crashed application

If your application crashes before you have a chance to understand what's going on, you may find this technique very useful.

Running the application with the-I parameter (python3-I app.py) causes the interactive shell to start as soon as the program exits. At this point, you can check variables and functions.

If that's not good enough, you can bring a more powerful tool-the pdb-Python debugger. Pdb has many features that can be explained in a separate article. But here is an example and an outline of the most important part. Let's first look at the crash script:

# crashing_app.py SOME_VAR = 42 class SomeError (Exception): pass def func (): raise SomeError ("Something went wrong...") Func ()

Now, if we run it with the-I argument, we have a chance to debug it:

# Run crashing application ~ $python3-I crashing_app.py Traceback (most recent call last): File "crashing_app.py", line 9, in func () File "crashing_app.py", line 7, in func raise SomeError ("Something went wrong...") _ _ main__.SomeError: Something went wrong... > # We are interactive shell > > import pdb > > pdb.pm () # start Post-Mortem debugger >... / crashing_app.py (7) func ()-> raise SomeError ("Something went wrong...") (Pdb) # Now we are in debugger and can poke around and run some commands: (Pdb) p SOME_VAR # Print value of variable 42 (Pdb) l # List surrounding code we are working with 2 3 class SomeError (Exception): 4 pass 5 6 def func (): 7-> raise SomeError ("Something went wrong...") 8 9 func () [EOF] (Pdb) # Continue debugging... Set breakpoints, step through the code, etc.

The debugging session above shows quite simply what you can do with pdb. After the program is finished, we enter the interactive debugging session. First, import pdb and start the debugger. At this point, we can use all the pdb commands. As an example above, we use the p command to print variables and the l command to list the code. Most of the time you may want to set breakpoints, you can work with b LINE_NO and run the program until breakpoint (c), and then continue with age, page-by-page browsing features may be selected with w.

Stack trace

Suppose your code is a Flask or Django application running on a remote server, where you cannot get an interactive debugging session. In this case, you can use the traceback and sys packages to understand the failures in your code:

Import traceback import sys def func (): try: raise SomeError ("Something went wrong...") Except: traceback.print_exc (file=sys.stderr)

At run time, the above code prints the last exception thrown. In addition to printing exceptions, you can also use the traceback package to print stacktrace (traceback. Print_stack () or extract the original stack frame, format it, and further examine it (traceback. Format_list (traceback.extract_stack ()).

Reload the module during debugging

Sometimes, you may debug or experiment with certain functions in interactive shell and change them frequently. To make it easier to run / test and modify the cycle, you can run importlib.reload (module) to avoid restarting the interactive session after each change:

> import func from module > func () "This is result..." # Make some changes to "func" > func () "This is result..." # Outdated result > from importlib import reload; reload (module) # Reload "module" after changes made to "func" > func () "New result..." At this point, I believe you have a deeper understanding of "what is the method of Python Debug debugging?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report