[英]python: How to forward an instance's method call to its attribute
class Number(object):
def __init__(self):
super(Number, self).__init__()
self.data = 10
def __getattr__(self, name):
def _missing(*args, **kwargs):
method = getattr(self.data, name)
return method(args[0])
return _missing
a = Number()
b = Number()
print a.__add__(10) # this is ok!
print a + 10 # TypeError: "unsupported operand type(s) for +: 'Number' and 'int'"
print a + b # TypeError: "unsupported operand type(s) for +: 'Number' and 'Number'"
問題:“a .__ add __(10)”和“a + 10”之間的區別是什么,如何掛鈎運算符“+”?
Python只會使用實際的__add__
方法,而不是因__getattr__
而只“存在”的方法。
添加__add__ = (10).__add__
它可以正常工作。
所以你要做的是添加代理方法:
def __add__(self, *args): return self.data.__add__(*args)
def __sub__(self, *args): return self.data.__sub__(*args)
# ...
你可以試試這個,但它不漂亮:
import numbers
def redirect(name):
def redirected(self, *args):
assert len(args) <= 1
if len(args) == 1 and isinstance(args[0], Number):
return getattr(self._data, name)(args[0]._data)
else:
return getattr(self._data, name)(*args)
return redirected
names = set(['__gt__', '__ge__'])
names.update(numbers.Real.__abstractmethods__)
methods = dict((name, redirect(name)) for name in names)
methods.update(
{'__init__': lambda self, data: setattr(self, '_data', float(data))})
Number = type("Number", (), methods)
你可以像這樣使用它:
>>> a = Number(5)
>>> b = Number(7)
>>> a + 10
15.0
>>> a + b
12.0
>>> a > b
False
>>> a == Number(5.0)
True
請注意,算術運算符返回的類型是float
而不是Number
(可能與您預期的一樣,也可能不是)。
如果你想有一個整數,你可以刪除float()
調用,並更改numbers.Real
到numbers.Integral
。 但請注意,算術運算符將停止使用浮點值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.