加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python:静态变量装饰器

发布时间:2020-12-20 13:03:36 所属栏目:Python 来源:网络整理
导读:我想创建一个像下面这样的装饰器,但我似乎无法想到一个有效的实现.我开始认为这是不可能的,但我想我先问你们. 我意识到在Python中有各种其他方法可以创建静态变量,但我发现这些方法很难看.如果可能的话,我真的想使用下面的语法. @static(x=0)def f(): x += 1
我想创建一个像下面这样的装饰器,但我似乎无法想到一个有效的实现.我开始认为这是不可能的,但我想我先问你们.

我意识到在Python中有各种其他方法可以创建静态变量,但我发现这些方法很难看.如果可能的话,我真的想使用下面的语法.

@static(x=0)
def f():
    x += 1
    print x

f() #prints 1
f() #prints 2

我不关心静态的实现是长期还是黑客,只要它像上面那样工作.

我创建了这个版本,但它只允许< function>.< varname>语法,使用更长的函数和变量名称很快就会变得很麻烦.

def static(**assignments):
    def decorate(func):
        for var,val in assignments.items():
            setattr(func,var,val)
        return func
    return decorate

我想到的各种事情,但无法开展工作的是:

>将f(装饰函数)更改为可调用类,并以某种方式透明地将静态变量存储在自身中.
>修改装饰器内的f()的全局变量,并以某种方式将’global x’语句插入到f的代码中.
>将f更改为生成器,我们手动绑定变量,然后直接执行f代码.

解决方法

这是一个似乎有用的装饰器.
请注意,这需要在函数末尾返回locals(),因为无法从外部设置本地(我没有太多编程经验,所以如果有办法,我不知道).

class Static(object):
    def __init__(self,**kwargs):
        self.kwargs = kwargs

    def __call__(self,f):
        def wrapped_f():
            try:
                new_kwargs = {}
                for key in self.kwargs:
                    i = getattr(f,key)
                    new_kwargs[key] = i
                self.kwargs = new_kwargs
            except:
                pass
            for key,value in f(**self.kwargs).items():
                setattr(f,key,value)
        return wrapped_f

@Static(x=0,y=5,z='...')
def f(x,y,z):
    x += 1
    y += 5
    print x,z
    return locals()

输出将是:

>>> f()
1 10 ...
>>> f()
2 15 ...
>>> f()
3 20 ...

编辑:

我在http://code.activestate.com/recipes/410698/找到了一些东西,并决定尝试添加它.它现在没有回报.

再次编辑:更改为使其快几秒.
编辑3;改为功能而不是类

def static(**kwargs):
    def wrap_f(function):
        def probeFunc(frame,event,arg):
            if event == 'call':
                frame.f_locals.update(kwargs)
                frame.f_globals.update(kwargs)
            elif event == 'return':
                for key in kwargs:
                    kwargs[key] = frame.f_locals[key]
                sys.settrace(None)
            return probeFunc
        def traced():
            sys.settrace(probeFunc)
            function()
        return traced
    return wrap_f

测试:

@static(x=1)
def f():
    x += 1

global_x = 1
def test_non_static():
    global global_x
    global_x += 1


print 'Timeit static function: %s' % timeit.timeit(f)
print 'Timeit global variable: %s' % timeit.timeit(test_non_static)

输出:

Timeit static function: 5.10412869535
Timeit global variable: 0.242917510783

使用settrace会大大减慢它的速度.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读