您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如何在Python中创建动态范围变量?

如何在Python中创建动态范围变量?

我认为大法官在这里的推理是正确的。

另一方面-我无法抗拒为Python的另一种“非自然的”编程范例实现概念证明-我只是喜欢这样做。:-)

因此,我创建了一个类,其对象属性的定义与您的要求相同(并且可以动态创建)。就像我说的那样,它只是处于概念验证状态- 但是我认为,大多数常见错误(例如尝试在根本没有定义的作用域中访问变量)都应该引发错误,即使不是正确的错误(IndexError)例如由于堆栈下溢而不是AttributeError)

import inspect


class DynamicVars(object):
    def __init__(self):
        object.__setattr__(self, "variables", {})

    def normalize(self, stackframe):
        return [hash(tpl[0]) for tpl in stackframe[1:]]

    def __setattr__(self, attr, value):
        stack = self.normalize(inspect.stack())
        d = {"value": value, "stack": stack}
        if not attr in self.variables:
            self.variables[attr] = []
            self.variables[attr].append(d)
        else:
            our_value = self.variables[attr]
            if our_value[-1]["stack"] == stack:
                our_value[-1]["value"] = value
            elif len(stack) <= len(our_value):
                while our_value and stack !=  our_value["stack"]:
                    our_value.pop()
                our_value.append(d)
            else: #len(stack) > len(our_value):
                our_value.append(d)
    def __getattr__(self, attr):
        if not attr in self.variables:
            raise AttributeError
        stack = self.normalize(inspect.stack())
        while self.variables[attr]:
            our_stack = self.variables[attr][-1]["stack"]
            if our_stack == stack[-len(our_stack):]:
                break
            self.variables[attr].pop()
        else:
            raise AttributeError
        return self.variables[attr][-1]["value"]


# for testing:
def c():
    D = DynamicVars()
    D.c = "old"
    print D.c
    def a():
        print D.c
    a()
    def b():
        D.c = "new"
        a()
    b()
    a()
    def c():
        D.c = "newest"
        a()
        b()
        a()
    c()
    a()

c()
@H_301_9@

-出现了另一个类似的问题,我设计了一种不需要特殊名称空间对象的hack(但是它诉诸于使用cpython的内部功能,例如将locals()更新为实际变量:(适用于Python 3.8)

解决方法

我正在将一些代码从Lisp转换为Python。

在Lisp中,您可以使用let构造,其中引入的变量声明为special,因此具有动态范围。(请参阅http://en.wikipedia.org/wiki/Dynamic_scope#Dynamic_scoping

我该如何在Python中做同样的事情?似乎该语言不直接支持此功能,如果为true,将有什么模仿的好方法?

喜欢与人分享编程技术与工作经验,欢迎加入编程之家官方交流群!

-出现了另一个类似的问题,我设计了一种不需要特殊名称空间对象的hack(但是它诉诸于使用cpython的内部功能,例如将locals()更新为实际变量:(适用于Python 3.8)

我正在将一些代码从Lisp转换为Python。

在Lisp中,您可以使用let构造,其中引入的变量声明为special,因此具有动态范围。(请参阅http://en.wikipedia.org/wiki/Dynamic_scope#Dynamic_scoping

我该如何在Python中做同样的事情?似乎该语言不直接支持此功能,如果为true,将有什么模仿的好方法?

-出现了另一个类似的问题,我设计了一种不需要特殊名称空间对象的hack(但是它诉诸于使用cpython的内部功能,例如将locals()更新为实际变量:(适用于Python 3.8)

python 2022/1/1 18:28:34 有193人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