[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [IMP-dev] Is it possible to write decorators in python?



I added support for exporting protected methods to python (and constructors). The methods get renamed to Class._foo() from Class.foo() on the python side to denote that they are protected. Not all of IMP has this yet, but Decorator does.

On Jun 28, 2012, at 7:33 PM, Daniel Russel wrote:

> Added imp-dev.
> 
> First, a general comment. As you point out, swig doesn't wrap protected methods, which doesn't interact well with various C++ idioms that use them. Better supporting python would require either making those methods public or doing some trickiness where they are public to swig and the swig wrappers (and visual studio since it makes the protection part of the method signature), but protected when seen by the C++ side of IMP and doxygen. It is probably worth instituting one of these as standard practice in IMP. For example by adding an IMP_PROTECTED macro that resolves to the correct one of public/protected depending on the context.
> 
> As for Decorator, the public constructor you see is, somewhat confusingly just there to illustrate what an actual decorator should look like (it only appears in doxygen). It probably makes for cleaner docs to simply link to the ExampleDecorator. I'll fix that presently.
> 
> On Jun 28, 2012, at 4:23 PM, Javier Velazquez wrote:
> 
>> Daniel,
>> 
>> Running a program with the decorator below stubbornly says:
>> def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined")
>> 
>> According to SWIG's manual no constructor is wrapped  if it is protected. It is indeed protected in Decorator.h, but you define a public constructor too. As a result of not accessing the public decorator, I can't access the member function get_particle(). There is a way around this problem using a self.particle member, but looks ugly, and I don't know if it is entirely correct. Is there a correct way to do it?
>> 
>> 
>> Thanks
>> 
>> 
>> class Price(IMP.Decorator):
>>   price_key = IMP.IntKey("price")
>> 
>>   def __init__(self, p):
>>       if not self.particle_is_instance(p):
>>           self.setup_particle(p)
>>           IMP.Decorator.__init__(self,p)
>> 
>>   def setup_particle(self, p):
>>       p.add_attribute(self.price_key, 0)
>>       return Price(p)
>> 
>>   def get_price(self):
>>       return self.get_particle().get_value(self.price_key)
>> 
>>   def set_price(self, x):
>>       self.get_particle().set_value(self.price_key, int(x))
>> 
>>   def particle_is_instance(self, p):
>>       return p.has_attribute(self.price_key)
>