Мне нужно написать класс, который реализует 32-разрядные целые числа без знака так же, как они работают на языке программирования C. То, что я забочусь о большинстве являются бинарными сдвиги, но я вообще хочу, чтобы мой класс:Python 3 __getattr__ ведет себя иначе, чем в Python 2?
- имеют одинаковый интерфейс
int
имеет и работает сint
надлежащим - Любая операция с моим
U32
класса (ИНТU32
,U32
+ ИНТ и т.д.) также возвращает U32 - быть чисто-питона - Я не хочу использовать NumPy, ctypes и т.д.
Как можно найти в this answer, я получил решение, которое работает под Python 2. Недавно я попытался запустить его под Python 3 и заметил, что в то время как следующий тестовый код работает отлично под более старыми версиями Python, Python 3 вызывает ошибку:
class U32:
"""Emulates 32-bit unsigned int known from C programming language."""
def __init__(self, num=0, base=None):
"""Creates the U32 object.
Args:
num: the integer/string to use as the initial state
base: the base of the integer use if the num given was a string
"""
if base is None:
self.int_ = int(num) % 2**32
else:
self.int_ = int(num, base) % 2**32
def __coerce__(self, ignored):
return None
def __str__(self):
return "<U32 instance at 0x%x, int=%d>" % (id(self), self.int_)
def __getattr__(self, attribute_name):
print("getattr called, attribute_name=%s" % attribute_name)
# you might want to take a look here:
# https://stackoverflow.com/q/19611001/1091116
r = getattr(self.int_, attribute_name)
if callable(r): # return a wrapper if integer's function was requested
def f(*args, **kwargs):
if args and isinstance(args[0], U32):
args = (args[0].int_,) + args[1:]
ret = r(*args, **kwargs)
if ret is NotImplemented:
return ret
if attribute_name in ['__str__', '__repr__', '__index__']:
return ret
ret %= 2**32
return U32(ret)
return f
return r
print(U32(4)/2)
print(4/U32(2))
print(U32(4)/U32(2))
А вот ошибка :
Traceback (most recent call last):
File "u32.py", line 41, in <module>
print(U32(4)/2)
TypeError: unsupported operand type(s) for /: 'U32' and 'int'
похоже getattr
трюк не дозвонились вообще в Python 3. Почему? Как я могу получить этот код, работающий как под Python 2, так и 3?
Не могли бы вы показать пример метакласса '__getattr__'? – d33tah
После этого ответ будет завершен, и я буду рад принять его. – d33tah
@ d33tah: Я добирался до него. :-) Я напишу вам конкретную, тем временем, взгляните на этот [мой старый ответ] (http://stackoverflow.com/a/11281744). –