Adding method to class at run-time: bad style?
Scott David Daniels
Scott.Daniels at Acm.Org
Tue Apr 7 13:09:10 EDT 2009
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!
I also dislike the trailing backslashes and over-parenthesizing.
So, I'd do it like this (using the pare to avoid the backslash):
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)
...
> 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 latter could be insured by monkey-patching:
...
ClientForm.Control = FancyControl
ClientForm.HTMLForm = FancyHTMLForm
But substituting monkey-patching for class method insertion seems like
you are going from one quick and dirty technique to a slightly nicer
quick and dirty technique.
--Scott David Daniels
Scott.Daniels at Acm.Org
More information about the Python-list
mailing list