是否可以擴展一個應用了裝飾器的類?例如:在Python中擴展裝飾類
@someDecorator
Class foo(object):
...
...
Class bar(foo):
...
...
理想情況下bar不會受裝飾者的影響,但首先我想知道這是否可能。目前,我得到一個非運行時錯誤:
「類型錯誤:錯誤調用元類基地 ()函數的參數1必須是代碼的時候,沒有str的 」
有什麼建議?
是否可以擴展一個應用了裝飾器的類?例如:在Python中擴展裝飾類
@someDecorator
Class foo(object):
...
...
Class bar(foo):
...
...
理想情況下bar不會受裝飾者的影響,但首先我想知道這是否可能。目前,我得到一個非運行時錯誤:
「類型錯誤:錯誤調用元類基地 ()函數的參數1必須是代碼的時候,沒有str的 」
有什麼建議?
正如馬特所說的,你的裝飾器不工作。每當你得到你的裝飾正常工作(通過複製做一些測試,甚至imediate測試,並粘貼到一個控制檯):
什麼的(有效)裝飾返回是類「富」 - 你不能訪問如果使用裝飾器語法,裝飾器在應用之前是什麼。
但是,Python中的裝飾器是一種合成糖,它可以用裝飾器處理該函數或類來返回以下聲明的函數或類。因此,這些是等價的:
@someDecorator
class foo(object):
pass
和
class foo(object):
pass
foo = someDecorator(foo)
因此,你可以簡單地通過執行實現應用裝飾前擴展一個類的效果:
class foo(object):
pass
class bar(foo):
pass
foo = someDecorator(foo)
是的,只要@someDecorator
實際上正在返回一個類是可能的。類裝飾器將類作爲它的參數,並且應該幾乎總是返回一個類,除非你正在做非常不尋常的事情。
foo
,在這種情況下,將被綁定到任何@someDecorator
返回。
這是裝修工會返回其他東西? A str
?
對於任何希望對於所選答案的替代方案,我發現最適合我的方式是在類裝飾器中裝飾__init__
。例如:
def some_decorator(cls):
def decorate_init(func):
def decorated(*args, **kwargs):
func(*args, **kwargs) # Run __init__
instance = args[0]
# Do whatever you need with the newly constructed instance
return decorated
cls.__init__ = decorated_init(cls.__init__)
return cls
很好的解釋,謝謝。我想我現在理解裝飾器有點更好了。 – Graham 2010-07-08 15:43:43