Descriptors in global scope?
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.
精彩评论