The descriptor protocol in Python 2.6 is only defined for class definitions, and thus can only be used by instances.
Is there some equivalent for instrumenting get/set of globals?
I'm trying to speed up the importing of a module which interacts with the host system, and as such has to perform some expensive probing of the host. The results of the (expensive) probe are stored in a module global that is initialized at import time; so I'm trying to delay the initialization until absolutely required.
Please, no comments about globals being evil. I know what they are and when to use them.
My c开发者_运维技巧urrent plan is to create a global instance that uses descriptors, and move all my current globals into the attributes of this instance. I expect this will work; I'm just asking if there's another way.
My current plan is to create a global instance that uses descriptors, and move all my current globals into the attributes of this instance. I expect this will work; I'm just asking if there's another way.
That's precisely what I would do. There is no equivalent to descriptors outside of classes.
The other option, which I have also sometimes used, would be to use a function instead of a variable name, something like this:
_expensive_to_compute = None
def get_expensive_to_compute():
global _expensive_to_compute
if _expensive_to_compute is None:
_expensive_to_compute = do_computation()
return _expensive_to_compute
If you already have a @memoize
decorator defined somewhere, you can simplify the above considerably.
If you really want to do this, this link gives a pretty cool method to implement. The only caveat is you'd have to execute your code using eval/exec/execfile.
https://mail.python.org/pipermail/python-ideas/2011-March/009657.html
class MyDict:
def __init__(self, mapping):
self.mapping = mapping
def __getitem__(self, key):
value = self.mapping[key]
if hasattr(value, '__get__'):
print('Invoking descriptor on', key)
return value.__get__(key)
print('Getting', key)
return value
def __setitem__(self, key, value):
self.mapping[key] = value
class Property:
def __init__(self, getter):
self.getter = getter
def __get__(self, key):
return self.getter(key)
if __name__ == '__main__':
md = MyDict({})
md['x'] = 10
md['_y'] = 20
md['y'] = Property(lambda key: md['_'+key])
print(eval('x+y+1', {}, md))
While a little cumbersome, I thought this was very cool.
精彩评论