本文介绍了装饰器作为通用的预绑定钩子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! ;-) 我们有 @deco def foo():传递 作为糖(除非装饰者中有未被捕获的例外) def foo():传递 foo = deco(foo) 类名的绑定类似,类装饰器看起来很自然,即 @cdeco class Foo :传递 for class Foo:传递 Foo = cdeco(Foo) 什么正在发生的是我们正在截取某个对象的绑定 并让装饰器在绑定发生之前对该对象做了一些事情。 那么为什么不呢? /> @deco foo = lambda:传递 相当于 foo = deco(lambda:pass ) 从那里, @deco < left-hand-side> =<右手边> 相当于 < left-hand-side> = deco(< right-hand-side>) 例如, @range_check(1,5) a = 42 for a = range_check(1,5)(42) 或 @ default_value(42) b = ce [''f''](''g'') for b = default_value(42) (ce [''f''](''g'')) Hm,binding-intercept-decoration也可以用来捕捉异常, 并将它们传递给装饰者,例如,上面可能是糖用于 尝试: b = default_value(42)(ce [''f ''](''g'')) 除了Exception,e: b = default_value(__ exception __ = e)#so decorator可以检查 #并返回一个值或者只是通过加注重新加注[注1] 这对于普通的旧函数装饰器也是有用的,如果你想装饰器 来定义替换某些东西的政策,例如:默认参数评估 抛出和异常。因此 @deco def foo(x = a / b):传递#例如,如果b == 0怎么办? as 试试: def foo(x = a / b):传递#例如,如果b == 0怎么办? foo = deco(foo) 除了异常,e: 如果不是deco.func_code.co_flags& 0x08:引发#avoid神秘意外关键字TypeError foo = deco(__ exception __ = e) [注1:] 有趣的提升似乎不必在同一帧中或者向下堆叠,所以上面调用的装饰者 可以重新加注: ...除了异常,e:deco(__ exception __ = e) ... {''__ exception__'':< exceptions.ZeroDivisionError实例位于0x02EF190C>} 回溯(最近一次调用最后一次): 文件"< stdin>",第2行,在? 文件"< stdin>",第1行,在? ZeroDivisionError:整数除法或模数为零 正交 - 沉思;-) 问候, Bengt里希特 解决方案 ...除了Exception,e:deco(__ exception __ = e) ... {''__ exception__'':< exceptions.ZeroDivisionError instance at 0x02EF190C>回溯(最近一次调用最后一次):文件"< stdin>",第2行,在?文件"< stdin>",第1行,in ?ZeroQivision错误:整数除法或模数为零 有趣的。 说到装饰器,和现在有了陈述,我不能帮助 但是觉得有某种潜在的概念可以更好地运作。它与以动态方式推广流量控制有关。相对于相关块,。 一个想法是能够使用占位符表达式列表 告诉声明何时执行以下代码块。 我会在这里使用''do''...因为它目前尚未使用,所以使用@@@作为 占位符。 (这些都没有想到那么远,我知道...只是试图 显示可能的方向。) do f = open(filename); @@@; f.close():#do the block where @@@ is。 for line in f: print line, print 和类似于with的备用版本声明。 尝试f = open(filename); @@@;最后f.close(): 换行如果f: 打印行, 打印 也许这个例外可以在试用线完成之后保留吗? 占位符的想法也可能对装饰有用。但是我不知道不知道函数名和arguemtns会如何传递给它。 do deco(@@@): def foo(): 通过 或者可能需要... 做f = @@@,deco(f): def foo() 通过 我说,它仍然需要一些思考.. ;-) 也许离开冒号会使用以下行,而不是 缩进按照你的例子? 做装饰(@@@) b = 42 我觉得这样做并不是很好。可能有几个 不同类型的占位符符号可能会改变行为? 做装饰( )# ;-)We have@decodef foo(): passas sugar (unless there''s an uncaught exception in the decorator) fordef foo(): passfoo = deco(foo)The binding of a class name is similar, and class decorators would seem natural, i.e.,@cdecoclass Foo: passforclass Foo: passFoo = cdeco(Foo)What is happening is we are intercepting the binding of some objectand letting the decorator do something to the object before the binding occurs.So why not@decofoo = lambda:passequivalent tofoo = deco(lambda:pass)and from there,@deco<left-hand-side> = <right-hand-side>being equivalent to<left-hand-side> = deco(<right-hand-side>)e.g.,@range_check(1,5)a = 42fora = range_check(1,5)(42)or@default_value(42)b = c.e[''f''](''g'')forb = default_value(42)(c.e[''f''](''g''))Hm, binding-intercept-decoration could be sugar for catching exceptions too,and passing them to the decorator, e.g., the above could be sugar fortry:b = default_value(42)(c.e[''f''](''g''))except Exception, e:b = default_value(__exception__=e) # so decorator can check# and either return a value or just re-raise with raise [Note 1]This might be useful for plain old function decorators too, if you wanted the decoratorto define the policy for substituting something if e.g. a default argument evaluationthrows and exception. Thus@decodef foo(x=a/b): pass # e.g., what if b==0?astry:def foo(x=a/b): pass # e.g., what if b==0?foo = deco(foo)except Exception, e:if not deco.func_code.co_flags&0x08: raise #avoid mysterious unexpected keyword TypeErrorfoo = deco(__exception__=e)[Note 1:]Interestingly raise doesn''t seem to have to be in the same frame or down-stack, so a decoratorcalled as above could re-raise:... except Exception, e: deco(__exception__=e)...{''__exception__'': <exceptions.ZeroDivisionError instance at 0x02EF190C>}Traceback (most recent call last):File "<stdin>", line 2, in ?File "<stdin>", line 1, in ?ZeroDivisionError: integer division or modulo by zeroorthogonal-musing-ly ;-)Regards,Bengt Richter 解决方案 ... except Exception, e: deco(__exception__=e) ... {''__exception__'': <exceptions.ZeroDivisionError instance at 0x02EF190C>} Traceback (most recent call last): File "<stdin>", line 2, in ? File "<stdin>", line 1, in ? ZeroDivisionError: integer division or modulo by zeroInterestin.When it comes to decorators, and now the with statements, I can''t helpbut feel that there''s some sort of underlying concept that would workbetter. It has to do with generalizing flow control in a dynamic wayrelative to an associated block.One thought is to be able to use a place holder in an expression list totell a statement when to do the following block of code.I''ll use ''do'' here... since it''s currently unused and use @@@ as theplace holder.(These are *NOT* thought out that far yet, I know... just trying toshow a direction that might be possible.)do f=open(filename); @@@; f.close(): # do the block where @@@ is.for line in f:print line,printAnd an alternate version similar to a "with" statement.try f=open(filename); @@@; finally f.close():for line if f:print line,printMaybe the exception could be held until after the try line is complete?The place holder idea might be useful for decorating as well. But I''mnot sure how the function name and arguemtns would get passed to it.do deco(@@@):def foo():passor maybe it would need to be...do f=@@@, deco(f):def foo()passAs I said, it still needs some thinking.. ;-)Maybe leaving off the colon would use the following line withoutindenting as per your example?do deco(@@@)b = 42It doesn''t quite work this way I think. Possibly having a couple ofdifferent types of place holder symbols which alter the behavior might work?do deco( 这篇关于装饰器作为通用的预绑定钩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 07-02 04:13