我想创建一个python类,其中几个属性的类型为datetime.date
,但也可以使用str
或datetime.datetime
实例设置它们。到目前为止我有这个:
import datetime
def my_date_fn(date_in):
"""
Return a datetime.date object from either a string (e.g. "2018/01/04"),
datetime.datetime or datetime.date object.
"""
if type(date_in) is str:
return datetime.date(*map(int, date_in.split('/')))
elif type(date_in) is datetime.datetime:
return date_in.date()
elif type(date_in) is datetime.date:
return date_in
class MyClass(object):
"""
Class to contain date information.
"""
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
@property
def a(self):
return self._a
@a.setter
def a(self, value):
self._a = my_date_fn(value)
@property
def b(self):
return self._b
@b.setter
def b(self, value):
self._b = my_date_fn(value)
@property
def c(self):
return self._c
@c.setter
def c(self, value):
self._c = my_date_fn(value)
test = MyClass('2017/7/7', datetime.date(2012, 8, 4),
datetime.datetime(2001, 5, 3, 12, 0))
for x in ['a', 'b', 'c']:
print getattr(test, x), type(getattr(test, x))
这工作正常,但有很多重复的代码与@property
和@*.setter
函数。有没有更优雅的方式来做到这一点?
简单地说,定义一个函数:
def date_property(name):
def set_date(self, date_in):
"""
Return a datetime.date object from either a string (e.g. "2018/01/04"),
datetime.datetime or datetime.date object.
"""
if isinstance(date_in, str):
date_in = datetime.date(*map(int, date_in.split('/')))
elif isinstance(date_in, datetime.datetime):
date_in = date_in.date()
elif isinstance(date_in, datetime.date):
pass
else:
raise TypeError()
setattr(self, name, date_in)
return property(lambda self: getattr(self, name), set_date)
class MyClass(object):
"""
Class to contain date information.
"""
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
a = date_property('_a')
b = date_property('_b')
c = date_property('_c')