Warning when new attributes are added to classes at run time
Nick Vatamaniuc
vatamane at gmail.com
Thu Jul 20 13:39:12 EDT 2006
Use __slots__ they will simply give you an error. But at the same time
I don't think they are inheritable and in general you should only use
slots for performance reasons (even then test before using).
Or you could also simulate a __slots__ mechanism the way you are doing
i.e. checking the attributes yourself. But I would suggest though that
you create a test case (unittest) and run testing _separately_ from
your code. Your code should do only what it does, too many "if i
messed: up warn me" or "need to make sure I don't have extra
attributes" checks would make the code itself incomprehnsible over time
as half of it would end up being just checks for exceptional
situations. So spend 5 minutes to look up
http://pyunit.sourceforge.net/ and then in the long run your effort to
implement testing will be rewarded.
Nick V.
Matthew Wilson wrote:
> I sometimes inadvertently create a new attribute on an object rather
> update a value bound to an existing attribute. For example:
>
> In [5]: class some_class(object):
> ...: def __init__(self, a=None):
> ...: self.a = a
> ...:
>
> In [6]: c = some_class(a=1)
>
> In [7]: c.a
> Out[7]: 1
>
> In [8]: c.A = 2
>
> I meant to update c.a but I created a new c.A. I make this mistake
> probably hourly.
>
> I suspect adding attributes at run time can be a beautiful thing, but in
> this particular instance, I'm only using this feature to hurt myself.
>
> I wrote a simple class that will warn me when I make this mistake in the
> future:
>
> import warnings
>
> class C(object):
>
> warn_on_new_attributes = True
>
> standard_attributes = []
>
> def __setattr__(self, name, value):
>
> if self.warn_on_new_attributes \
> and name is not 'warn_on_new_attributes' \
> and name not in self.standard_attributes:
>
> warnings.warn("%s has no standard attribute %s."
> % (self.__class__.__name__, name))
>
>
> self.__dict__[name] = value
>
>
> class C1(C):
>
> standard_attributes = ['a1', 'a2']
>
>
> class C2(C):
>
> warn_on_new_attributes = False
>
> # Do some simple testing.
> c11 = C1()
> c11.a1 = 1
> c11.a2 = 2
> c11.a3 = 3
> c11.a4 = 4
>
> # Disable warnings for this instance.
> c12 = C1()
> c12.warn_on_new_attributes = False
> c12.a1 = 1
> c12.a2 = 2
> c12.a3 = 3
> c12.a4 = 4
>
> c11.a5 = 5
>
> # Use an object that has warnings disabled by default.
> c2 = C2()
> c2.a1 = 1
> c2.a2 = 2
> c2.a3 = 3
> c2.a4 = 4
>
> # enable warnings for this object.
> c2.warn_on_new_attributes = True
> c2.a1 = 1
> c2.a5 = 5
>
>
> All comments are welcome. Is there a better way of implementing the
> above class, OR, is this approach generally wrong-headed? Am I the only
> one that makes this mistake?
>
> TIA
>
> --
> A better way of running series of SAS programs:
> http://overlook.homelinux.net/wilsonwiki/SasAndMakefiles
More information about the Python-list
mailing list