杰瑞科技汇

Python filelineno如何获取当前行号?

Of course! The filelineno() method is an essential tool in Python for logging and debugging. It's part of the standard logging module.

Python filelineno如何获取当前行号?-图1
(图片来源网络,侵删)

Let's break it down.

What is filelineno()?

filelineno() is a method available on Python LogRecord objects. A LogRecord is the internal object that the logging module creates for every single log message (e.g., when you call logger.info(...)).

The filelineno() method returns the line number of the source code file where the logging call was made.


How to Use It

You can't call filelineno() directly on your logger. Instead, you use it within a custom formatter. A formatter is an object that controls the final string format of your log messages.

Python filelineno如何获取当前行号?-图2
(图片来源网络,侵删)

Here is a complete, step-by-step example.

Step 1: Create a Python Script

Let's say you have a file named my_app.py with the following code. Notice the comments indicating where the log calls are made.

# my_app.py
import logging
import time
import random
# 1. Set up a logger
logger = logging.getLogger("my_app_logger")
logger.setLevel(logging.DEBUG)  # Capture all levels of logs
# 2. Create a custom formatter that uses filelineno()
# The %(filename)s and %(lineno)s are standard placeholders.
# We add %(funcName)s to see the function name as well.
formatter = logging.Formatter(
    fmt='%(asctime)s - %(levelname)s - %(filename)s:%(funcName)s:%(lineno)d - %(message)s'
)
# 3. Create a console handler (to print logs to the terminal)
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
# 4. Add the handler to the logger
logger.addHandler(console_handler)
# --- Application Logic ---
def process_data():
    """A function that simulates processing some data."""
    logger.info("Starting data processing.")
    for i in range(3):
        time.sleep(0.5)
        item = random.choice(['apple', 'banana', 'cherry'])
        logger.debug(f"Processing item {i}: {item}")
    logger.info("Finished data processing.")
def main():
    """Main function of the application."""
    logger.info("Application has started.")
    try:
        process_data()
        logger.warning("This is a warning message from the main function.")
    except Exception as e:
        logger.error(f"An error occurred: {e}", exc_info=True) # exc_info is useful for errors
    logger.info("Application is shutting down.")
if __name__ == "__main__":
    main()

Step 2: Run the Script

When you run this script from your terminal:

python my_app.py

Step 3: Observe the Output

The output will clearly show the filename, function name, and exact line number for each log message.

Python filelineno如何获取当前行号?-图3
(图片来源网络,侵删)
2025-10-27 10:30:00,123 - INFO - my_app.py:main:37 - Application has started.
2025-10-27 10:30:00,124 - INFO - my_app.py:process_data:22 - Starting data processing.
2025-10-27 10:30:00,725 - DEBUG - my_app.py:process_data:27 - Processing item 0: banana
2025-10-27 10:30:01,226 - DEBUG - my_app.py:process_data:27 - Processing item 1: apple
2025-10-27 10:30:01,727 - DEBUG - my_app.py:process_data:27 - Processing item 2: cherry
2025-10-27 10:30:01,728 - INFO - my_app.py:process_data:30 - Finished data processing.
2025-10-27 10:30:01,728 - WARNING - my_app.py:main:40 - This is a warning message from the main function.
2025-10-27 10:30:01,728 - INFO - my_app.py:main:42 - Application is shutting down.

As you can see:

  • The INFO log for "Application has started" is on line 37 of my_app.py in the main function.
  • The DEBUG log for "Processing item..." is on line 27 of my_app.py in the process_data function.
  • The WARNING log is on line 40, also in the main function.

Key Points and Comparison

filelineno() vs. lineno

It's easy to confuse filelineno() with the standard %(lineno)s placeholder in a formatter. They are very similar but have a critical difference.

  • %(lineno)s: This gives the line number in the module where the logging call was made. This is usually what you want and is more common.
  • filelineno(): This method also returns the line number in the module where the logging call was made. In most simple cases, they produce the same result.

The primary reason filelineno() exists is for more complex scenarios, particularly when you are creating your own custom LogRecord subclasses or advanced handlers. For 99% of use cases, %(lineno)s in your formatter string is sufficient and more direct.

filelineno() vs. module and filename

  • %(filename)s: The name of the module file (e.g., my_app.py).
  • %(module)s: The name of the module (e.g., my_app). This can be different from filename.py if the module is imported.
  • filelineno(): The actual line number within that file.

When to Use filelineno() (or %(lineno)s)

Using the line number in your logs is incredibly useful for:

  1. Debugging: When an error occurs in a log message, you can instantly jump to the exact line of code that generated it.
  2. Code Review: When reviewing logs, you can quickly locate the specific part of the code that produced a certain message.
  3. Complex Applications: In large applications, it helps pinpoint the origin of a log message without having to search through multiple files manually.

When NOT to Use It

  • In Production Logs for High-Volume Systems: Line numbers add extra characters to every log message. In a system that generates millions of logs per second, this can significantly increase storage and processing overhead. For production, you might omit it or use a less verbose format.
  • For Simple Scripts: If you're just writing a quick script and only logging to the console for immediate feedback, the line number might be overkill.

Summary

Feature Description How to Use
filelineno() A method on a LogRecord object that returns the line number of the source file. Used inside a custom Formatter class.
%(lineno)s A standard placeholder for a Formatter string that does the same thing as filelineno(). Used directly in the fmt string of a Formatter.
Best Practice For most cases, %(lineno)s is simpler and preferred. filelineno() is more powerful for custom LogRecord or handler logic. Use logging.Formatter(fmt='... %(filename)s:%(lineno)d ...') for a quick and effective solution.
分享:
扫描分享到社交APP
上一篇
下一篇