Summary of several methods for debugging Python code _python

Source: Internet
Author: User
Tags readfile

Debugging with the PDB

The PDB is a Python-brought package that provides an interactive source code debugging feature for Python programs, including setting breakpoints, stepping through debugging, entering function debugging, viewing current code, viewing stack fragments, dynamically changing the values of variables, and so on. The PDB provides some common debugging commands, as detailed in table 1.
Table 1. PDB Common commands

The following is a concrete example of how to use the PDB for debugging.
Listing 1. Test code sample

Import pdb 
 a = "AAA"
 pdb.set_trace () 
 b = "BBB"
 C = "CCC"
 final = a + B + C 
 print final

Start debugging: Run the script directly, stay at Pdb.set_trace (), and select N+enter to perform the current statement. After you press N+enter for the first time, you can press ENTER directly to repeat the previous debug command.
Listing 2. Using PDB debugging

[root@rcc-pok-idg-2255 ~]# python epdb1.py 
 >/root/epdb1.py (4)? () 
 -> B = "BBB"
 (PDB) n 
 >/root/epdb1.py (5)? () 
 -> C = "CCC"
 (Pdb) 
 >/root/epdb1.py (6)? () 
 -> final = a + B + C 
 (PDB) List 
 1   import Pdb 
 2   a = "AAA"
 3   pdb.set_trace () 
 4
   b = "BBB"
 5   C = "CCC"
 6-> final = a + B + C 
 7   print final 
 [EOF] 
 (PDB) 
 [EOF] 
 (PDB) n 
 >/root/epdb1.py (7)? () 
 -> Print Final 
 (PDB)

Exit Debug: Use Quit or Q to exit the current debug, but quit will exit the program in a very rude way, and the result is a direct crash.
Listing 3. Exit Debug

[root@rcc-pok-idg-2255 ~]# python epdb1.py 
 >/root/epdb1.py (4)? () 
 -> B = "BBB"
 (PDB) n 
 >/root/epdb1.py (5)? () 
 -> C = "CCC"
 (PDB) Q 
 traceback (most recent call last): 
 File "epdb1.py", line 5, in? 
  c = "CCC"
 File "epdb1.py", line 5, in? 
  c = "CCC"
 File "/usr/lib64/python2.4/bdb.py", line-in-Trace_dispatch return 
  self.dispatch_line (frame) 
 File "/usr/lib64/python2.4/bdb.py", line, in Dispatch_line 
  if Self.quitting:raise bdbquit 
 bdb. Bdbquit

Print Variable Value: If you need to print the value of a variable during debugging, you can use p plus the variable name directly, but note that the print only sees the specific value after the current statement has been executed, otherwise it will be reported to Nameerror: < exceptions. Nameerror. ....> error.
Listing 4. Print variables during debug

[root@rcc-pok-idg-2255 ~]# python epdb1.py 
 >/root/epdb1.py (4)? () 
 -> B = "BBB"
 (PDB) n 
 >/root/epdb1.py (5)? () 
 -> C = "CCC"
 (PDB) P b 
' BBB '
 (PDB) 
' BBB '
 (PDB) n 
 >/root/epdb1.py (6)? () 
 -> final = a + B + C 
 (PDB) P C 
' CCC '
 (PDB) p final 
 * * * nameerror: <exceptions. Nameerror instance at 0x1551b710 > 
 (Pdb) n 
 >/root/epdb1.py (7)? () 
 -> Print final 
 (PDB) p final 
' AAABBBCCC '
 (PDB)

Use C to stop the current debug so that the program continues to execute. If you continue with the Set_statement () declaration in the following program, you will re-enter the debug state, and the reader can add set_trace () validation before the code print final.
Listing 5. Stop debug Continue executing program

[root@rcc-pok-idg-2255 ~]# python epdb1.py 
 >/root/epdb1.py (4)? () 
 -> B = "BBB"
 (PDB) n 
 >/root/epdb1.py (5)? () 
 -> C = "CCC"
 (PDB) c 
 AAABBBCCC

Display code: The current code block is not necessarily remembered in debug, and can be displayed by using the list or L command if you want to see a specific block of code. The list points to the current debug statement with an arrow->.
Listing 6. Display code during debug

