社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

告别简单format()!Python Formatter类让你的代码更专业

python • 2 天前 • 9 次点击  


Python中Formatter类是string模块中的一个重要类,它实现了Python字符串格式化的底层机制,允许开发者创建自定义的格式化行为。通过深入理解Formatter类的工作原理和使用方法,可以更好地掌握Python字符串处理的精髓,提升代码的可读性和维护性。

基础概念

Formatter类是Python标准库中string模块的核心组件,提供了字符串格式化的基础框架。该类实现了format()方法的底层逻辑,通过继承和重写相关方法来实现自定义的格式化行为。Formatter类的设计遵循了开放封闭原则,既提供了默认的格式化功能,又允许用户根据特定需求进行扩展。

Formatter类的主要职责包括解析格式化字符串、处理字段替换、应用格式规范以及生成最终的格式化结果。通过一系列可重写的方法,如get_field()、get_value()、check_unused_args()等,为开发者提供了精细控制格式化过程的能力。

核心方法

1、基本使用方法

Formatter类的最基本用法是直接实例化并调用format方法。这个方法接受格式化字符串作为第一个参数,后续参数用于填充格式化占位符。

import string

# 创建Formatter实例并进行基本格式化
formatter = string.Formatter()
result = formatter.format("Hello, {name}! You are {age} years old.", name="Alice", age=25)
print(result)
# 输出: Hello, Alice! You are 25 years old.

# 使用位置参数进行格式化
result2 = formatter.format("The {0} {1} jumps over the {2}.""quick""brown fox""lazy dog")
print(result2)
# 输出: The quick brown fox jumps over the lazy dog.

2、自定义Formatter类

通过继承Formatter类并重写相关方法,可以创建具有特定行为的自定义格式化器。

import string
from datetime import datetime

class CustomFormatter(string.Formatter):
    def get_value(self, key, args, kwargs):
        # 自定义获取值的逻辑
        if  isinstance(key, str):
            try:
                # 尝试从kwargs中获取值
                return kwargs[key]
            except KeyError:
                # 如果键不存在,返回默认值
                returnf"[{key} not found]"
        else:
            # 处理位置参数
            return super().get_value(key, args, kwargs)
    
    def format_field(self, value, format_spec):
        # 自定义字段格式化逻辑
        if format_spec == 'upper':
            return str(value).upper()
        elif format_spec == 'datetime':
            if isinstance(value, datetime):
                return value.strftime('%Y-%m-%d %H:%M:%S')
        return super().format_field(value, format_spec)

# 使用自定义Formatter
custom_formatter = CustomFormatter()
result = custom_formatter.format("Name: {name:upper}, Time: {time:datetime}"
                                 name="john doe"
                                 time=datetime.now())
print(result)
# 输出: Name: JOHN DOE, Time: 2024-01-15 14:30:25

# 测试缺失键的处理
result2 = custom_formatter.format("Hello {name}, your score is {score}", name="Alice")
print(result2)
# 输出: Hello Alice, your score is [score not found]

高级应用场景

1、安全格式化实现

在处理用户输入或不可信数据时,安全的字符串格式化变得尤为重要。通过自定义Formatter类,可以实现对格式化过程的严格控制,防止潜在的安全风险。

import string

class SafeFormatter(string.Formatter):
    def __init__(self, allowed_keys=None):
        super().__init__()
        self.allowed_keys = set(allowed_keys) if allowed_keys else set()
    
    def get_value(self, key, args, kwargs):
        # 只允许访问预定义的键
        if isinstance(key, str) and key notin self.allowed_keys:
            raise ValueError(f"Access to key '{key}' is not allowed")
        return super().get_value(key, args, kwargs)
    
    def get_field(self, field_name, args, kwargs):
        # 禁止访问属性和方法
        if'.'in field_name or'['in field_name:
            raise ValueError("Attribute access and indexing are not allowed")
        return super().get_field(field_name, args, kwargs)

# 使用安全格式化器
safe_formatter = SafeFormatter(allowed_keys=['username''message'])

try:
    # 正常使用
    result = safe_formatter.format("User: {username}, Message: {message}"
                                  username="alice", message="Hello World")
    print(result)
    # 输出: User: alice, Message: Hello World
    
    # 尝试访问不允许的键
    result2 = safe_formatter.format("Secret: {password}", password="secret123")
except ValueError as e:
    print(f"安全错误:  {e}")
    # 输出: 安全错误: Access to key 'password' is not allowed

2、条件格式化器

在某些应用场景中,需要根据数据的值或类型来决定格式化的方式。通过创建条件格式化器,可以实现智能的格式化行为,根据不同的条件应用不同的格式化规则。

import string

