Это другой ответ, потому что он сильно отличается от другого, который я опубликовал. (и я почувствовал, что это заслуживает того, чтобы быть отделено)
Кодекс:
class RandomInt:
def __getattr__(self, name):
attr = getattr(int, name, '')
if attr != '':
def wrapper(*args, **kw):
return attr(random.randint(1, 100), *args, **kw)
return wrapper
else:
raise AttributeError(
"'{0}' object has no attribute '{1}'".format('RandomInt',name))
Пример запуска:
>>> x = RandomInt()
>>> x
88
>>> 1 + x # __radd__
67
>>> x*100 # __mul__
1900
>>> x+5 # __add__
50
>>> x-1000 # __sub__
-945
>>> x//5 # __floordiv__
8
>>> float(x) # __float__
63.0
>>> str(x) # __str__
'75'
>>> complex(x) # __complex__
(24+0j)
>>> sum([x]*10)
573
Существует возможность для улучшения:
>>> x + x
Traceback (most recent call last):
File "<pyshell#1456>", line 1, in <module>
x + x
TypeError: unsupported operand type(s) for +: 'instance' and 'instance'
Same для x*x
, x/x
и аналогичные
Другой вариант на этот раз, похоже на @gatto's ответ:
import random, inspect
class RandomInt:
def __init__(self):
def inject(attr):
def wrapper(*args, **kw):
args = list(args)
for i,x in enumerate(args):
if isinstance(x, RandomInt):
args[i] = x+0
return attr(random.randint(1,100), *args, **kw)
return wrapper
for name in dir(int):
attr = getattr(int, name)
if inspect.ismethoddescriptor(attr):
setattr(self, name, inject(attr))
И этот имеет поддержку:
>>> x + x
49
>>> x // x
2
>>> x * x
4958
>>> x - x
77
>>> x ** x
467056167777397914441056671494001L
>>> float(x)/float(x)
0.28
еще один вариант, который использует класс атрибутов преодолеть проблему нового стиля/старого стиля (спасибо @gatto):
import random, inspect
class RandomInt(object):
pass
def inject(attr):
def wrapper(*args, **kw):
args = list(args)
for i,x in enumerate(args):
if isinstance(x, RandomInt):
args[i] = random.randint(1,100)
return attr(*args, **kw)
return wrapper
for name in dir(int):
attr = getattr(int, name)
if inspect.ismethoddescriptor(attr):
setattr(RandomInt, name, inject(attr))
Выход:
>>> x
86
>>> x
22
>>> x * x
5280
>>> [1] * x
[1, 1, 1, 1, 1, 1]
>>> x * '0123'
''
>>> s[x] # s = '' * 10
'5'
Вы говорите о динамически определении каждой функции (в списке функций добавить, мул, вычитание и т.д.) для возврата randint передается каждому методу? Изменить: нет смысла даже спрашивать, что это говорит об этом в вопросе – jamylak
@jamylak: Что-то в этом роде. Пока конечный результат заключается в том, что значение «RandomInt» появляется случайным для каждого метода. – Blender
@Blender: ah, для * каждый * способ. Да, тогда вам нужно создать методы .. И это будет работать, только если 'int' является левым операндом * или *, если левый операнд сам не определяет крючок для операции. –