[root@rcc-pok-idg-2255 ~]# python epdb1.py 
 >/root/epdb1.py (4)? () 
 -> B = "BBB"
 (PDB) List 
 1   import Pdb 
 2   a = "AAA"
 3   pdb.set_trace () 
 4-> b = "BBB" C11/>5   C = "CCC"
 6   final = a + B + C 
 7   pdb.set_trace () 
 8   Print Final 
 [EOF] 
 (PDB) C 
 >/root/epdb1.py (8)? () 
 -> Print Final 
 (Pdb) List 
 3   pdb.set_trace () 
 4   b = "BBB"
 5   C = "CCC"
 6   final = a + B + C 
 7   pdb.set_trace () 
 8-> Print Final 
 [EOF] 
 (PDB)

Debug with a function
Listing 7. Examples of using functions

Import PDB 
 def combine (s1,s2):   # define subroutine Combine, which ... 
  S3 = S1 + s2 + S1  # sandwiches S2 between copies of S1, ... 
  S3 = ' "' + s3 + '" '  # encloses it in double quotes,... 
  Return S3      # and returns it. 
 A = "AAA"
 pdb.set_trace () 
 b = "BBB"
 C = "CCC"
 final = Combine (a,b) 
 print final

If you use N to debug directly to Final=combine (A,B) The sentence will be treated as a normal assignment statement, into print final. What if you want to debug a function? You can use S to enter the function block directly. The single step debugging in a function is similar to the one described above. If you do not want to step into a function, you can simply press R at the breakpoint to exit to the call place.
Listing 8. To debug a function

[root@rcc-pok-idg-2255 ~]# python epdb2.py >/root/epdb2.py (10)? ()-> B = "BBB" (PDB) n >/root/epdb2.py (11)? ()-> C = "CCC" (PDB) n >/root/epdb2.py (12)? ()-> final = Combine (a,b) (Pdb) s--call-->/root/epdb2.py (3) combine ()-> def Combine (s1,s2): # def 
 Ine subroutine combine, which ... 
 (PDB) n >/root/epdb2.py (4) combine ()-> s3 = s1 + s2 + S1 # Sandwiches S2 between copies of S1, ... 
 (PDB) List 1 Import Pdb 2 3 def Combine (S1,S2): # define subroutine Combine, which ... 
 4-> s3 = s1 + s2 + S1 # Sandwiches S2 between copies of S1, ... 
 5 S3 = ' "+ s3 + '" ' # encloses it in double quotes,... 
 6 return S3 # and returns it.  7 8 A = "AAA" 9 pdb.set_trace () b = "BBB" one C = "CCC" (PDB) n >/root/epdb2.py (5) combine ()-> 
 S3 = ' "' + s3 + '" ' # encloses it in double quotes,... 
 (PDB) n >/root/epdb2.py (6) combine ()-> return S3 # and returns it. (PDB)n--return-->/root/epdb2.py (6) combine ()-> ' aaabbbaaa ' '-> return S3 # and returns it. (PDB) n >/root/epdb2.py (13)?

 ()-> Print final (Pdb)

Dynamically change the value when debugging. When debugging, you can dynamically change the value of the variable, as shown in the following example. Note that there is an error below, because B has been assigned, if you want to change the assignment of B, you should use! B.
Listing 9. Dynamically changing values while debugging

[root@rcc-pok-idg-2255 ~]# python epdb2.py 
 >/root/epdb2.py? () 
 -> B = "BBB"
 (PDB) var = "1234"
 (PDB) b = "Avfe"
 * * * The specified object ' = ' avfe ' ' is not a function 
 Or is not found along Sys.path. 
 (PDB)!b= "AFDFD"
 (PDB)

The obvious flaw with PDB debugging is that it is not good enough to support multithreading, remote debugging, etc., and does not have a more intuitive interface for large python projects. In larger Python projects, these debugging requirements are more common and require more advanced debugging tools. Next, you will describe the debugging methods for the Pycharm IDE.
using Pycharm for debugging

