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

Is it dubious practice to reference a global variable in a custom error_handler for python's str() function?

是否 bad/dubious/allowable 习惯在自定义 error_handler 中为 str() 函数引用(或更改)全局变量,该函数使用 codecs.register_error() 设置? (参见 https://docs.python.org/3.6/library/codecs.html#codecs.register_error.

我正在尝试实现一个自定义的 'backslashreplace' 函数,除了反斜杠转义之外,它还将结果用单引号 (') 或双引号 (") 括起来,非常类似于 gnu ls 程序在 --quoting-style=shell-escape.

时处理文件名

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

(我正在使用 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 而不是闭包:

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)