Does altering a private member decouple the property's value?
Bruno Desthuilliers
bruno.42.desthuilliers at wtf.websiteburo.oops.com
Wed Jun 20 08:37:33 EDT 2007
Ethan Kennerly a écrit :
> Hello,
>
> There are a lot of Python mailing lists. I hope this is an appropriate one
> for a question on properties.
It is.
> I am relatively inexperienced user of Python. I came to it to prototype
> concepts for videogames. Having programmed in C, scripted in Unix shells,
> and scripted in a number of proprietary game scripting languages, I'm
> impressed at how well Python meets my needs. In almost all respects, it
> does what I've been wishing a language would do.
So welcome onboard !-)
> One example is properties. I really like properties for readonly
> attributes, and their ability to make the interface more elegant, by hiding
> uninteresting methods (like dumb get/set accessors).
FWIW, since Python has properties, you often just don't need the
getter/setter pairs. Start with a plain publi attribute, then switch to
a computed one (using property or a custom descriptor) if and when needed.
>
> But a gotcha bit me in the behavior of properties that I didn't expect.
> If another function accesses an underlying data member of a property, then
> the data member returned by the property is no longer valid.
>
> Here is a session example.
>
>>>> class a_class:
oops ! properties don't work properly with old-style classes. Use a
new-style class instead:
class AClass(object):
> ... def __init__( self ): self.__p = None
> ... def __set_p( self, new_p ): self.__p = new_p
Take care, the name mangling invoked by the '__name' scheme may lead to
undesired results. This feature should only be used when you want to
make sure an attribute will not be accidentally used in a derived class.
The idiomatic way to mark an attribute as "implementation" is a single
leading underscore, ie: '_name'.
> ... def reset( self ): self.__p = None
> ... p = property( lambda self: self.__p, __set_p )
> ...
(snip)
>
> I had wanted to access the private data member in the class to avoid
> side-effects of the set method.
>
> Can someone show me how to reference the data member underlying a property
> and update the property without calling the property set method?
cf above.
While we're at it, everything in Python being an object - yes, functions
and methods too -, and there's nothing like a "private" modifier in
Python. So s/private data member/implementation attribute/ !-)
> By the way, I thought maybe that a variable outside of an __init__ method
> would be static,
An attribute defined in the class body (ie not in a method) becomes a
class attribute (shared by all instances).
> but as far as I can tell, it is dynamic. For example, the
> following class appeared equivalent to the above for tests.
>
>>>> class a_class:
> ... __p = None # No __init__
here, you create a class attribute
> ... def __set_p( self, new_p ): self.__p = new_p
And here, you create an instance attribute that will shadow the class
attribute.
>
> I preferred not having the __init__ for this example and my prototype,
> because I wasn't doing anything fancy, and it meant one less method that the
> programmer needed to see.
There are other ways to obtain the same result. Like defining the
__new__ method (the proper constructor).
(snip the rest)
I think you should take some time to learn the Python object model -
trying to apply C++/Java concepts to Python won't do it. Articles about
new-style classes and descriptors on python.org should be a good
starting point.
My 2 cents...
More information about the Python-list
mailing list