在将Python 2代码移植到Python 3时处理ctypes和ASCII字符串

 个信2502907653 发布于 2023-01-31 21:46

昨晚我厌倦了并开始将PyVISA移植到Python 3(这里的进展:https://github.com/thevorpalblade/pyvisa).

只要我将设备地址(嗯,任何字符串确实)作为ASCII字符串而不是默认的unicode字符串
传递(例如,HP = vida.instrument(b"GPIB:),我已经达到了一切正常的程度.:16")工作,而HP = vida.instrument("GPIB :: 16")不起作用,引发ValueError.

理想情况下,最终用户不必关心字符串编码.关于我应该如何处理的任何建议?ctypes类型定义中的某些东西也许?

就目前而言,相关的ctypes类型定义是:

ViString = _ctypes.c_char_p

abarnert.. 6

ctypes与Python 3中的大多数内容一样,故意不会在unicode和bytes之间自动转换.这是因为在大多数用例中,这只会要求UnicodeEncodeError人们切换到Python 3以避免相同类型的mojibake或灾难.

但是,当你知道你只处理纯ASCII时,那是另一个故事.你必须明确 - 但你可以将这种显式性分解为包装器.


正如在指定所需的参数类型(函数原型)中所解释的那样,除了标准ctypes类型之外,您还可以传递任何具有from_paramclassmethod的类 - 它通常返回具有_as_parameter_属性的某种类型的实例(通常是相同的类型),但是也只是返回一个原生ctypes类型的值.

class Asciifier(object):
    @classmethod
    def from_param(cls, value):
        if isinstance(value, bytes):
            return value
        else:
            return value.encode('ascii')

这可能不是你想要的确切规则 - 例如,它会失败bytearray(就像那样c_char_p),即使它可以安静地转换为bytes......但是你不想隐式转换intbytes.任何事情,无论你决定什么规则都应该很容易编码.


这是一个例子(在OS X上;你显然必须改变libc为Linux,Windows等加载的方式,但你可能知道如何做到这一点):

>>> libc = CDLL('libSystem.dylib')
>>> libc.atoi.argtypes = [Asciifier]
>>> libc.atoi.restype = c_int
>>> libc.atoi(b'123')
123
>>> libc.atoi('123')
123
>>> libc.atoi('???') # Unicode fullwidth digits
ArgumentError: argument 1: : 'ascii' codec can't encode character '\uff10' in position 0: ordinal not in range(128)
>>> libc.atoi(123)
ArgumentError: argument 1: : 'int' object has no attribute 'encode'

显然,如果这些异常对于您的用例不够清楚,您可以捕获异常并提出另一个异常.

您可以类似地为某个特定库编写一个Utf8ifierEncodifier(encoding, errors=None)类工厂或其他任何其他工具,并argtypes以相同的方式粘贴它.


如果您还想自动解码返回类型,请参阅返回类型和errcheck.


最后一件事:当您确定数据应该是UTF-8时,但是您想要处理它们与Python 2.x不同的情况(通过保留它们原样),你甚至可以在3.x中做到这一点.使用前面提到的Utf8ifierargtype和解码器errcheck,然后使用errors=surrogateescape.请参阅此处以获取完整示例.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有