Last active
August 29, 2015 14:13
-
-
Save ledmonster/9eae9747036c43f8d41e to your computer and use it in GitHub Desktop.
ValueObject implementation in Python ref: http://qiita.com/ledmonster/items/2f16d52cdf58d1a73685
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ValueObject(object): | |
""" base class for Value Objects | |
please call _set_properties in constructor. | |
""" | |
def __new__(class_, *args, **kwargs): | |
self = object.__new__(class_, *args, **kwargs) | |
self.__initialized = False | |
self.__params = dict() | |
return self | |
def _set_properties(self, mapping): | |
if self.__initialized: | |
raise AttributeError('callable only by constructor') | |
self.__initialized = True | |
self.__params = dict(mapping) | |
self.__labels = [k for k, v in mapping] | |
def setprop(key): | |
setattr(self.__class__, key, property(lambda x: x.__params[key])) | |
for k, v in mapping: | |
if not hasattr(self.__class__, k): | |
setprop(k) | |
def get_values(self): | |
return self.__params | |
def __repr__(self): | |
return unicode(self).encode('utf-8') | |
def __unicode__(self): | |
return u'%s(%s)' % ( | |
self.__class__.__name__, | |
u', '.join(unicode(self.__params[k]) for k in self.__labels)) | |
def __hash__(self): | |
return hash(repr(self)) | |
def __eq__(self, other): | |
if not isinstance(other, self.__class__): | |
return False | |
return repr(self) == repr(other) | |
def __ne__(self, other): | |
if not isinstance(other, self.__class__): | |
return True | |
return repr(self) != repr(other) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import pytest | |
from . import ValueObject | |
class Date(ValueObject): | |
def __init__(self, year, month, day): | |
self._set_properties([ | |
('year', int(year)), | |
('month', int(month)), | |
('day', int(day)), | |
]) | |
class Foo(ValueObject): | |
def __init__(self, text='foo'): | |
self._set_properties([ | |
('text', text), | |
]) | |
@pytest.fixture | |
def date(): | |
return Date(2012, 2, 20) | |
@pytest.fixture | |
def foo_unicode(): | |
return Foo(u'ふー') | |
def test_properties(date): | |
assert date.year == 2012 | |
assert date.month == 2 | |
assert date.day == 20 | |
def test_immutable(date): | |
with pytest.raises(AttributeError): | |
date.year = 2015 | |
def test_set_properties(date): | |
with pytest.raises(AttributeError): | |
date._set_properties([ | |
('year', 2015), | |
]) | |
def test_repr(date): | |
assert repr(date) == "Date(2012, 2, 20)" | |
def test_get_values(date): | |
date.get_values == {'year': 2012, 'month': 2, 'day': 20} | |
def test_unicode(foo_unicode): | |
assert foo_unicode.text == u'ふー' | |
assert unicode(foo_unicode) == u"Foo(ふー)" | |
assert repr(foo_unicode) == u"Foo(ふー)".encode('utf-8') | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment