On Mon, 16 Jan 2006 18:55:43 -0800, David Hirschfield <[EMAIL PROTECTED]> wrote:
>Thanks for this, it's a great list of the ways it can be done. Here's a Actually, your way is yet another ;-) >bit more insight into the arrangement I'm trying to get: > >restrict = True Why a global value? If it is to affect class instantiation, why not pass it or a value to the constructor, e.g., C(True) or C(some_bool)? > >class A(object): ^--should that be R? > _restrict = ["test"] > > def _null(self, *args, **kws): > raise Exception,"not allowed to access" > > def test(self): > print "test restricted" > > def __init__(self): > if restrict: > for f in self._restrict: > setattr(self,f,self._null) I assume you know that you are using a bound method attribute on the instance to shadow the method of the class, for a per-instance effect as opposed to an all-instances shared effect. > >class C(R): > def __init__(self): > super(C,self).__init__() > > def test(self): > print "test from c" > > >In this design, calling c.test() where c is an instance of C will raise >an exception. Now, the only thing I'd like is to not have to fill out >that _restrict list like that, but to have some function or something >that let's me say which methods are restricted in the same way you >define class methods or properties, i.e.: > >class A(object): > _restrict = [] > > def _null(self, *args, **kws): > raise Exception,"not allowed to access" > > def test(self): > print "test restricted" > restrict(test) > #### this does some magic to insert "test" into the _restrict list > > >I can't really find a way to make that work with descriptors, and it >can't just be a function call, because I won't know what object to get >the _restrict list from. Is there a way to refer to the class that "is >being defined" when calling a function or classmethod? >So, ideas on how to accomplish that...again, greatly appreciated. You can do it with a decorator, though it doesn't really do decoration, just adding the decoratee to the associated _restrict list. You don't have to factor out mkrdeco if you'r'e only defining the restrict decorator in one class. I changed A to R, and made the global restriction flag a constructor argument, but you can easily change that back, either by using the global restricted in R.__init__ as a global, or by passing it explicitly like c = C(restricted). >>> def mkrdeco(rlist): ... def restrict(f): ... rlist.append(f.func_name) ... return f ... return restrict ... >>> class R(object): ... _restrict = [] ... restrict = mkrdeco(_restrict) ... def _null(self, *args, **kws): ... raise Exception,"not allowed to access" ... def __init__(self, restricted): ... if restricted: ... for f in self._restrict: ... setattr(self,f,self._null) ... @restrict ... def test(self): ... print "test restricted" ... >>> class C(R): ... def __init__(self, restricted=False): ... super(C,self).__init__(restricted) ... ... def test(self): ... print "test from c" ... >>> c = C(True) >>> c.test() Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 5, in _null Exception: not allowed to access >>> c2 = C(False) >>> c2.test() test from c >>> vars(c) {'test': <bound method C._null of <__main__.C object at 0x02EF3C4C>>} >>> vars(c2) {} >>> R._restrict ['test'] Still don't know what real application problem this is solving, but that's ok ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list