Adding method to class at run-time: bad style?
Grant Edwards
invalid at invalid
Tue Apr 7 14:38:11 EDT 2009
On 2009-04-07, Scott David Daniels <Scott.Daniels at Acm.Org> wrote:
> Grant Edwards wrote:
>> I realize that technically all methods are added to classes at
>> "run-time", but what I'm talking about is this:
>>
>> import ClientForm
>>
>> def controlEqual(self,other):
>> return (self.type == other.type) and \
>> (self.name == other.name) and \
>> (self.value == other.value) and \
>> (self.disabled == other.disabled) and\
>> (self.readonly == self.readonly)
> Note:
> Here you are checking that self.readonly == self.readonly!
Doh!
> I also dislike the trailing backslashes and over-parenthesizing.
> So, I'd do it like this (using the pare to avoid the backslash):
The paren to avoid the backslashes is a good tip.
> def controlEqual(self,other):
> return (self.type == other.type
> and self.name == other.name
> and self.value == other.value
> and self.disabled == other.disabled
> and self.readonly == self.readonly)
I don't really like to rely on my memory of operator
precidence, but that's a personal problem.
> ...
>> ClientForm.Control.__eq__ = controlEqual
>> ClientForm.Control.__ne__ = controlNotEqual
>>
>> def formEqual(self,other):
>> if len(self.controls) != len(other.controls):
>> return False
>> for (c1,c2) in zip(self.controls,other.controls):
>> if c1 != c2:
>> return False
>> return True
>>
>> def formNotEqual(self,other):
>> return not (self==other)
>>
>> ClientForm.HTMLForm.__eq__ = formEqual
>> ClientForm.HTMLForm.__ne__ = formNotEqual
>
>> It works fine, but it seems like it might be dangerous (or just
>> bad form) to insert methods into existing classes like that.
>> Perhaps it would be safer to make sure that __eq__, __ne__,
>> and __cmp__ don't exist before adding my own?
>
> Well, a more standard approach would be:
> class FancyControl(ClientForm.Control):
> def __eq__(self, other):
> return (self.type == other.type
> and self.name == other.name
> and self.value == other.value
> and self.disabled == other.disabled
> and self.readonly == self.readonly)
>
> def __ne__(self, other):
> return not self.__eq__(other)
>
> class FancyHTMLForm(ClientForm.HTMLForm):
> def __eq__(self,other):
> ...
>
> def __ne__(self, other):
> return not self.__eq__(other)
>
> You'd have to make sure FancyControl and FancyClientForm get used in
> the app.
The problem is that my app never instanciates either the
Control or the HTMLForm class: that's all done by module
functions that the app calls, and they don't know about the new
classes without some trickery (e.g. below)
> The latter could be insured by monkey-patching:
> ...
> ClientForm.Control = FancyControl
> ClientForm.HTMLForm = FancyHTMLForm
>
> But substituting monkey-patching
:) How did I not know that phrase until today?
> for class method insertion seems like you are going from one
> quick and dirty technique to a slightly nicer quick and dirty
> technique.
I think like your monkey-patching solution better. It feels a
bit cleaner.
--
Grant Edwards grante Yow! ! Up ahead! It's a
at DONUT HUT!!
visi.com
More information about the Python-list
mailing list