2010-08-23 3 views
2

Je suis en train de traiter des données à partir d'une application qui a quelques bizarreries dans la façon dont elle garde le temps. L'une des bizarreries les plus simples est qu'elle utilise le «jour de l'année» (1 janvier est 1, 1 février est 32, etc) au lieu de mois + jour. Je veux donc créer ma propre classe de date qui hérite de la classe datetime par défaut et qui possède quelques méthodes personnalisées. J'appelle ce jour. En plus des méthodes qui sortent à mes formats étranges, j'ai besoin de méthodes qui entrent le format bizarre dans une journée. Tout comme la méthode .fromordinal() peut être appelée à partir de datetime, je veux avoir une méthode .fromdayofyear() qui peut être appelée depuis le jour. Jusqu'à présent, je suis arrivé:Classes personnalisées en python: une méthode DOIT-elle être appelée avec une instance?

import datetime 

class daytime(datetime.datetime): 
    @property 
    def dayofyear(self): 
     return (self.date - datetime.date(self.year,1,1)).days + 1 
    def fromdayofyear(year,dayofyear): 
     return datetime(year,1,1)+datetime.timedelta(dayofyear-1) 

Le problème est que depuis fromdayofyear est une classe, il a besoin d'une instance de jour pour effectuer toutes les méthodes.

>>> from utils import daytime 
>>> day = daytime.fromdayofyear(2010,32)   #should give a datetime, Feburary first 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method from_datetime() must be called with DayTime instance as first argument (got str instance instead) 
>>> 

Je pourrais facilement écrire une série de fonctions pour ce faire, mais que les défaites le point de faire une classe personnalisée pour commencer. Je réalise que je ne devrais probablement pas utiliser un cours ici. Quelqu'un peut me diriger dans la bonne direction?

EDIT:

Voici ce que je me suis installé sur:

import datetime 

class daytime(datetime.datetime): 
    @property 
    def dayofyear(self): 
     return (self.date - datetime.date(self.year,1,1)).days + 1 
    @classmethod 
    def fromdayofyear(cls,year,dayofyear): 
     dt = cls(year,1,1)+datetime.timedelta(dayofyear-1) 
     return cls(dt.year,dt.month,dt.day) 
+0

Quelle horrible « bizarrerie » - assurez-vous que votre compte pendant des années bissextiles! –

+0

Pourrait être plus horrible - Je me souviens d'un format de date de 16 bits; 7 bits élevés étaient année depuis 1900, et 9 bits bas étaient le jour de l'année. Quelque part dans le système d'exploitation HP3000 MPE IIRC. –

Répondre

2

Le « réglé sur » solution organophosphorés a des bugs sérieux (self.date a besoin d'être appelé, non seulement mentionné, et la méthode fromdayofyear retourne en fait une instance datetime.datetime, non un daytime un, malgré la tentative apparente de le faire en utilisant cls).

est ici une version que je crois fonctionne comme prévu:

class daytime(datetime.datetime): 

    @property 
    def dayofyear(self): 
     return (self.date() - datetime.date(self.year, 1, 1)).days + 1 

    @classmethod 
    def fromdayofyear(cls, year, dayofyear): 
     dt = datetime.datetime(year, 1, 1) + datetime.timedelta(dayofyear-1) 
     return cls(dt.year, dt.month, dt.day) 
+0

Votre commentaire sur la réponse de THC4K était correct. Je vais mettre à jour ma solution. – chriscauley

8

Vous voulez décorateur @classmethod. Votre méthode récupère alors la classe au lieu de l'instance d'objet comme premier argument. Il est de coutume de l'appeler cls:

@classmethod 
def from_file(cls, f): 
    return cls(f.read()) 
+0

Vous rock. Je vais modifier ma question pour refléter cela – chriscauley

Questions connexes