A better self
Duncan Booth
duncan at NOSPAMrcp.co.uk
Mon Jul 22 05:12:53 EDT 2002
Grant Griffin <not.this at seebelow.org> wrote in
news:ah9p0o01ds at drn.newsguy.com:
> For example:
>
> with self:
> result=sin(t)*x**y+sqrt(z) # A pretend formula
>
> I don't know if there's a technical reason (in terms of either Python
> grammar or C implementation) why this wouldn't work, but perhaps it's
> not in Python because:
>
> 1) explicit is better than implicit
> 2) there should be one--and preferably only one--way to do things
It isn't in Python for a variety or reasons (your two among them), but
perhaps more because there is no way in your scheme to tell which of
result, t, x, y, and z are members of the self instance, and which are
global (or in result's case local) variables. Languages which require you
to declare all the member variables in advance can get away with this sort
of usage, but they then introduce new problems. Even in C++ it can be
impossible to tell whether a variable in a function is implicitly
referencing a member variable or a global of the same name.
An alternative which is proposed from time to time would be implementable:
with self:
result=sin(.t)*.x**.y+sqrt(.z) # A pretend formula
This has the advantage of tagging the member variables, but is thought by
many to reduce readability and be error prone. Perhaps someone should put
it into a patch though so people could try it out. If Python supported this
format you might even allow functions to default to assuming a 'with' block
on their first argument. Then again, see your #1 above.
Of course, Python being what it is, there are ways to simulate some of what
people want without changing the language at all. Try the code below:
----- begin magic.py -----
# How to make methods magically access member variables.
#
import new
from math import sin, sqrt
def withself(method):
'''withself(method)
Converts an unbound method into a method where all global variables
are assumed to come from the instance.
Global variables are accessible only if the instance sets
self.__builtins__=globals()
Builtins are not accessible unless you do:
self.__builtins__=__builtins__
'''
def callwith(self, *args, **kw):
f = new.function(method.func_code,
self.__dict__,
method.func_name,
method.func_defaults or ())
return f(self, *args, **kw)
return callwith
class C:
def __init__(self, x, y, z):
self.x, self.y, self.z = x, y, z
# Makes global variables visible to formulae
self.__builtins__ = globals()
def formula(self):
return x + y - z
formula = withself(formula)
def updater(self):
global x
x += 1
updater = withself(updater)
def formula2(self):
return sqrt(y*z)
formula2 = withself(formula2)
test = C(3, 7, 2)
print test.formula()
test.updater()
print test.formula()
print test.formula2()
----- end magic.py -----
--
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