This shows how to make a class also be a set of its own instances.
A conceptually simpler way of maintaining a global registry of instances.
>>> class SetMetaClass(type):
... def __new__(cls, *a, **kw):
... cls.all = set()
... return type.__new__(cls, *a, **kw)
... def __iter__(cls): return cls.all.__iter__()
... def __len__(cls): return len(cls.all)
... def __contains__(cls, e): return e in cls.all
... def add(cls, e): cls.all.add(e)
... def discard(cls, e): cls.all.discard(e)
...
>>> class InstanceSet(object):
... __metaclass__ = SetMetaClass
... def __init__(self, *a, **kw):
... self.__class__.add(self)
...
>>> InstanceSet()
<__main__.InstanceSet object at 0x00DAB0F0>
>>> InstanceSet()
<__main__.InstanceSet object at 0x00D23610>
>>> [a for a in InstanceSet]
[<__main__.InstanceSet object at 0x00DAB0F0>, <__main__.InstanceSet object at 0x
00D23610>]
>>> len(InstanceSet)
2
Kind of like "hey guys, check it out you can just duct tape down the dead-man's switch on this power tool and use it one handed". In Python.
Friday, October 21, 2011
Tuesday, October 11, 2011
Decoration? Instantiation? Decorstantiation
>>> class Decorstantiator(object):
... def __init__(self, func): self.func = func
... def __call__(self): print "foo"; func()
...
>>> @Decorstantiator
... def bar(): print "bar"
...
>>> bar()
foo
bar
... def __init__(self, func): self.func = func
... def __call__(self): print "foo"; func()
...
>>> @Decorstantiator
... def bar(): print "bar"
...
>>> bar()
foo
bar
Sunday, October 9, 2011
I can DoAnything
Sometimes you just want to test a piece of code that does deep calls into other objects in isolation.
For example:
def _change(self, op, val):
self.parent.context.change(self.parent.model, self.attr, op, val)
How can we create an object to stand in for parent in the above code?
class DoAnything(object):
def __call__(self, *a, **kw): return self
__getattr__ = __add__ = __sub__ = __mul__ = __div__ = __call__
#overload more operators to taste/requirements
>>> parent = DoAnything()
>>> parent.context.change(parent.model, "foo", "bar", "baz")
<__main__.DoAnything object at 0x02169B10>
For example:
def _change(self, op, val):
self.parent.context.change(self.parent.model, self.attr, op, val)
How can we create an object to stand in for parent in the above code?
class DoAnything(object):
def __call__(self, *a, **kw): return self
__getattr__ = __add__ = __sub__ = __mul__ = __div__ = __call__
#overload more operators to taste/requirements
>>> parent = DoAnything()
>>> parent.context.change(parent.model, "foo", "bar", "baz")
<__main__.DoAnything object at 0x02169B10>
Friday, September 30, 2011
__slots__ cannot be updated
>>> class Slots(object): __slots__ = ()
...
>>> Slots.__slots__ = ('t',)
>>> Slots.__slots__
('t',)
>>> s2 = Slots()
>>> s2.t = 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Slots' object has no attribute 't'
...
>>> Slots.__slots__ = ('t',)
>>> Slots.__slots__
('t',)
>>> s2 = Slots()
>>> s2.t = 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Slots' object has no attribute 't'
namedtupledict
With three kinds of member access, it is easier to use than ever.
>>> def namedtupledict(*a, **kw):
... namedtuple = collections.namedtuple(*a, **kw)
... def getitem(self, key):
... if type(key) == str:
... return getattr(self, key)
... return tuple.__getitem__(self, key)
... namedtuple.__getitem__ = getitem
... return namedtuple
...
>>> t = namedtupledict('t', 'a b c')
>>> t1 = t(1,2,3)
>>> t1.a
1
>>> t1[0]
1
>>> t1['a']
1
>>> def namedtupledict(*a, **kw):
... namedtuple = collections.namedtuple(*a, **kw)
... def getitem(self, key):
... if type(key) == str:
... return getattr(self, key)
... return tuple.__getitem__(self, key)
... namedtuple.__getitem__ = getitem
... return namedtuple
...
>>> t = namedtupledict('t', 'a b c')
>>> t1 = t(1,2,3)
>>> t1.a
1
>>> t1[0]
1
>>> t1['a']
1
Thursday, September 29, 2011
Wednesday, September 21, 2011
I'm my own grandpa.
A fellow Pythonaut had a simple problem...
How to test code with dependencies on the date? Specifically, a Django project with models that have DateTimeFields with auto_now=True.
The chosen approach was to monkey-patch datetime.date.today() in order to return a constant value.
The first snag: datetime.date is a C class. This means it is not monkey-patchable.
This can be solved by monkey-patching the entire datetime.date class. The most straightforward thing to replace datetime.date with is a new subclass of datetime.date, whose only change is to override the today() function.
The second problem: there are now two kinds of datetime.date's floating around the system. Those by datetime.date.today(), and those created by every other function, which being C code will still return the same class.
Specifically, DateTimeField validates isinstance(data, datetime.date) before saving to the database.
A class which is simultaneously a super and subclass of datetime.date is required.
Override __subclasshook__ so that isinstance(super(datetime.date)(), datetime.date) is True.
>>> class DateProxy(datetime.date):
... __metaclass__ = abc.ABCMeta
... @classmethod
... def __subclasshook__(cls, C): return True
... @classmethod
... def today(cls): return datetime.date(2011,9,20)
...
>>> datetime.date = DateProxy
In other words, the superclass is also a subclass. The parent of the parent being the grandparent, this class is it's own grandpa.
How to test code with dependencies on the date? Specifically, a Django project with models that have DateTimeFields with auto_now=True.
The chosen approach was to monkey-patch datetime.date.today() in order to return a constant value.
The first snag: datetime.date is a C class. This means it is not monkey-patchable.
This can be solved by monkey-patching the entire datetime.date class. The most straightforward thing to replace datetime.date with is a new subclass of datetime.date, whose only change is to override the today() function.
The second problem: there are now two kinds of datetime.date's floating around the system. Those by datetime.date.today(), and those created by every other function, which being C code will still return the same class.
Specifically, DateTimeField validates isinstance(data, datetime.date) before saving to the database.
A class which is simultaneously a super and subclass of datetime.date is required.
Override __subclasshook__ so that isinstance(super(datetime.date)(), datetime.date) is True.
>>> class DateProxy(datetime.date):
... __metaclass__ = abc.ABCMeta
... @classmethod
... def __subclasshook__(cls, C): return True
... @classmethod
... def today(cls): return datetime.date(2011,9,20)
...
>>> datetime.date = DateProxy
In other words, the superclass is also a subclass. The parent of the parent being the grandparent, this class is it's own grandpa.
Subscribe to:
Posts (Atom)