Пользовательские классы в python: должен ли метод вызываться с экземпляром? - PullRequest
2 голосов
/ 24 августа 2010

Я обрабатываю данные из приложения, у которого есть несколько изысков в том, как оно хранит время. Одна из самых простых странностей заключается в том, что вместо месяца + дня используется «день года» (1 января - 1, 1 февраля - 32 и т. Д.). Поэтому я хочу создать свой собственный класс даты, который наследуется от класса даты и времени по умолчанию и имеет несколько пользовательских методов. Я звоню в этот день. В дополнение к методам, которые выводят в мои странные форматы, мне нужны методы, которые вводят странные форматы в дневное время. Так же, как метод .fromordinal () может быть вызван из datetime, я хочу иметь метод .fromdayofyear (), который можно вызывать из дневного времени. Пока я получил:

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)

Проблема в том, что поскольку fromdayofyear является классом, ему нужен экземпляр дневного времени для выполнения любых методов.

>>> 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)
>>>

Я мог бы легко написать ряд функций для этого, но это лишает смысла создание собственного класса для начала. Я понимаю, что мне, вероятно, не следует использовать здесь класс. Может ли кто-нибудь указать мне правильное направление?

EDIT:

Вот что я остановился на:

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)

Ответы [ 2 ]

8 голосов
/ 24 августа 2010

Вы хотите декоратор @classmethod.Тогда ваш метод получает класс вместо экземпляра объекта в качестве первого аргумента.Обычно это называют cls:

@classmethod
def from_file(cls, f):
    return cls(f.read())
2 голосов
/ 24 августа 2010

В "оплаченном" решении OP есть серьезные ошибки (self.date должен быть , называемый , а не просто упомянутый ; а метод fromdayofyear фактически возвращает datetime.datetimeэкземпляр, а не daytime, несмотря на очевидную попытку сделать это с помощью cls).

Вот версия, которая, я считаю, работает как задумано:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...