问题描述
在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)