I have a class with a name attribute, which I want to modify using
property.The following code works just fine:
class Portfolio(object):
def __init__( self, name="Port1"):
self.name=name
This may not do what you think it does (see below)
def getname(self):
return self._name
def setname(self,newname="Port2"):
self._name=newname
name=property(getname,setname,None,None)
However, it no longer works if I modify getname and setname to
def getname(self):
return self.name
def setname(self,newname="Port2"):
what's the use of putting a default value here ?
How could this work, since self.name is now a property object that calls
on setname() and getname() ?
Why is it so critical to have getname and setname modify _name and not
name?
because 'name' is how you named your property...
The constructor does not make name a private attribute,
Note that there is in fact no notion of private/public in Python (I mean
: in the language). The underscore stuff is nothing more than a convention.
Now you don't seem to understand what happens when __init__ is called.
Try this:
8<------------------------------------------------
class Portfolio(object):
def __init__( self, name="Port1"):
self.name=name
print "self._name is %s" % self._name
print "self.__class__.name is %s" % self.__class__.name
def _getname(self):
print "in getname"
return self._name
def _setname(self, newname):
print "in setname"
try:
print "self._name is %s" % self._name
except AttributeError, e:
print "got AttributeError %s" % e
print "when trying to access self._name"
self._name=newname
name=property(fget=_getname, fset=_setname)
print "in Portfolio class definition : name is %s" % name
p = Portfolio()
8<------------------------------------------------
As you can see, the 'name=property(...)' statement at the end of your
class definition is executed when the class definition is first eval'd
(this is when the code is loaded in the interpreter). So when __init__
is called, the statement 'self.name = name' does not create an instance
variable 'name', but calls the existing property, which in turn creates
the instance variable '_name'.
so why do
getname and setname have to treat it as such?
From a technical POV, we don't care if the attribute accessed by a
property is 'private' or whatever. The only thing is that it can't have
the same name as the property...
From a conceptual POV, it makes no sense (well, IMHO) to use a property
for a 'public' (by convention...) attribute. Either you want a property
(think : a computed attribute) and then you hide the implementation
details, or you're ok with a plain old 'public' attribute and then you
don't use a property.
BTW, this is also true of the setter and getter used by the property:
they are implementation details, and as such should not be exposed as
part of the interface.
HTH