如何保留或识别呼叫者的堆栈帧?

时间:2010-02-14 03:14:24

标签: python stack decorator

我的大脑今天感觉很慢。

我正在使用装饰器在Python中编写前/后/不变量。目前,我需要每次调用为上下文指定locals和globals,这感觉很难看。有没有办法从装饰器应用程序级别获取本地和全局变量,即使它是任意深度。

也就是说,我正试图制作这个丑陋的代码:     来自dectools import invariant,pre,post,call_if

@invariant("self.price >= 0 and self.inventory >= 0 and Item.tax_rate >= 0")
class Item(object):
    tax_rate = 0.10  # California.  No property taxes on old property.

    @post("ItemDB.fetch(self) = (name, price)", locals(), globals())
    def __init__(self, name, price):
        self.name = name
        self.price = price
        self.total_sold = 0
        self.inventory = 0

    @call_if(check_level, "manager")
    @post("self.total_sold > 0", locals(), globals())
    @pre("discount > 0 and discount <= self.price * 0.50", locals(), globals())
    def adjust_price(self, adjustment):
         ....

进入相同的丑陋代码而没有所有“locals(),globals()”。我遇到了嵌套装饰器给我任意堆栈深度的问题,因此我的dectools.pre实现无法从常量深度sys._getframe()中获取。筹码不是我玩过的东西,如果有人有诡计,我会很感激。 (是的,我通过假设self将在正确的堆栈框架中将局部变量破解到本地变量。这是Item.tax_rate总是超出范围,自我和ItemDB。)

提前谢谢你,

查尔斯

1 个答案:

答案 0 :(得分:2)

如果你可以访问self.total_sold,你可以访问self.tax_rate(这与Item.tax_rate相同,除非你踩它 - 所以你不要踩它,将税率保持为原始类变量,并通过self.访问它! - )。这比通过堆栈更加坚固,尤其是图片中的嵌套装饰器,这或多或少保证了脆弱的,特定于版本的代码(堆栈内省意味着用于调试)目的,基本上,用于生产目的。)