Best practice for object attributes?

laotseu bdesth at removethis.free.fr
Wed Apr 2 10:22:13 EST 2003


Michael Sparks wrote:
> laotseu wrote:
> 
> 
>>One outstanding advantage of the second 'idiom' is that it's the right
>>way to define *instance* attributes !-) (which is probably what your
>>looking for)
> 
> 
> Given the first idiom seems to create instance attributes by cloning the
> current state of the class attributes, I'm finding it useful is where
> certain instance attributes are unlikely to differ much between
> instances, or changes infrequently related to object creation. 
> 
> For example: if you're creating large numbers of objects which need a
> ballpark timestamp, you could timestamp the class periodically, and
> reduce your number of calls to gettimeofday.
> 
> Another example is in a custom logging class - it has default logging
> levels for most objects defined by the class attributes, but can be
> raised/lowered on a per instance basis, or globally for all new objects
> by changing the class attributes.
> 
> 
>>With the first form you get *class* attributes.  Make 2 instances of
>>Shrubbery1, change the name of first one to 'Brian', print the name of
>>the second one, and then try to understand what is the purpose of the
>>'self' argument in methods.
> 
> 
> I'm aware of the meaning of self :) and know that the first form gives
> you class attributes. The reason I was asking is because I'd noticed
> the following interesting behaviour, which if _intentional_ is useful.
> 
> 
>>>>a=shrubbery1()
>>>>b=shrubbery1()
>>>>a.name,b.name,shrubbery1.name
>>>
> (None, None, None)                  # a.name, b.name exist - presumed
>                                     # references to shrubbery1.name
> 
>>>>a.name="hello"
>>>>a.name,b.name,shrubbery1.name
>>>
> ('hello', None, None)               # Bzzzt! a.name seems to be
>                                     # independent
> 
>>>>b.name="brian"
>>>>a.name,b.name,shrubbery1.name
>>>
> ('hello', 'brian', None)            # Hmm. So is b.name
> 
>>>>shrubbery1.name="Surprise"
>>>>a.name,b.name,shrubbery1.name
>>>
> ('hello', 'brian', 'Surprise')      # Changing class leaves existing
>                                     # instances unaffected.
> 
>>>>a=shrubbery1()                  # Get 2 fresh copies.
>>>>b=shrubbery1()
>>>>a.name,b.name,shrubbery1.name
>>>
> ('Surprise', 'Surprise', 'Surprise') # a.name, b.name cloned from
>                                      # shrubbery1.name
> 
> As far as I can tell the behaviour seems to be that you automatically
> gain instance attributes that clone the state of the class attributes
> at object creation time, which are then independent and can be modified
> via the usual self.<attr> syntax later on. (They cannot however be
> modified via the self.__dict__[<attr>] syntax since they're not stored
> there)
> 
> For reference, this behaviour holds with the following python versions:
>    * python 2.3 alpha 2
>    * python 2.2.1
>    * python 2.2.2 stackless
> 
> Given it seems consistent across versions, and seems useful (changing
> default values for later objects just by updating a class attribute -
> eg an external timestamper perhaps) I was wondering if there's a good
> reason not to use this.
> 

oops ! I should have shut my mouth :(
Ok, sorry, next time I'll try first and only then answer.

I always thought of the first form as a way to define class attributes, 
and never tried to use it the way you did. And effectively, it works as 
you noticed (python 2.2.x), and may be useful sometimes.

Just one more thing I noticed :
 >>>class Toto:
 >>>    name = 'toto'
 >>>    def __init__(self, age)
 >>>        self.age = age
 >>>
 >>>a = Toto(42)
 >>>a.age
42
 >>>a.name
'toto'
 >>>a.__dict__
{'age' : 42}

Until there, ok. Now if we set a.name...
 >>>a.name = 'tutu'
 >>>a.__dict__
{'age' : 42, 'name' : 'tutu'}

So if you try to modify this [class ??? instance ??? or what ???] 
attribute, you in fact create a new instance attribute that hides the 
[class ??? instance ??? whatsoever ???] one.

Do we have a guru 'round here ?-) Could use one...


Laotseu








More information about the Python-list mailing list