define
Duncan Booth
duncan at NOSPAMrcp.co.uk
Tue May 13 04:58:31 EDT 2003
bokr at oz.net (Bengt Richter) wrote in news:b9ohig$i07$0 at 216.39.172.122:
>>I would probably write the former as:
>>
>>(a, b, c, sign) = (self.a, self.b, self.c, self.sign)
>>self.y = (-b + sign*sqrt(b**2 - 4.0*a*c))/2.0*a
>>
>>Maybe the present request could be satisfied by finding a way to simplify
>>the compound assignment?
>>
> Hm, ...
>
> (a, b, c, sign) = self.(a, b, c, sign)
> self.y = (-b + sign*sqrt(b**2 - 4.0*a*c))/2.0*a
>
> ??
Let's not forget that Python does have a builtin macro processor, called
Python. Here, by adding a lot of code, is one way to completely hide the
assignment from self.
Health warning: read from the bottom up, the bit of interest is the 'class
C'. Or maybe don't read at all.
The metaclass version of this is left as an exercise for Alex. :-)
---- test.py ----
import inspect, sys
from math import sqrt
def mkwrapper(fn, nArgs = sys.maxint-1):
argnames, positional, keyword = inspect.getargs(fn.func_code)
if argnames:
selfname = argnames[0]
wrappedargs = argnames[1:nArgs+1]
unwrapped = argnames[:1] + argnames[nArgs+1:]
wrappedcall = (argnames[:1] +
[ "%s.%s" % (selfname, arg) for arg in wrappedargs ] +
argnames[nArgs+1:])
if positional:
unwrapped += ["*" + positional]
wrappedcall += ["*" + positional]
if keyword:
unwrapped += ["**" + keyword]
wrappedcall += ["**" + keyword]
commasep = ", ".join
return fn.func_name, commasep(unwrapped), commasep(wrappedcall)
def argsFromSelf(fn, nArgs=sys.maxint-1):
'''argsFromSelf(fn, [nArgs])
Create a new function which calls the original but takes
some or all arguments as attributes of the first argument.
e.g.
def fn(self, x, y, z):
...
fn = argsFromSelf(fn, 2)
is (roughly) equivalent to:
def fn(self, z):
x, y = self.x, self.y
...
'''
name, argsin, argsout = mkwrapper(fn, nArgs)
code = '''\
def wrapit(fn):
def %s(%s):
return fn(%s)
return %s
''' % (name, argsin, argsout, name)
namespace = {}
exec code in globals(), namespace
return namespace['wrapit'](fn)
import unittest
class TestWrapper(unittest.TestCase):
def testNoArgs(self):
def f(): pass
self.assertEquals(mkwrapper(f),
('f', '', ''))
def testSelfOnly(self):
def f(slf): pass
self.assertEquals(mkwrapper(f),
('f', 'slf', 'slf'))
def testOneArg(self):
def f(slf, arg1): pass
self.assertEquals(mkwrapper(f),
('f', 'slf', 'slf, slf.arg1'))
def testSeveral(self):
def f(slf, arg1, arg2, arg3): pass
self.assertEquals(mkwrapper(f),
('f', 'slf', 'slf, slf.arg1, slf.arg2, slf.arg3'))
self.assertEquals(mkwrapper(f, 1),
('f', 'slf, arg2, arg3', 'slf, slf.arg1, arg2, arg3'))
def testpositional(self):
def g(self, arg1, *args): pass
self.assertEquals(mkwrapper(g),
('g', 'self, *args', 'self, self.arg1, *args'))
def testkw(self):
def g(self, arg1, **kw): pass
self.assertEquals(mkwrapper(g),
('g', 'self, **kw', 'self, self.arg1, **kw'))
def testInClass(self):
class C:
def __init__(self, a, b, c, sign):
self.a, self.b, self.c, self.sign = a, b, c, sign
def root(self, a, b, c, sign):
return (-b + sign*sqrt(b**2 - 4.0*a*c))/(2.0*a)
# def root1(self, sign): ...
root1 = argsFromSelf(root, nArgs = 3)
# def root(self): ...
root = argsFromSelf(root)
inst = C(1, 4, 3, 1)
self.assertEquals(inst.root(), -1.0)
self.assertEquals(inst.root1(sign=1), -1.0)
self.assertEquals(inst.root1(-1), -3.0)
if __name__=='__main__':
unittest.main()
-----------------
--
Duncan Booth duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
More information about the Python-list
mailing list