簡體   English   中英

一個更好的python屬性裝飾器

[英]A better python property 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

可能是可能的; 似乎這種濫用settrace是在它返回之前用來捕獲裝飾函數,以便竊取它的局部變量......

不幸的是,我現在能想到的主要方法涉及破解字節碼:-(。

但是,您可以將其替換為需要每個如此裝飾的函數來調用另一個特殊函數而不是簡單地返回,或者您可以將其修改為調用sys.gettrace而不是丟棄任何跟蹤函數可能處於活動狀態,並恢復相同的函數。之后跟蹤功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM