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... -- http://mail.python.org/mailman/listinfo/python-list