Let's make a class that returns a random number for its hash.
>>> import random
>>> class DictDestroyer(object):
... def __hash__(self): return random.randint(0, 2**31)
...
>>> d = DictDestroyer()
>>> hash(d)
520880499
>>> hash(d)
793941724
Now, DictDestroyer lives up to its name:
>>> a = {d:1, d:2, d:3}
>>> import pprint
>>> pprint.pprint(a)
{<__main__.DictDestroyer object at 0x00CE8E90>: 1,
<__main__.DictDestroyer object at 0x00CE8E90>: 2,
<__main__.DictDestroyer object at 0x00CE8E90>: 3}
What is this? One key has multiple values? What happens when data is fetched?
>>> a[d]
1
>>> a[d]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: <__main__.DictDestroyer object at 0x00CE8E90>
Inconsistent behavior. Some times it returns one of the values, other times it gives a key error.
The C source for python dictionaries holds the answer.
I'll have to update later when I figure it out.
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.
Thursday, June 23, 2011
Wednesday, June 22, 2011
cron-like functionality (sched module)
The Python standard library includes a handy little scheduler, with which you can do cron-like functionality. The following code will print the current time every 5 seconds forever.
>>> import sched
>>> import datetime
>>> import time
>>> s = sched.scheduler(time.time, time.sleep)
>>> def print_time():
... print datetime.datetime.now()
... s.enter(5, 1, print_time, ())
...
>>> print_time()
2011-06-22 17:56:41.262000
>>> s.run()
2011-06-22 17:56:46.668000
2011-06-22 17:56:51.669000
2011-06-22 17:56:56.669000
2011-06-22 17:57:01.669000
This is a simple example of continuation passing style -- where functions "schedule" each other to run at a later time rather than calling directly.
>>> import sched
>>> import datetime
>>> import time
>>> s = sched.scheduler(time.time, time.sleep)
>>> def print_time():
... print datetime.datetime.now()
... s.enter(5, 1, print_time, ())
...
>>> print_time()
2011-06-22 17:56:41.262000
>>> s.run()
2011-06-22 17:56:46.668000
2011-06-22 17:56:51.669000
2011-06-22 17:56:56.669000
2011-06-22 17:57:01.669000
This is a simple example of continuation passing style -- where functions "schedule" each other to run at a later time rather than calling directly.
Sunday, May 29, 2011
inner functions, how do they work?
When a higher order function returns a new function, a new context has been wrapped around the existing code object. The code of that function is created once, at compile time. There is absolutely no compiler involved at runtime, no new byte code is generated.
>>> def foo(n):
... def bar():
... print n
... return bar
...
>>> a,b = foo(1), foo(2)
>>> a == b
False
>>> a()
1
>>> b()
2
>>> a.__code__ == b.__code__
True
>>> def foo(n):
... def bar():
... print n
... return bar
...
>>> a,b = foo(1), foo(2)
>>> a == b
False
>>> a()
1
>>> b()
2
>>> a.__code__ == b.__code__
True
Wednesday, May 18, 2011
__class__ is special
>>> class Classless(object):
... def __getattr__(self, name): raise AttributeError(name)
...
>>> Classless().__class__
<class '__main__.Classless'>
>>> c = Classless()
>>> c.__class__ = None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __class__ must be set to new-style class, not 'NoneType' object
... def __getattr__(self, name): raise AttributeError(name)
...
>>> Classless().__class__
<class '__main__.Classless'>
>>> c = Classless()
>>> c.__class__ = None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __class__ must be set to new-style class, not 'NoneType' object
Monday, May 16, 2011
the keys to the kingdom
Most of the low-level guts of an operating system are only exposed to C. Enter ctypes, part of the python standard library which allows python to call C code natively.
For example, say you are trying to access some function of open-ssl that is not exposed through the ssl module.
>>> import ctypes
>>> libssl = ctypes.cdll.LoadLibrary('libssl.so')
>>> libssl.PEM_read_bio_PrivateKey
<_FuncPtr object at 0x7fc001ba3a10>
With ctypes, your code is a full peer of C/C++ in how it can interact with the OS.
For example, say you are trying to access some function of open-ssl that is not exposed through the ssl module.
>>> import ctypes
>>> libssl = ctypes.cdll.LoadLibrary('libssl.so')
>>> libssl.PEM_read_bio_PrivateKey
<_FuncPtr object at 0x7fc001ba3a10>
Thursday, May 5, 2011
reloading a module does not regenerate the module object
When a module is reloaded, the module object is not removed from memory. Old data which is not overwritten will stick around.
>>> import json
>>> oldjson = json
>>> reload(json)
<module 'json' from 'C:\Python26\lib\json\__init__.pyc'>
>>> json is oldjson
True
To truly clean up modules in memory is a tricky process.
>>> import json
>>> oldjson = json
>>> reload(json)
<module 'json' from 'C:\Python26\lib\json\__init__.pyc'>
>>> json is oldjson
True
To truly clean up modules in memory is a tricky process.
Wednesday, April 20, 2011
making dict(myobject) do something useful
>>> class T(object):
... def __iter__(self):
... return self.__dict__.items().__iter__()
...
>>> t = T()
>>> t.a = "cat"; t.b = "dog"
>>> dict(t)
{'a': 'cat', 'b': 'dog'}
... def __iter__(self):
... return self.__dict__.items().__iter__()
...
>>> t = T()
>>> t.a = "cat"; t.b = "dog"
>>> dict(t)
{'a': 'cat', 'b': 'dog'}
Subscribe to:
Posts (Atom)