class ConditionalFormatter(string.Formatter):
    def format_field(self, value, format_spec):
        # 处理数值的条件格式化
        if format_spec.startswith('cond:'):
            conditions = format_spec[5:].split('|')
            for condition in conditions:
                if':'in condition:
                    test, format_rule = condition.split(':'1)
                    if self._evaluate_condition(value, test):
                        return self._apply_format(value, format_rule)
            return str(value)  # 默认返回字符串形式
        
        return super().format_field(value, format_spec)
    
    def _evaluate_condition(self, value, test):
        # 简单的条件评估
        if test.startswith('>'):
            return float(value) > float(test[1:])
        elif  test.startswith('):
            return float(value) < float(test[1:])
        elif test.startswith('='):
            return str(value) == test[1:]
        returnFalse
    
    def _apply_format(self, value, format_rule):
        # 应用格式规则
        if format_rule == 'currency':
            returnf"${float(value):.2f}"
        elif format_rule == 'percent':
            returnf"{float(value):.1%}"
        elif format_rule.startswith('prefix:'):
            prefix = format_rule[7:]
            returnf"{prefix}{value}"
        return str(value)

# 使用条件格式化器
cond_formatter = ConditionalFormatter()

# 测试不同条件下的格式化
values = [1500500.25]
for value in values:
    result = cond_formatter.format(
        "Value: {amount:cond:>1000:currency|>0:prefix:+|=0:prefix:zero}",
        amount=value
    )
    print(result)

# 输出:
# Value: $1500.00
# Value: +50
# Value: zero

实际应用案例

1、日志格式化系统

在实际的软件开发中,日志格式化是Formatter类的重要应用场景。通过自定义Formatter,可以创建统一的日志格式化系统,确保日志信息的一致性和可读性。

import string
from datetime import datetime
import logging

class LogFormatter(string.Formatter):
    def __init__(self):
        super().__init__()
        self.log_levels = {
            'DEBUG''🐛',
            'INFO''ℹ️',
            'WARNING''⚠️',
            'ERROR''❌',
            'CRITICAL''🚨'
        }
    
    def format_field(self, value, format_spec):
        if format_spec == 'level_icon':
            return self.log_levels.get(str(value), '❓')
        elif format_spec == 'timestamp':
            if isinstance(value, datetime):
                return value.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
        elif format_spec == 'module_short':
            # 缩短模块名称
            return str(value).split('.')[-1if'.'in str(value) else str(value)
        
        return super().format_field(value, format_spec)

# 使用日志格式化器
log_formatter = LogFormatter()

log_template = "{timestamp:timestamp} [{level:level_icon}] {module:module_short}: {message}"

# 模拟日志条目
log_entries = [
    {'timestamp': datetime.now(), 'level''INFO''module''app.main''message''Application started'},
    {'timestamp': datetime.now(), 'level''WARNING''module''app.database''message''Connection timeout'},
    {'timestamp': datetime.now(), 'level''ERROR''module''app.api.user''message''User not found'}
]

for entry in log_entries:
    formatted_log = log_formatter.format(log_template, **entry)
    print(formatted_log)

# 输出示例:
# 2024-01-15 14:30:25.123 [ℹ️] main: Application started
# 2024-01-15 14:30:25.456 [⚠️] database: Connection timeout
# 2024-01-15 14:30:25.789 [❌] user: User not found

2、API响应格式化器

通过自定义Formatter类,创建统一的API响应格式化系统,确保不同接口返回数据的一致性和规范性。

import string
from datetime import datetime
import json

class APIResponseFormatter(string.Formatter):
    def __init__(self):
        super().__init__()
        self.status_messages = {
            200'Success',
            400'Bad Request',
            401'Unauthorized',
            404'Not Found',
            500'Internal Server Error'
        }
    
    def format_field(self, value, format_spec):
        if format_spec == 'status_text':
            return self.status_messages.get(int(value), 'Unknown Status')
        elif format_spec == 'iso_time':
            if isinstance(value, datetime):
                return value.isoformat()
        elif format_spec == 'json_data':
            return json.dumps(value, ensure_ascii=False, indent=2)
        elif format_spec == 'success_flag':
            return str(int(value) 400).lower()
        
        return super().format_field(value, format_spec)

# 使用API响应格式化器
api_formatter = APIResponseFormatter()

response_template = '''{{
    "status": {status},
    "status_text": "{status:status_text}",
    "success": {status:success_flag},
    "timestamp": "{timestamp:iso_time}",
    "data": {data:json_data},
    "message": "{message}"
}}'''


# 模拟不同的API响应
responses = [
    {
        'status'200,
        'timestamp': datetime.now(),
        'data': {'user_id'123'username''alice''email''alice@example.com'},
        'message''User retrieved successfully'
    },
    {
        'status'404,
        'timestamp': datetime.now(),
        'data'None,
        'message''User not found'
    },
    {
        'status'500,
        'timestamp': datetime.now(),
        'data': {'error_code''DB_CONNECTION_FAILED'},
        'message' 'Database connection failed'
    }
]

for response in responses:
    formatted_response = api_formatter.format(response_template, **response)
    print(formatted_response)
    print("-" * 50)

# 输出示例:
# {
#     "status": 200,
#     "status_text": "Success",
#     "success": true,
#     "timestamp": "2024-01-15T14:30:25.123456",
#     "data": {
#       "user_id": 123,
#       "username": "alice",
#       "email": "alice@example.com"
#     },
#     "message": "User retrieved successfully"
# }

总结

Formatter类作为Python字符串格式化的核心组件,为开发者提供了强大而灵活的格式化能力。通过深入理解其工作原理和使用方法,可以创建出满足各种复杂需求的自定义格式化器。无论是简单的字符串替换还是复杂的条件格式化,Formatter类都能够提供优雅的解决方案。掌握Formatter类的使用技巧,将有助于提升Python程序的字符串处理能力和代码质量。

如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!

我们还为大家准备了Python资料,感兴趣的小伙伴快来找我领取一起交流学习哦!

图片

往期推荐

历时一个月整理的 Python 爬虫学习手册全集PDF(免费开放下载)

Beautiful Soup快速上手指南,从入门到精通(PDF下载)

Python基础学习常见的100个问题.pdf(附答案)

124个Python案例,完整源代码!

30 个Python爬虫的实战项目(附源码)

从入门到入魔,100个Python实战项目练习(附答案)!

80个Python数据分析必备实战案例.pdf(附代码),完全开放下载

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/183266
 
9 次点击