全局范围内的描述符?

发布于 2024-09-15 19:16:03 字数 401 浏览 11 评论 0原文

Python 2.6 中的 描述符协议 仅定义为类定义,因此只能由实例使用。

是否有一些等效的工具来检测全局变量的获取/设置?

我正在尝试加快与主机系统交互的模块的导入速度,因此必须对主机执行一些昂贵的探测。 (昂贵的)探测的结果存储在导入时初始化的模块全局中;所以我试图推迟初始化直到绝对需要。

请不要评论全局变量是邪恶的。我知道它们是什么以及何时使用它们。

我当前的计划是创建一个使用描述符的全局实例,并将当前的所有全局变量移至该实例的属性中。我希望这会起作用;我只是想问一下还有没有别的办法

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 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沉睡月亮 2024-09-22 19:16:03

我当前的计划是创建一个使用描述符的全局实例,并将所有当前的全局变量移至该实例的属性中。我希望这会起作用;我只是想问问还有没有别的办法。

这正是我要做的。类之外没有与描述符等效的东西。

我有时也使用的另一个选项是使用函数而不是变量名,如下所示:

_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

如果您已经在某处定义了 @memoize 装饰器,则可以简化上述内容相当。

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.

余生一个溪 2024-09-22 19:16:03

如果您确实想这样做,此链接提供了一个非常酷的实现方法。唯一需要注意的是您必须使用 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))

虽然有点麻烦,但我认为这非常酷。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文