mic said:
Is it possible to control method exectution using similiar mechanism as with
get/setatrribute special methods for attributes? I'd like to have every (or
some of ) method of class instance run common code defined outside the class
without making any explicit references to it.
To give an example, I'd like to prepare secure environment, in which users
could execute only methods that can be accessed by them. IMO the most
universal way to do it would be to run automatically authorisation routine
before every method execution.
Regards,
Michal
setattr/getattr work with methods just as with attributes, provided you
define your setattr/getattr in the right place, i.e. in the metaclass.
Google for "simionato frozen" in c.l.py (first hit) and you will see
an example of how to make methods "safe" under accidental overriding
with this trick. Also, you may want to look at properties.
For what concern your problem (securing method execution) here I show
you another metaclass based solution, which is the less intrusive solution
(i.e. you don't change the original class).
Of course, the password mechanism I show in this example is ridicolous from
the point of view of security, but you can replace the password
step with any kind of "secure" identification mechanism you want.
Needless to say, security goes to zero if people have access to Python
and they know how to use its dynamical capabilities. Still, the method may
prevent accidental method calls:
### protecting methods from execution ####
PASSWD="xxx"
class ProtectionError(Exception): pass
def securecall(func,*args):
know_the_passwd=raw_input("Password required to use this method:")==PASSWD
if know_the_passwd: return func(*args)
else: raise ProtectionError("Wrong password given")
class Secure(type):
def __init__(cls,n,b,d):
for k,v in d.iteritems():
if hasattr(v,"__doc__") and v.__doc__=='protected':
setattr(cls,k,lambda self,*args: securecall(v,self,*args))
class C(object):
__metaclass__=Secure
def f(self,*args):
"protected"
print "Doing something if the user know the password"
C().f()
# END
Here you protect your methods by using a docstring containing the word
"protected". It is easy to try variations of this idea.
HTH,
Michele