python - 一个更好的 python 属性装饰器

标签 python debugging properties decorator

我继承了一些 python 代码,其中包含一个相当神秘的装饰器。这个装饰器在整个项目的类中设置属性。问题是我已经将我的调试问题追溯到这个装饰器。似乎它“fubars”了我试过的所有调试器,并试图用 psyco 加速代码破坏了一切。 (似乎 psyco 和这个装饰器玩得不好)。我认为最好更改它。

def Property(function):
    """Allow readable properties"""
    keys = 'fget', 'fset', 'fdel'
    func_locals = {'doc':function.__doc__}
    def probeFunc(frame, event, arg):
        if event == 'return':
            locals = frame.f_locals
            func_locals.update(dict((k,locals.get(k)) for k in keys))
            sys.settrace(None)
        return probeFunc
    sys.settrace(probeFunc)
    function()
    return property(**func_locals)

这样使用:

class A(object):
    @Property
    def prop():
        def fget(self):
            return self.__prop
        def fset(self, value):
            self.__prop = value
    ... ect

我得到的错误说问题是因为 sys.settrace。 (也许这是对 settrace 的滥用?)

我的问题:没有 sys.settrace 是否可以实现相同的装饰器。如果不是,我将进行一些重写。

最佳答案

同样的东西?不,如果没有像 sys.settrace 这样的魔法,你不能做那个装饰器所做的事情。 (从技术上讲,它不一定非得是 sys.settrace,但使用其他东西——比如字节码重写——不会是一种改进。)你可以通过以下方式使它变得更简单,例如:

def Property(f):  
    fget, fset, fdel = f()
    fdoc = f.__doc__
    return property(fget, fset, fdel, fdoc)

class Foo(object):
    @Property
    def myprop():
        "Property docstring"
        def fget(self):  
            return 'fget' 
        def fset(self, x):
            pass
        def fdel(self):
            pass
        return fget, fset, fdel

不过,在 Python 2.6 及更高版本中,您可以使用稍微不同的装饰器:

def Property(cls):
    fget = cls.__dict__.get('fget')
    fset = cls.__dict__.get('fset')
    fdel = cls.__dict__.get('fdel')
    fdoc = cls.__doc__
    return property(fget, fset, fdel, fdoc)

你会像这样使用它:

class Foo(object):
    @Property
    class myprop(object):
        "Property docstring"
        def fget(self):
            return 'fget'
        def fset(self, x):
            pass
        def fdel(self):
            pass

但是,在 Python 2.6 及更高版本中,更惯用的方法是这样的:

class Foo(object):
    @property
    def myprop(self):
        "Property docstring"
        return 'fget'
    @myprop.setter
    def myprop(self, x):
            pass
    @myprop.deleter
    def myprop(self):
            pass

关于python - 一个更好的 python 属性装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2610621/

相关文章:

python - 无法 pickle _thread.rlock 对象 Pyspark 向 elasticsearch 发送请求

python - BeautifulSoup 嵌套标签

visual-studio - 为try-catch语句配置Visual Studio调试器

javascript - knockout 选项绑定(bind)引用属性

javascript - 为什么将字符串 'prototype' 分配给一个变量然后用它来设置对象的原型(prototype)?

python - 从列表中两两取出元素

python - 使用 Win32 使窗口透明?

html - Firefox 不显示来自缓存的图像仅替代文本

在 Pycharm 中调试 Nose 测试不显示输出

types - 如何确定neo4j中节点内的属性值类型?