Python中的自定义类:方法是否必须通过实例调用?
我正在处理一个应用程序的数据,这个程序在时间处理上有一些特别的地方。其中一个比较简单的地方是,它使用“年度中的天数”来表示日期,比如1月1日是1,2月1日是32,依此类推,而不是用月份加日期的方式。所以我想自己做一个日期类,继承默认的日期时间类,并添加一些自定义的方法。我把这个类叫做daytime。除了能输出我这种奇怪格式的方法外,我还需要一些方法,能够把这种奇怪的格式输入到daytime中。就像可以从datetime调用的方法.fromordinal()一样,我想要一个可以从daytime调用的方法.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是一个类,它需要一个daytime的实例才能执行任何方法。
>>> 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)
>>>
我可以很容易地写一系列函数来完成这个,但那样就失去了创建自定义类的意义。我意识到我可能不应该在这里使用类。有人能给我指个方向吗?
编辑:
这是我最终决定的:
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
你想要使用@classmethod这个装饰器。这样的话,你的方法就会把类本身作为第一个参数,而不是对象实例。通常我们把这个参数叫做cls:
@classmethod
def from_file(cls, f):
return cls(f.read())
2
原作者选择的解决方案存在严重问题(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)