在自定义的error_handler中为python的str函数引用全局变量是否是可疑的做法?

问题描述

str()函数自定义error_handler中引用(或更改)全局变量是否是错误/可疑/允许的做法,该全局变量是通过codecs.register_error()设置的? (请参阅https://docs.python.org/3.6/library/codecs.html#codecs.register_error.

我正在尝试实现自定义的“反斜杠替换”功能,该功能除了反斜杠换行外,还将结果包装在单引号(')或双引号(“)中,非常类似于gnu ls程序--quoting-style=shell-escape时使用文件名。

问题是,单引号或双引号之间的选择无法传输到错误处理程序。让它知道使用哪个的唯一方法是,它引用一个全局变量标记是否应使用单/双引号。

(我使用的是Python 3.6.9版)。

这是一个示例程序:

#!/usr/bin/env python3

import codecs

# in my program,quote varies between these two at runtime
#quote = "'"
quote = '"'


def my_replace( e ):
    global quote        # <-- global variable

    if not isinstance( e,UnicodeDecodeError ):
        raise TypeError( "don't kNow how to handle %r" % e )

    x = []
    for c in e.object[e.start:e.end]:
        try:
            if c == 0x93 or c == 0x94:
                x.append( quote + ( "$'\\%o'" % c) + quote )
        except KeyError:
            return( None )

    return( "".join(x),e.end )


codecs.register_error( "my_replace",my_replace )

s = b'61. \x93Gleich wie ein Hirsch begehret\x94,P.169_ IV. Variatio 3.flac'
s = str( s,'utf-8',errors='my_replace' )
print( quote + s + quote )

解决方法

仅使用全局变量来存储,然后从一个或多个位置读取设置,对我来说看起来不错。特别考虑到这很简单。

对于另一个想法,您是否考虑过对处理程序使用闭包,如下所示:

def outer(quote):
    settings = dict(quote=quote)
    def inner():
        print(settings['quote'])
    return inner

error_handler = outer("'")

# Then you register your error_handler...
# Later when called it remembers the settings
error_handler() # prints the simple quote

考虑到您的评论,请使用类而不是闭包:

class QuotedErrorHandler:
    quote = "'"

    def handler(self,error):
        # do your thing
        print("Quote to use: {}".format(QuotedErrorHandler.quote))
        return error.upper()

QuotedErrorHandler.quote = '"'
my_handler = QuotedErrorHandler()
error_handler = my_handler.handler

print(error_handler("Some error"))
print(my_handler.quote)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...