1.1 --- a/lib/operator.py Sun May 30 21:09:08 2010 +0200
1.2 +++ b/lib/operator.py Wed Jun 02 22:00:29 2010 +0200
1.3 @@ -19,19 +19,19 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -def binary_op(a, b, left_name, right_name):
1.8 +def binary_op(a, b, left_accessor, right_accessor):
1.9
1.10 """
1.11 A single parameterised function providing the binary operator mechanism for
1.12 - arguments 'a' and 'b' using methods of the given 'left_name' and
1.13 - 'right_name'.
1.14 + arguments 'a' and 'b' using accessors given as 'left_accessor' and
1.15 + 'right_accessor' which provide the methods for the operands.
1.16 """
1.17
1.18 # First, try and get a method for the left argument, and then call it with
1.19 # the right argument.
1.20
1.21 try:
1.22 - fn = getattr(a, left_name)
1.23 + fn = left_accessor(a)
1.24 except AttributeError:
1.25 pass
1.26 else:
1.27 @@ -43,7 +43,7 @@
1.28 # with the left argument.
1.29
1.30 try:
1.31 - fn = getattr(b, right_name)
1.32 + fn = right_accessor(b)
1.33 except AttributeError:
1.34 pass
1.35 else:
1.36 @@ -56,40 +56,48 @@
1.37
1.38 raise TypeError
1.39
1.40 +# Concrete operator functions.
1.41 +# These functions defer method lookup by wrapping the attribute access in
1.42 +# lambda functions. Thus, the appropriate methods are defined locally, but no
1.43 +# attempt to obtain them is made until the generic function is called.
1.44 +
1.45 +# NOTE: The compiler should make it possible for these to call the generic
1.46 +# NOTE: operator implementation with no additional call overhead.
1.47 +
1.48 def add(a, b):
1.49 - return binary_op(a, b, "__add__", "__radd__")
1.50 + return binary_op(a, b, lambda a: a.__add__, lambda b: b.__radd__)
1.51
1.52 def and_(a, b):
1.53 - return binary_op(a, b, "__and__", "__rand__")
1.54 + return binary_op(a, b, lambda a: a.__and__, lambda b: b.__rand__)
1.55
1.56 def div(a, b):
1.57 - return binary_op(a, b, "__div__", "__rdiv__")
1.58 + return binary_op(a, b, lambda a: a.__div__, lambda b: b.__rdiv__)
1.59
1.60 def floordiv(a, b):
1.61 - return binary_op(a, b, "__floordiv__", "__rfloordiv__")
1.62 + return binary_op(a, b, lambda a: a.__floordiv__, lambda b: b.__rfloordiv__)
1.63
1.64 def lshift(a, b):
1.65 - return binary_op(a, b, "__lshift__", "__rlshift__")
1.66 + return binary_op(a, b, lambda a: a.__lshift__, lambda b: b.__rlshift__)
1.67
1.68 def mod(a, b):
1.69 - return binary_op(a, b, "__mod__", "__rmod__")
1.70 + return binary_op(a, b, lambda a: a.__mod__, lambda b: b.__rmod__)
1.71
1.72 def mul(a, b):
1.73 - return binary_op(a, b, "__mul__", "__rmul__")
1.74 + return binary_op(a, b, lambda a: a.__mul__, lambda b: b.__rmul__)
1.75
1.76 def or(a, b):
1.77 - return binary_op(a, b, "__or__", "__ror__")
1.78 + return binary_op(a, b, lambda a: a.__or__, lambda b: b.__ror__)
1.79
1.80 def pow(a, b):
1.81 - return binary_op(a, b, "__pow__", "__rpow__")
1.82 + return binary_op(a, b, lambda a: a.__pow__, lambda b: b.__rpow__)
1.83
1.84 def rshift(a, b):
1.85 - return binary_op(a, b, "__rshift__", "__rrshift__")
1.86 + return binary_op(a, b, lambda a: a.__rshift__, lambda b: b.__rrshift__)
1.87
1.88 def sub(a, b):
1.89 - return binary_op(a, b, "__sub__", "__rsub__")
1.90 + return binary_op(a, b, lambda a: a.__sub__, lambda b: b.__rsub__)
1.91
1.92 def xor(a, b):
1.93 - return binary_op(a, b, "__xor__", "__rxor__")
1.94 + return binary_op(a, b, lambda a: a.__xor__, lambda b: b.__rxor__)
1.95
1.96 # vim: tabstop=4 expandtab shiftwidth=4