Preventing class methods from being defined
David Hirschfield
davidh at ilm.com
Tue Jan 17 13:23:09 EST 2006
>>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)?
>
>
>
For reasons unrelated to this problem, the class that does this magic
can't take any parameters to its "__init__" method.
>>class A(object):
>>
>>
> ^--should that be R?
>
>
Yes, it should. Damn you Copy and Paste!
>> _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.
>
>
>
Yes, that's true...it shouldn't really matter for my usage. What would I
do to make this an all-instances-shared thing?
>>
>>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
>
>
I'm using python 2.3.3 here, so no go on the nice decorator, but I can
definitely use the concept to make it work, thanks.
-David
--
Presenting:
mediocre nebula.
More information about the Python-list
mailing list