Pycharm is a Python IDE built by JetBrains with syntax highlighting, Project management, code jumps, smart hints, automated completion, unit testing, versioning, and other features that provide for Django development and Google App Engine Support. Divided into individual and commercial version of the license, you need support, you can also get a free 30-day trial. Trial version of the Pycharm can be downloaded on the official web, download the address: http://www.jetbrains.com/pycharm/download/index.html. Pycharm also provides a more complete debugging function, support multithreading, remote debugging and so on, you can support breakpoint settings, Single-step mode, expression evaluation, variable view and a series of functions. The Pycharm IDE's debug window layout is shown in Figure 1.
Figure 1. Pycharm IDE Window Layout

The following example describes how to use Pycharm for multithreaded debugging. The code instance used for the specific debugging is shown in Listing 10.
Listing 10. Pycharm Debugging Code Instance

 __author__ = ' zhangying ' #!/usr/bin/python import thread import time # Define a fun Ction for the thread def print_time (ThreadName, delay): Count = 0 While count < 5:count + + 1 print '%s:% S "% (ThreadName, Time.ctime (Time.time ())) def check_sum (THREADNAME,VALUEA,VALUEB): print" To calculate the sum of T 
 Wo number Her "result=sum (VALUEA,VALUEB) print" The result is "; 
 def sum (VALUEA,VALUEB): If Valuea >0 and Valueb>0:return valuea+valueb def readFile (threadname, filename): FILE = open (filename) for line in File.xreadlines (): Print line Try:thread.start_new_thread (Print_time, ("thre Ad-1 ", 2,)" Thread.start_new_thread (Check_sum, ("Thread-2", 4,5,)) Thread.start_new_thread (ReadFile, ("Thread-3") , ' Test.txt ',) Except:print ' error:unable to start thread ' while 1: # print ' End ' pass 

You usually need to set breakpoints before debugging, and breakpoints can be set at the loop or conditional-judged expression or at the point of the program. The way to set a breakpoint is simple: Move the cursor to the line where you want to set the breakpoint in the Code edit box, and then press Ctrl+f8 or select the menu "Run"-> "Toggle", which is a more straightforward way to double-click the left edge of the code editor. You can see small dots that appear red (Figure 2). When debugging begins, the code that is currently executing is displayed in blue directly. The following illustration sets three breakpoints, which are highlighted in blue as code being executed.
Figure 2. Breakpoint Settings

Expression evaluation: In the debugging process sometimes need to trace the value of some expressions to discover problems in the program, PYCHARM support expression evaluation, you can select the expression, and then select "Run"-> "Evaluate Expression", in the window that appears directly select Evaluate can then be viewed.

Pychar also provides Variables and Watches windows, where the values of the specific variables involved in the debugging steps can be viewed directly in the variable column.
Figure 3. Variable view

If you want to dynamically monitor a variable, you can select the variable directly and select Menu "Run"-> "Add Watch" to add to the Watches column. When you debug the statement that contains the variable, you can see the specific value of the variable directly in the window.
Figure 4. Monitoring variables

For multithreaded programming, there are usually multiple threads, and it is often necessary for the IDE to have good multithreaded debugging capabilities when you need debug breakpoints to be set separately in the corresponding thread bodies of different threads. In Pycharm, a virtual thread with the first name of the Dummy is automatically generated when the main thread starts the child threads, and each frame corresponds to the respective debug frame. As shown in Figure 5, there are four threads in this example, where the main line mechanical engineer into three threads, respectively, dummy-4,dummy-5,dummy-6. Where Dummy-4 corresponds to thread 1, and the rest correspond to thread 2 and thread 3 respectively.
Figure 5. multithreaded windows

When debugging enters the subroutine of each thread, frame will automatically switch to its corresponding frame, the corresponding variable bar will also show the relevant variables corresponding to the process, such as Figure 6, direct control debugging buttons, such as Setp in,step over can be easily debugged.
Figure 6. Child thread Debugging

Using PyDev for debugging

PyDev is an open source plugin that can be easily integrated with Eclipse to provide convenient and powerful debugging capabilities. At the same time, as a good Python IDE also provides syntax error tips, source code Editor assistant, Quick Outline, Globals Browser, Hierarchy View, run, and other powerful features. Here's how to integrate PyDev and Eclipse. Before installing PyDev, you need to install Java 1.4 or later, Eclipse, and Python. Step one: Start Eclipse, find the Help bar in the Eclipse menu bar, select Help > Install New Software, and select Add button to ptdev download site Http://pydev.org/up Dates. After you select PyDev, you can install PyDev by completing the remaining steps.
Figure 7. Install PyDev

After the installation is complete, you need to configure the Python interpreter, and in the Eclipse menu bar, select Window > Preferences > Pydev > Interpreter–python. Python is installed under the C:\Python27 path. Click New, select the Python interpreter python.exe, open a window that contains a lot of check boxes, select the path you want to add to the system Pythonpath, and click OK.
Figure 8. Configure PyDev

After Pydev is configured, you can select File > New > Project > Pydev >pydev Project in the Eclipse menu bar and click Next to create a Python project, which assumes that P The Ython project has been created, and there is a script that needs to be debugged remote.py (as described below), which is a script that logs on to a remote machine to execute some commands, and passes in some parameters at run time, detailing how to pass in the parameters during debugging.
Listing 11. Pydev Debugging Sample Code

 #!/usr/bin/env python 
 import os 
 def telnetdo (Host=none, User=none, Pass=none, Command=none): #define a function 
 import telnetlib, sys 
 if not HOST: 
 try: 
 HOST = sys.argv[1] 
 USER = sys.argv[2] Pass 
 = sys.argv[3 ] 
 COMMAND = sys.argv[4] 
 except: 
 print "Usage:remote.py host user pass COMMAND"
 return 
 tn = Telnetlib. Telnet () # 
 try: 
 tn.open (HOST) 
 except: 
 print "Cannot open HOST"
 return 
 Tn.read_until ( "Login:") 
 tn.write (USER + ' \ n ') 
 if pass: 
 tn.read_until ("Password:") 
 Tn.write (pass + ' \ n ' 
 ) Tn.write (COMMAND + ' \ n ') 
 tn.write ("exit\n") 
 tmp = Tn.read_all () 
 tn.close () 
 del tn 
 return TMP 
 
 If __name__ = = ' __main__ ': 
 print telnetdo ()

When debugging some conditions need to pass some parameters, before debugging need to make the appropriate configuration to receive the required parameters, select the program to be debugged (this example remote.py), the script in the process of debugging needs to enter four parameters: Host,user,password and commands. In the eclipse's engineering directory, select the program you want to debug, right-click, select Debug as,-> Debug configurations, and select Variables in the Arguments Tab page. As shown in Figure 9 below.
Figure 9. Configuration variables

Select "Edit varuables" after the window "select Variable", the following window appears, select "New" in the following figure and enter the corresponding variable name and value in the pop-up window. It is important to note that there must be a space behind the value, otherwise all parameters will be read as the first parameter.
Figure 10. Add a specific variable

Configure all of the parameters in turn, and then select the corresponding variable in the order in which you want to install the parameters in the Select Variable window. After the configuration is complete, the status is shown in Figure 11 below.
Figure 11. Complete configuration

By choosing Debug, you can start debugging a program that is similar to the use of the built-in debugging features of Eclipse, and supports multiple threads of debug, and there are many articles that readers can search for themselves, or refer to the article "debugging using the Eclipse platform."
use the log function to achieve the purpose of debugging

Log information is a very useful way to debug during software development, especially when large software development processes require the collaboration of a lot of relevant people. Developers can benefit from identifying the problems in the code by adding specific information in their code that can record various events in the software's operation. This information may include time, descriptive information, and specific contextual information when errors or anomalies occur. The original debug method is to locate the problem of the program by embedding the print statement in the code and outputting some relevant information. But this method has certain flaw, the normal program output and the debug information mix together, gives the analysis to have the difficulty, when the program debugging end no longer needs the debug output, usually does not have the very simple method to screen out the print information or locates to the file. The logging module in Python can easily solve these problems, it provides the log function, the level of logger is divided into five levels, can be set by Logger.setlevel (LVL). The default level is warning.
Table 2. Level of the log

Ogging Lib contains 4 main objects

  1. Logger:logger is the interface of program information output. It is dispersed in different code so that the program can record the appropriate information at run time and determine which information needs to be exported and distributed to its associated handler based on the log level or filter set. Common methods are Logger.setlevel (), Logger.addhandler (), Logger.removehandler (), Logger.addfilter (), Logger.debug (), Logger.info (), logger.warning (), Logger.error (), GetLogger (), etc. Logger supports hierarchical inheritance relationships, and the name of the child logger is usually the way of the parent logger.name. If you do not create an instance of logger, the default root logger is used, and the root logger instance is obtained by Logging.getlogger () or Logging.getlogger ("").
  2. Handler:handler is used to process the output of information, which can be exported to the console, file or network. You can add handler to the Logger object by Logger.addhandler (), and the commonly used handler have Streamhandler and Filehandler classes. Streamhandler sends error messages to the stream, and the Filehandler class is used to output log information to the file, which is defined in the core module of logging. Two handler. Other hander are defined in the Logging.handles module, such as Httphandler,sockethandler.
  3. Formatter:formatter determines the format of the log information, which is defined in the form of a% (< dictionary key >) s, such as '% (asctime) s-% (levelname) s-% (message S ', the supported key can be viewed in the LogRecord attributes of a python-brought document.
  4. Filter:filter is used to determine what information needs to be exported. Can be used by handler and logger to support hierarchical relationships, such as if the filter is set to a logger named A.B, then the logger and its child logger information are output, such as A.B,A.B.C.

Listing 12. Log usage examples

Import logging
Log1=logging.getlogger (' B.C ')
Log2=logging.getlogger (' D.E ')
Filehandler = logging. Filehandler (' Test.log ', ' a ')
Formatter = logging. Formatter ('% (name) s% (asctime) s% (levelname) s% (message) s ')
Filehandler.setformatter (Formatter)
Filter=logging. Filter (' B ')
Filehandler.addfilter (Filter)
Log1.addhandler (Filehandler)
Log2.addhandler (Filehandler)
Log1.setlevel (Logging.info)
Log2.setlevel (logging. DEBUG)
Log1.debug (' It's a debug info for Log1 ')
Log1.info (' Normal infor for Log1 ')
Log1.warning (' Warning info for LOG1:B.C ')
Log1.error (' Error info for LOG1:ABCD ')
Log1.critical (' Critical info for Log1:not worked ')
Log2.debug (' Debug info for log2 ')
Log2.info (' Normal info for log2 ')
Log2.warning (' Warning info for log2 ')
Log2.error (' ERROR:B.C ')
Log2.critical (' critical ')

The above example sets filter B, then B.C is the logger of B, so the log information associated with the logger of the filter condition is output, and other logger that do not satisfy the condition (here is D.E) are filtered out.
Listing 13. Output results

B.C 2011-11-25 11:07:29,733 INFO normal infor for Log1
B.C 2011-11-25 11:07:29,733 WARNING WARNING info for LOG1:B.C
B.C 2011-11-25 11:07:29,733 Error Error info for LOG1:ABCD
B.C 2011-11-25 11:07:29,733 CRITICAL CRITICAL info for Log1:not worked

The use of logging is very simple, and it is thread-safe, with a multithreaded example of how to use logging for Debug.
Listing 14. Multithreading using logging

Logging.conf 
 [loggers] 
 keys=root,simpleexample 

 [handlers] 
 keys=consolehandler 

 [formatters] 
 Keys=simpleformatter 

 [Logger_root] 
 Level=debug 
 Handlers=consolehandler 

 [logger_simpleexample] 
 level=debug 
 handlers= Consolehandler 
 qualname=simpleexample 
 propagate=0 

 [Handler_consolehandler] 
 class= Streamhandler 
 level=debug 
 formatter=simpleformatter 
 args= (sys.stdout,) 

 [Formatter_ Simpleformatter] 
 format=% (asctime) s-% (name) s-% (levelname) s-% (message) s 
 datefmt= 

 code example: 
 #!/usr/bin/python 
 Import thread 
 import time 
 import logging 
 import Logging.config 
 Logging.config.fileConfig (' logging.conf ') 
 # Create logger 
 logger = Logging.getlogger (' simpleexample ') 
 # Define A function 
 for the thread def print_time (ThreadName, delay): 
 logger.debug (' Thread 1 call print_t IME function Body ') 
 count = 0 
 logger.debug (' count:%s ', count)

Summarize

The full text introduces several different ways of debug in Python, including PDB modules, debugging with PyDev and Eclipse integration, Pycharm, and debug logs, in the hope of giving reference to relevant Python users. For more information on Python debugger, see resources.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.