简体   繁体   English

一个更好的python属性装饰器

[英]A better python property decorator

I've inherited some python code that contains a rather cryptic decorator. 我继承了一些python代码,其中包含一个相当神秘的装饰器。 This decorator sets properties in classes all over the project. 此装饰器在整个项目的类中设置属性。 The problem is that this I have traced my debugging problems to this decorator. 问题是,我已将此调试问题跟踪到此装饰器。 Seems it "fubars" all debuggers I've tried and trying to speed up the code with psyco breaks everthing. 似乎它“fubars”我试过的所有调试器,并试图加速psyco休息的代码。 (Seems psyco and this decorator dont play nice). (似乎psyco和这个装饰师不好玩)。 I think it would be best to change it. 我认为最好改变它。

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)

Used like so: 像这样使用:

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

The errors I get say the problems are because of sys.settrace . 我得到的错误说问题是因为sys.settrace (Perhaps this is abuse of settrace ?) (也许这是滥用settrace?)

My question: Is the same decorator achievable without sys.settrace. 我的问题: 没有 sys.settrace,是否可以实现相同的装饰器。 If not I'm in for some heavy rewrites. 如果不是,我正在进行一些重写。

The same thing? 一样的东西? No. You can't do what that decorator does without magic like sys.settrace. 没有。如果没有像sys.settrace这样的魔法,你就无法做那个装饰器。 (It technically doesn't have to be sys.settrace, but using something else -- like bytecode rewriting -- wouldn't be an improvement.) You can make it a lot simpler by doing, for example: (从技术上讲,它不一定是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

In Python 2.6 and later you can use a slightly different decorator, though: 在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)

And you would use it like so: 你会像这样使用它:

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

However, a more idiomatic way of doing this in Python 2.6 and later is like so: 但是,在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

It might be possible; 可能是可能的; it appears that this abuse of settrace is being used to catch the decorated function just before it returns for the purpose of pilfering it's local variables... 似乎这种滥用settrace是在它返回之前用来捕获装饰函数,以便窃取它的局部变量......

Unfortunately, the main approaches I can think of at the moment involve hacking the bytecode :-(. 不幸的是,我现在能想到的主要方法涉及破解字节码:-(。

However, you could replace it with one that requires every so-decorated function to call another special function rather than simply returning, or you could modify it to call sys.gettrace rather than throwing out whatever trace function might be active, and restore the same trace function afterward. 但是,您可以将其替换为需要每个如此装饰的函数来调用另一个特殊函数而不是简单地返回,或者您可以将其修改为调用sys.gettrace而不是丢弃任何跟踪函数可能处于活动状态,并恢复相同的函数。之后跟踪功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM