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