我在python中扩展date
类时遇到了问题。
然而,由于日期是静态类,我还没有按照它应该的那样工作。我尝试修改datetime
上的代码库,因为此类从date
扩展。但是,失败了。
问题是:
ed = ExtendDate(2011,1,1,week = 3,quarter = 3)
print ed.week#3
如何处理python静态类中的__new__
和__init__
(理论上)?
如何扩展日期类(一般情况下)?
感谢。
class ExtendDate(date):
"""Extend to have week and quarter property"""
#
# def __init__(self, year, month, day, week=None, quarter=None):
# pass
def __init__(self, year, month, day, week=None, quarter=None):
print 0
super(ExtendDate, self).__init__(year,month,day)
print 1
self._week = week
self._quarter = quarter
@staticmethod
def __new__(cls, year, month, day, week=None, quarter=None):
cls._week = 1
super(ExtendDate, cls).__new__(year, month, day)
def __cmp__(self, other):
if self.cmp_year(other) in [-1,0,1]:
return self.cmp_year(other)
if hasattr(self, 'quarter'):
return self.cmp_quarter(other)
if hasattr(self, 'week'):
return self.cmp_week(other)
# TODO: test - what if it's just a normal date object ?
pass
def cmp_quarter(self, other):
if self.quarter < other.quarter:
return -1
elif self.quarter == other.quarter:
return 0
elif self.quarter > other.quarter:
return 1
def cmp_week(self, other):
if self.week < other.week:
return -1
elif self.week == other.week:
return 0
elif self.week > other.week:
return 1
def cmp_year(self, other):
if self.year < other.year:
return -1
elif self.year == other.year:
return 0
elif self.year > other.year:
return 1
def __repr__(self):
return 'year:' + str(self.year) + ' ' + \
'quarter:' + str(self.quarter) + ' ' + \
'month:' + str(self.month) + ' '+ \
'week:' + str(self.week) + ' '+ \
'day:' + str(self.day) + ' '
week = property(lambda self: 0)
quarter = property(lambda self: 0)
@week.setter
def week(self, value):
self._week = value
@quarter.setter
def quarter(self, value):
self._quarter = value
答案 0 :(得分:2)
__new__
不应该使用@staticmethod
进行修饰(隐式地使用类方法,不应使用装饰器)。并且它应该返回创建的实例,代码正在修改cls
(它不应该)并且不返回super
__new__
调用的结果(它应该)。另外,如果您提供__new__
(使该课程在逻辑上不可变),则您不应提供__init__
。
真的,你想要的代码就像:
class ExtendDate(date):
"""Extend to have week and quarter property"""
__slots__ = '_week', '_quarter' # Follow date's lead and limit additional attributes
def __new__(cls, year, month, day, week=None, quarter=None):
self = super(ExtendDate, cls).__new__(cls, year, month, day)
self._week = week
self._quarter = quarter
return self
据推测,您还需要功能性吸气剂,例如
@property
def week(self):
return self._week
# ... etc. ...
答案 1 :(得分:0)
当@ShadowRanger回答时,我更改了一些行以使其正常工作。
主要变化是__new__(cls, year, month, day)
:
from datetime import date
class ExtendDate(date):
"""Extend to have week and quarter property"""
__slots__ = '_week', '_quarter'
def __new__(cls, year, month, day, week=None, quarter=None):
# self = super(ExtendDate, cls).__new__(year, month, day)
self = date.__new__(cls, year, month, day)
self._week = week
self._quarter = quarter
return self
def __cmp__(self, other):
if self.cmp_year(other) in [-1,0,1]:
return self.cmp_year(other)
if hasattr(self, 'quarter'):
return self.cmp_quarter(other)
if hasattr(self, 'week'):
return self.cmp_week(other)
# TODO: test - what if it's just a normal date object ?
pass
def cmp_quarter(self, other):
if self.quarter < other.quarter:
return -1
elif self.quarter == other.quarter:
return 0
elif self.quarter > other.quarter:
return 1
def cmp_week(self, other):
if self.week < other.week:
return -1
elif self.week == other.week:
return 0
elif self.week > other.week:
return 1
def cmp_year(self, other):
if self.year < other.year:
return -1
elif self.year == other.year:
return 0
elif self.year > other.year:
return 1
def __repr__(self):
return 'year:' + str(self.year) + ' ' + \
'quarter:' + str(self.quarter) + ' ' + \
'month:' + str(self.month) + ' '+ \
'week:' + str(self.week) + ' '+ \
'day:' + str(self.day) + ' '
@property
def week(self):
return self._week
@property
def quarter(self):
return self._quarter
ed = ExtendDate(2011,1,2,3,4)
print type(ed)
print ed._week