繁体   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