python修饰符的引用计次问题

ka-keung 发布于 2014/11/26 21:38
阅读 305
收藏 0

今天第一次接触修饰符,想利用修饰符,在运行脚本的时候,加入修饰符被调用的次数从而显示出来。可能我说不明白,但是运行脚本,我想要的结果是这样的:

1    'xxxx' 'xxxxx'

2    'sdawd' 'sdasdad

后面那些字符不重要,重要的是序列1和2。但是,无论我如何的修改脚本,都不能为修饰符加入计次,为什么?

1、首先我遇到的问题,为什么引用的次数不是递增则是直接显示累计的结果?

#!/usr/bin/python
#--*encoding=utf8--*
import os
num=0

def hehe(w=1):
        global num
        num=sum+1
        def xiushiqi(fun):
                def test(*args):
                        os.chdir('/var/tmp')
                        print num,os.getcwd(),fun(*args)
                return test
        return xiushiqi


@hehe(num)
def ljq(x,y,z):
    return x*y+z

@hehe(num)
def xx(x,y,z):
    return x*y+z

@hehe(num)
def xwx(x,y,z):
    return x*y+z


ljq(2,9,29)
xx(22,9,29)
xwx(8,9,29)

[root@test-A opt]# python c.py 
3 /var/tmp 47
3 /var/tmp 227
3 /var/tmp 101



每次,我的确引用了3次,但是按照正常来说,输出不应该是这样么?

1 /var/tmp 47
2 /var/tmp 227
3 /var/tmp 101

当第一次引用ljq时,sum就是为sum=sum+1,就是说应该显示的是1才对,为什么全部都为3(总共被引用的次数)??

无论我把sum=sum+1改为sum+=1还是sum=sum+w结果都一样,这个可以理解。因为都只是+1的不同写法,就是不能明白为什么。。。显示的是总引用次数


2、有没有一种比较好的方法实现我的需求???


菜鸟才疏学浅,求教各位大侠帮忙解决这个问题,谢谢




加载中
0
优游幻世
优游幻世
#!/usr/bin/python
#--*encoding=utf8--*
import os
num=0
 
def hehe(w=1):
	global num
	num=num+1
	i=num
	def xiushiqi(fun):
			def test(*args):
					print i,fun(*args)
			return test
	return xiushiqi
 
 
@hehe(num)
def ljq(x,y,z):
    return x*y+z
 
@hehe(num)
def xx(x,y,z):
    return x*y+z
 
@hehe(num)
def xwx(x,y,z):
    return x*y+z
 
 
ljq(2,9,29)
xx(22,9,29)
xwx(8,9,29)

在执行

ljq(2,9,29)
这条语句前num就已经为3,所以才有你的结果,增加个新的变量就行。


优游幻世
优游幻世
回复 @ka-keung : 这里哪有什么循环了,看看这篇文章http://coolshell.cn/articles/11265.html,修饰器的本质就是func=desicriptor(arg)(func),你这里的num是个全局变量,每调用一次修饰器num就会加1,所以在执行那3个函数前num就已经是3了,增加个i在num加1之后将num的值赋给i,i会一直保持那个值。
k
ka-keung
是的,但是它里面一直是一个循环,为什么增加个新变量就可以了?这个我有点不解,按照说这个循环i不断的迭代最终会成为3才进行xiushiqi这个函数。 按照ljq(2,9,29)这句话前,num就已经为3了,是否可以理解,脚本中每有@hehe一次,它自动在hehe这个函数层自动计算?但是这样我还是不理解为什么增加个i就可以了。 求请教。。。
k
ka-keung
正确,求解,为什么要把数字赋值给i才能这样??我看它在hehe这个函数内是一个不断的循环的。。
0
_yjp
_yjp

闭包+后期绑定所导致的。

可以加入下面的打印语句帮助理解,注意调用时机

# -*- coding:utf-8 -*-
num=0


def hehe(fun):
    global num
    num = num+1
    i = num
    print '->0', i, num, id(i), id(num)  # 1
    def test(*args):
            print '->1', i, num, id(i), id(num),  fun # 2
    return test


@hehe
def ljq(x,y,z):
    return x*y+z


@hehe
def xx(x,y,z):
    return x*y+z


@hehe
def xwx(x,y,z):
    return x*y+z#




print hehe(None) # 3  直接调用hehe
print '----------------4' #4


print ljq, ljq.__name__
print xx, xx.__name__
print xwx, xwx.__name__ # 5 打印xwx的函数名




ljq(2,9,29)
xx(22,9,29)
xwx(8,9,29)

 
 
 
 


k
ka-keung
好的,非常感谢你的详细回答
_yjp
_yjp
辅助语句 #1和#2的执行时机完全不同。可以看到 #1在decorator使用时就执行了,#2在xwx、ljq、xx调用时才执行。 闭包中使用的变量的值(test中的i,m, fun),是在内层函数被调用的时候(xwx、ljq、xxx执行的时候)查找的。 查找i,m,fun变量时会自内向外进行查找(参考python作用域规则),i,fun可以在hehe中找到,num则是个全局变量。
k
ka-keung
好的,谢谢,我明天睡醒试试。按照这个说法,是Python的后期绑定造成的,是否可以理解为就是没有很合理的解释了??
返回顶部
顶部