views:

77

answers:

2

Hi,

I have a class with an attribute I wish to turn into a property, but this attribute is set within __init__. Not sure how this should be done. Without setting the propert in __init__ this is easy and works well

import datetime

class STransaction(object):
    """A statement transaction"""
    def __init__(self):
        self._date = None

    @property
    def date(self):
        return self._date

    @date.setter
    def date(self, value):
        d = datetime.datetime.strptime(value, "%d-%b-%y")
        self._date = d

st = STransaction()
st.date = "20-Jan-10"

But once initialisation needs to occur in __init__ it gets more complicated and I am not sure of the correct course of action.

class STransaction(object):
    """A statement transaction"""
    def __init__(self, date):
        self._date = None

Strangely to me, the following seems to work but smells very bad.

class STransaction(object):
    """A statement transaction"""
    def __init__(self, date):
        self._date = None
        self.date = date

    @property
    def date(self):
        return self._date

    @date.setter
    def date(self, value):
        d = datetime.datetime.strptime(value, "%d-%b-%y")
        self._date = d

What is the correct way to go about setting properties in __init__?

Thanks, aaron.

+5  A: 

I do not see any real problem with your code. In __init__, the class is fully created and thus the properties accessible.

Florian Mayer
Ok, so perhaps I am looking at this the wrong way. At the point of __init__ is the property already created so my call to self.date is accessing via the property is the same way that my call to st.date is?
Aaron Barclay
Yes, exactly (why does Stackoverflow dislike short, to-the-point messages? - it refused to post just "Yes, exactly").
Florian Mayer
+1 Perfectly right. I would add that the self._date = None in __init__ is really useless in this code (You can in some cases put the initialization of properties hidden variables in the getter using RAII ( `if not hasattr(self,_smth): do initialization...`)
Elenaher
Gotcha, thanks for help here, will look into RAII.
Aaron Barclay
A: 
class STransaction(object):
"""A statement transaction"""
def __init__(self, date):
    self._date = None #1
    self.date = date  #2

If you want to set the proxy self._date object without executing your setter use the #1 line. If you would like to execute the setter at startup too use the #2. Both ways are correct, it's just a matter of what do you need.

Secator