我有一些類的方法,我希望能夠添加到其他類可選。我最初的解決方案是使用混入,但是也會有點難看:Python(2.7):動態添加類方法
class Schedule(Enumerator, Humanizer, Inferer, ...):
...
所以我想,嘿,也許我可以使用類裝飾來達到同樣的效果。
@enumerator
@humanizer
@inferer
class Schedule(object):
...
這裏是裝飾功能的示例:
import inspect
def inferer(original_class):
from myproj.lib.inferer import Inferer
methods = inspect.getmembers(Inferer, predicate=inspect.ismethod)
for method in methods:
setattr(original_class, method[0], types.MethodTypes(method[1], original_class))
return original_class
...這似乎是適當的添加方法和classmethods到裝飾類。但是,當我在裝飾類上調用其中一種添加的方法(或類方法)時,出現一些錯誤。
對於方法:
>>> Schedule().humanize()
TypeError: unbound method humanize() must be called with Humanizer instance as first argument (got type instance instead)
...這似乎表明,這些被添加爲classmethods?
對於classmethods:
>>> schedule = Schedule.infer(foo)
TypeError: infer() takes exactly 2 arguments (3 given)
注推斷的定義:
class Inferer(object):
@classmethod
def infer(cls, dates):
...
我加了一些線infer
顯示,它被稱爲當得到什麼樣的參數爲Schedule.infer()
:
cls: <class 'myproj.lib.inferer.Inferer'>
dates: <class 'myproj.Schedule'>
所以,我的問題:
裝飾器函數出現錯誤,導致這些添加的方法和類方法行爲奇怪?或者,更好地說,如何修改裝飾器函數以正確處理這些添加?
請讓我知道,如果我可以提供任何澄清任何一點。
所以......你使用裝飾器的唯一原因是因爲傳統的語法看起來很醜陋?這聽起來像是大量的工作和額外的代碼脆弱性,僅僅爲了美學。 –
我不知道爲什麼你認爲使用這樣的裝飾器會比使用mixin更難看(有問題)。這就是說你可能需要使用元類來完成你正在嘗試做的事情。幾年前,我回想起建立一個系統,可以從一組函數中隨時創建類,並且我使用了元類(現在不記得所有的細節,對不起)。 –
我同意:mixins看起來更簡單,更清晰,而且它們實際上工作。爲什麼要去解決所有這些問題? –