簡體   English   中英

如何實現模式事件以在Python中調用類方法?

[英]How can I implement pattern event to call classmethod in Python?

我想根據事件代碼調用某些函數,如何在Python中實現呢?

我編寫了這樣的代碼,但是它不起作用,並且我認為僅一步之遙就可以使它起作用。

class Thing(object):
    @classmethod
    def do1(cls):
        print 'do1'

    @classmethod
    def do2(cls):
        print 'do2'

    eventToMethod = {'1': do1,
                     '2': do2}

    @classmethod
    def onEvent(cls, name):
        method = cls.eventToMethod.get(name)
        if method != None:
            method()

Thing.onEvent('1')

無論我收到這樣的錯誤,並且不知道如何以Python方式調用類方法。

TypeError: 'classmethod' object is not callable

您可以解決這個簡單的問題嗎?

你需要做出一些改變,以改變eventToMethod第一,不分配do1do2它,更好地分配字符串。 您始終可以使用字符串訪問類屬性。 與存儲到引用的問題do1do2在字典的是,他們不綁定方法,但(他們只是classmethod的對象(非數據描述符))當您將它們存儲在字典中,只有類定義完成后就是他們轉換為完全綁定的類方法。

eventToMethod = {'1': 'do1',
                 '2': 'do2'}

然后使用getaattr來獲取方法:

@classmethod
def onEvent(cls, name):
    method = getattr(cls, cls.eventToMethod.get(name))
    ...

請注意,您也可以直接將'do1'傳遞給onEvent而不用保留字典來存儲名稱,然后簡單地使用:

method = getattr(cls, name)

如果你打電話,你仍然可以擺脫當前的做法__get__的方法do1do2明確描述符:

method = cls.eventToMethod.get(name)
if method != None:
    method.__get__(None, cls)()

這工作,因為這正是Python的引擎蓋下呢, classmethod是一種非數據descriptor ,當你做Thing.do1的Python實際調用__get__的方法do1與第一agument為None和第二類型:

>>> Thing.do1.__get__(None, Thing)
<bound method type.do1 of <class '__main__.Thing'>>
>>> Thing.do1.__get__(None, Thing)
<bound method type.do1 of <class '__main__.Thing'>>
>>> Thing.do1
<bound method type.do1 of <class '__main__.Thing'>>
>>> Thing.eventToMethod['1'].__get__(None, Thing)   #Using OP's code.
<bound method type.do1 of <class '__main__.Thing'>>

雖然我知道這不能直接回答您的問題,但我認為查看替代方法可能會很有用。

通常可以在運行時使用反射來計算正確的方法。 例如:

    @classmethod
    def onEvent(cls, name):
        try:
            method = getattr(cls, 'do%s'%name)
        except AttributeError:
            return

        method()

如果您能夠在方法中遵循嚴格的命名約定(例如,在示例中似乎用“ do”作為前綴),則此方法可能很有用。 這類似於PyUnit檢測要運行的測試用例集的方式。

這避免了維護一個dict的需要,該dict可能與對象上的實際方法不同步。 可以說它還可以導致更清晰的代碼。

值得指出的是,如果您嘗試進行事件驅動的編程,那么有一些庫/框架可以幫助實現這一點:

例:

#!/usr/bin/env python

from circuits import Component, Event


class Thing(Component):

    def do1(self):
        print("do1")

    def do2(self):
        print("do2")

    def started(self, manager):
        self.fire(Event.create("do1"))
        self.fire(Event.create("do2"))
        raise SystemExit(0)


Thing().run()

輸出:

$ python foo.py
do1
do2

免責聲明:我是電路的作者

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM