栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

c_ulong的rshift的ctypes重新实现

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c_ulong的rshift的ctypes重新实现

由于

_ctypes._SimpleCData
类型没有
Py_TPFLAGS_CHECKTYPES
标志,因此2.x子类被视为
__coerce__
在二进制运算中使用的旧式数字。有关调用方案和函数中的实现,请参见Objects
/
abstract.c

binary_op1

出于演示目的,可以在类型对象上切换此标志,您只需要

void *
tp_flags
字段中定义(可能有很多)。

骇客
PyTypeObject

from ctypes import *import _ctypesPy_TPFLAGS_CHECKTYPES = 1 << 4class PyTypeObject(Structure):    _fields_ = (('ob_refcnt', c_ssize_t),     ('ob_type', c_void_p),     ('ob_size', c_ssize_t),     ('tp_name', c_char_p),     ('tp_basicsize', c_ssize_t),     ('tp_itemsize', c_ssize_t),     ('tp_dealloc', c_void_p),     ('tp_print', c_void_p),     ('tp_getattr', c_void_p),     ('tp_setattr', c_void_p),     ('tp_compare', c_void_p),     ('tp_repr', c_void_p),     ('tp_as_number', c_void_p),     ('tp_as_sequence', c_void_p),     ('tp_as_mapping', c_void_p),     ('tp_hash', c_void_p),     ('tp_call', c_void_p),     ('tp_str', c_void_p),     ('tp_getattro', c_void_p),     ('tp_setattro', c_void_p),     ('tp_as_buffer', c_void_p),     ('tp_flags', c_long))

接下来,创建一个

unsignedlong
子类,并使用
from_address
工厂为其创建一个
PyTypeObject
。使用内建获取地址,内建
id
是特定于CPython的实现细节:

class c_ulong(_ctypes._SimpleCData):    _type_ = "L"    def __rshift__(self, other):        print '__rshift__', self, other        if hasattr(other, 'value'): other = other.value        return c_ulong(self.value >> other)c_ulong_type = PyTypeObject.from_address(id(c_ulong))

演示版

>>> a = c_ulong(16)>>> b = c_ulong(2)>>> a >> b__rshift__ c_ulong(16L) c_ulong(2L)c_ulong(4L)>>> a >> 2Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for >>: 'c_ulong' and 'int'

最后一步按预期失败。现在设置标志:

>>> c_ulong_type.tp_flags |= Py_TPFLAGS_CHECKTYPES>>> a >> 2__rshift__ c_ulong(16L) 2c_ulong(4L)

问题解决了?但这是骇客。再次尝试

__coerce__
实施。


实行
__coerce__

class c_ulong(_ctypes._SimpleCData):    _type_ = "L"    def __rshift__(self, other):        print '__rshift__', self, other        if hasattr(other, 'value'): other = other.value        return c_ulong(self.value >> other)    def __coerce__(self, other):        print '__coerce__', self, other        try: return self, self.__class__(other)        except TypeError: return NotImplemented

演示版

>>> a = c_ulong(16)>>> b = c_ulong(2)>>> a >> 2__coerce__ c_ulong(16L) 2__rshift__ c_ulong(16L) c_ulong(2L)c_ulong(4L)>>> 16 >> b__coerce__ c_ulong(2L) 16__rshift__ c_ulong(16L) c_ulong(2L)c_ulong(4L)

当然,如果

c_ulong
无法创建,则失败,例如
float

>>> a >> 2.0__coerce__ c_ulong(16L) 2.0Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for >>: 'c_ulong' and 'float'


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/455859.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号