Immutability

N

Nick Maclaren

The way that I read it, Python allows only values (and hence types)
to be immutable, and not class members. The nearest approach to the
latter is to use the name hiding conventions.

Is that correct?


Regards,
Nick Maclaren.
 
R

Robert Kern

Nick said:
The way that I read it, Python allows only values (and hence types)
to be immutable, and not class members. The nearest approach to the
latter is to use the name hiding conventions.

Is that correct?

You can also make properties that don't allow writing.

class Foo(object):

def __init__(self, bar):
self._bar = bar

@property
def bar(self):
return self._bar

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
N

Nick Maclaren

|> > The way that I read it, Python allows only values (and hence types)
|> > to be immutable, and not class members. The nearest approach to the
|> > latter is to use the name hiding conventions.
|> >
|> > Is that correct?
|>
|> You can also make properties that don't allow writing.
|>
|> class Foo(object):
|>
|> def __init__(self, bar):
|> self._bar = bar
|>
|> @property
|> def bar(self):
|> return self._bar

Thanks very much. And, what's more, I have even found its documentation!
Whatsnew2.2. The 2.4.2 reference is, er, unhelpful.

One of Python's less-lovable attributes is the inscrutability of its
documentation :-(

But you knew that ....


Regards,
Nick Maclaren.
 
G

Georg Brandl

Nick said:
|> > The way that I read it, Python allows only values (and hence types)
|> > to be immutable, and not class members. The nearest approach to the
|> > latter is to use the name hiding conventions.
|> >
|> > Is that correct?
|>
|> You can also make properties that don't allow writing.
|>
|> class Foo(object):
|>
|> def __init__(self, bar):
|> self._bar = bar
|>
|> @property
|> def bar(self):
|> return self._bar

Thanks very much. And, what's more, I have even found its documentation!
Whatsnew2.2. The 2.4.2 reference is, er, unhelpful.

Is it?

http://docs.python.org/lib/built-in-funcs.html

documents "property" quite well.

Georg
 
N

Nick Maclaren

|> >
|> > Thanks very much. And, what's more, I have even found its documentation!
|> > Whatsnew2.2. The 2.4.2 reference is, er, unhelpful.
|>
|> Is it?
|>
|> http://docs.python.org/lib/built-in-funcs.html
|>
|> documents "property" quite well.

Sigh. No. It's terrible. What it documents is the use of the property
FUNCTION. It does not document what properties ARE, and how they interact
with the rest of the language. Until you know that, it is so ambiguous
as to be almost totally useless - and it is THAT information that needs to
be in the reference manual, but is only in whatsnew2.2.


Regards,
Nick Maclaren.
 
D

Diez B. Roggisch

Sigh. No. It's terrible. What it documents is the use of the property
FUNCTION. It does not document what properties ARE, and how they interact
with the rest of the language. Until you know that, it is so ambiguous
as to be almost totally useless - and it is THAT information that needs to
be in the reference manual, but is only in whatsnew2.2.

I have to second that - I found myself reading through "What's new" from
various versions to find that specific feature. It would be at least good
to see all of them grouped together to make an easier read. Still, that is
not optimal.

Diez
 
B

Bruno Desthuilliers

Nick said:
The way that I read it, Python allows only values (and hence types)
to be immutable,

I don't understand this sentence. Some types are immutable, some are
not. This has nothing to do with "values" (FWIW, everything in Python is
an object, there's no 'primitive type' vs 'object type' distinction)
and not class members.

If an attribute is of an immutable type, it will still be immutable.

If what you want is 'read-only' attributes, then use properties:

class MyClass(object):
def __init__(self, name):
self._name = name
name = property(fget=lambda self : self._name)
Traceback (most recent call last):
The nearest approach to the
latter is to use the name hiding conventions.

naming conventions are used to denote what's API and what's
implementation. But this won't make an attribute read-only. If you want
an attribute to be part of the API *but* read-only, use the solution above.

HTH
 
S

Sion Arrowsmith

Nick Maclaren said:
|> [ attributions lost ]
|> > Thanks very much. And, what's more, I have even found its documentation!
|> > Whatsnew2.2. The 2.4.2 reference is, er, unhelpful.
|> Is it?
|> http://docs.python.org/lib/built-in-funcs.html
|> documents "property" quite well.
Sigh. No. It's terrible. What it documents is the use of the property
FUNCTION. It does not document what properties ARE, and how they interact
with the rest of the language. Until you know that, it is so ambiguous
as to be almost totally useless - and it is THAT information that needs to
be in the reference manual, but is only in whatsnew2.2.

Actually, there's an almost throw-away mention in
http://docs.python.org/ref/descriptor-invocation.html
which gives you what you need (although not, I have to say, in an
easily digestible form).

What I've not seen documented anywhere is the:
@property
def fset(self, value):
...
idiom. It's not obvious from the documentation of the property
function that it can be used as a decorator like this. (cf.
classmethod and staticmethod.)
 
G

Gerard Flanagan

Nick said:
|> >
|> > Thanks very much. And, what's more, I have even found its documentation!
|> > Whatsnew2.2. The 2.4.2 reference is, er, unhelpful.
|>
|> Is it?
|>
|> http://docs.python.org/lib/built-in-funcs.html
|>
|> documents "property" quite well.

Sigh. No. It's terrible. What it documents is the use of the property
FUNCTION. It does not document what properties ARE, and how they interact
with the rest of the language. Until you know that, it is so ambiguous
as to be almost totally useless - and it is THAT information that needs to
be in the reference manual, but is only in whatsnew2.2.

There are (unofficial) documentation wikis here:

pytut.infogami.com
pyref.infogami.com
pyfaq.infogami.com

You might like to consider adding the information you perceive to be
lacking.

All the best.

Gerard
 
F

Fredrik Lundh

Sion said:
What I've not seen documented anywhere is the:
@property
def fset(self, value):
...
idiom. It's not obvious from the documentation of the property
function that it can be used as a decorator like this.

probably because it cannot be used in that way: the "property" function
takes the *getter* as its first argument, so you can only use this for read-
only properties...

</F>
 
G

Georg Brandl

Steve said:
I can't really agree that "quite good" documentation doesn't refer to
the use of property as a decorator. It's obvious that a ncessary upgrade
to the docs didn't happen (and we can all understand why, I am sure).

In my opinion property isn't really meant to be used as a decorator since
it's impossible to create a read-write property. The decorator pattern
doesn't really fit here.

What I agree is that it's not really defined what a "property" object
is and what its properties are. For that, documentation patches are
welcome.

Georg
 
S

Sion Arrowsmith

Fredrik Lundh said:
probably because it cannot be used in that way: the "property" function
takes the *getter* as its first argument, so you can only use this for read-
only properties...

Ahem. Yes. What I obviously meant to write was:

What I've not seen documented anywhere is the:
@property
def fget(self):
...
idiom. [ ... ]

(As correctly written by someone else further upthread.) It is possible
to find it described by Googling, but the Cookbook (and python.org) hits
provide much more complicated general-purpose (ie setters as well)
property decorators.
 
N

Nick Maclaren

|>
|> There are (unofficial) documentation wikis here:
|>
|> pytut.infogami.com
|> pyref.infogami.com
|> pyfaq.infogami.com

Thanks very much.

|> You might like to consider adding the information you perceive to be
|> lacking.

Consider it considered, but I have to start by understanding what is
supposed to happen and what does happen, precisely and in detail.


Regards,
Nick Maclaren.
 
N

Nick Maclaren

|>
|> Actually, there's an almost throw-away mention in
|> http://docs.python.org/ref/descriptor-invocation.html
|> which gives you what you need (although not, I have to say, in an
|> easily digestible form).

Thanks very much.

|> What I've not seen documented anywhere is the:
|> @property
|> def fset(self, value):
|> ...
|> idiom. It's not obvious from the documentation of the property
|> function that it can be used as a decorator like this. (cf.
|> classmethod and staticmethod.)

Most especially since it isn't working very well for me, and I am trying
to track down why. When I run:

class alf :
def pete (self) :
print "Inside pete\n"

b = alf()
b.pete()

class fred :
@property
def joe (self) :
print "Inside /joe\n"

a = fred()
a.joe()

I get:

Inside pete

Inside joe

Traceback (most recent call last):
File "crap.py", line 14, in <module>
a.joe()
TypeError: 'NoneType' object is not callable

VERY weird - I could understand it if I got the error and DIDN'T succeed
in the call ....
Regards,
Nick Maclaren.
 
F

Fredrik Lundh

Nick said:
class fred :
@property
def joe (self) :
print "Inside /joe\n"

a = fred()
a.joe()

Traceback (most recent call last):
File "crap.py", line 14, in <module>
a.joe()
TypeError: 'NoneType' object is not callable

VERY weird - I could understand it if I got the error and DIDN'T succeed
in the call ....

a property looks like an attribute, not a method, so you're trying to call whatever
your "joe()" method returns.

(that's what "a function for getting an attribute value" in the property documentation
refers to).

</F>
 
N

Nick Maclaren

|>
|> a property looks like an attribute, not a method, so you're trying to call whatever
|> your "joe()" method returns.

Well, yes, that was pretty obvious - but what was NOT obvious is why it
should do that for one of two identical methods.

|> (that's what "a function for getting an attribute value" in the property documentation
|> refers to).

Well, as joe is an attribute of the class fred, and the decorator is applied
to the declaration of joe within fred, I assumed that it referred to getting
joe from fred. That certainly doesn't appear to be the case, and I don't
see how it helps with my original request if not.


Regards,
Nick Maclaren.
 
B

Bruno Desthuilliers

Nick said:
|>
|> Actually, there's an almost throw-away mention in
|> http://docs.python.org/ref/descriptor-invocation.html
|> which gives you what you need (although not, I have to say, in an
|> easily digestible form).

Thanks very much.

|> What I've not seen documented anywhere is the:
|> @property
|> def fset(self, value):
|> ...
|> idiom. It's not obvious from the documentation of the property
|> function that it can be used as a decorator like this. (cf.
|> classmethod and staticmethod.)

Most especially since it isn't working very well for me, and I am trying
to track down why. When I run:

class alf :
def pete (self) :
print "Inside pete\n"

b = alf()
b.pete()

class fred :
@property
def joe (self) :
print "Inside /joe\n"


properties dont work properly on old-style classes (lookup 'new-style
classes' on python.org, in the documentation menu), hence the strange
behaviour you observe. Retry the same thing with s/class fred/class
fred(object)/
 
F

Fredrik Lundh

Nick said:
|> a property looks like an attribute, not a method, so you're trying to call whatever
|> your "joe()" method returns.

Well, yes, that was pretty obvious - but what was NOT obvious is why it
should do that for one of two identical methods.

identical? you only applied @property to one of the methods, and then you're
surprised that only one of the methods were turned into a property?
|> (that's what "a function for getting an attribute value" in the property documentation
|> refers to).

Well, as joe is an attribute of the class fred, and the decorator is applied
to the declaration of joe within fred, I assumed that it referred to getting
joe from fred. That certainly doesn't appear to be the case

@property turns your "joe" method into a getter method for the (virtual) attribute
"joe". when you access the attribute, the getter method will be called. whatever
that method returns will be the attribute's value. that's what the documentation
says, and that's what your code is doing.

</F>
 
F

Fredrik Lundh

Bruno said:
properties dont work properly on old-style classes (lookup 'new-style
classes' on python.org, in the documentation menu), hence the strange
behaviour you observe.

property getters work just fine on old-style classes (setters and deleters don't
work, but that's not what he's using).

</F>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top