2010-10-15 12 views
18

J'ai une classe avec un attribut que je souhaite transformer en propriété, mais cet attribut est défini en __init__. Je ne sais pas comment cela devrait être fait. Sans régler l'propert dans ce __init__ est facile et fonctionne bienComment définir une propriété python dans __init__

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" 

Mais une fois l'initialisation doit se produire dans __init__ cela devient plus compliqué et je ne suis pas sûr de la bonne mesure à prendre.

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

Étrangement pour moi, ce qui suit semble fonctionner mais sent très mauvais.

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 

Quelle est la bonne façon d'aller sur la définition des propriétés dans __init__?

Merci, aaron.

+1

En général, existe-t-il une raison pour définir 'self._date = None' avant la mise à jour de la propriété, car elle sera immédiatement remplacée par la nouvelle valeur? –

+0

Non. Cela n'a de sens que si la deuxième ligne est absente pour empêcher l'appel du getter sans attribut "_date" – nerdoc

Répondre

17

Je ne vois pas vraiment de problème avec votre code. En __init__, la classe est entièrement créée et donc les propriétés accessibles.

+0

Ok, donc peut-être que je regarde ça de travers. Au point de __init__, la propriété est-elle déjà créée, de sorte que mon appel à self.date accède via la propriété de la même manière que mon appel à st.date? –

+6

Oui, exactement (pourquoi Stackoverflow n'aime-t-il pas les messages courts et précis?) - il refuse de publier uniquement "Oui, exactement"). –

+0

+1 Parfaitement bien. J'ajouterais que le self._date = None dans __init__ est vraiment inutile dans ce code (Vous pouvez dans certains cas mettre l'initialisation des propriétés hidden dans le getter en utilisant RAII ('if not hastr (self, _smth): do initialisation. .. ') – ThR37

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

Si vous souhaitez définir l'objet proxy self._date sans exécuter setter utiliser la ligne n ° 1. Si vous souhaitez exécuter le setter au démarrage, utilisez le # 2. Les deux façons sont correctes, c'est juste une question de quoi avez-vous besoin.

+1

Pourquoi voudriez-vous mettre' _date' à 'None' quand init est clairement appelé avec un certain' date'? Vous devriez stocker la valeur correcte, donC# 1 n'est pas viable. –