大家好,我最近写了一个Python框架用于开发Mushclient机器人。这个基于mushclient的api,和mushclient api的区别是,这个是一个更“pythonic”的方法,并且更方便使用。例如,用decorator创建一个trigger:- @Trigger.make("一个regexp", ...):
- def callback_function(name,line,wc):
- # ...
- pass
复制代码 再例如,直接用print语句打印到mushclient notepad:- notepad = McTerminal("Title")
- print >> notepad, "hello world!"
复制代码 如果替换sys.stdout:- import sys
- sys.stdout = McTerminal("standard output")
复制代码 所有的程序,只要print到stdout的,都会被redirect到这个notepad!方便吧!
还有最得意的,python的coroutine,也就是Lua的wait:- @coroutine
- def a_coroutine():
- yield
- do_something()
- args, kwargs = yeild ('timer', 0,0,10) # 等待10秒
- args, kwargs = yield ('regexp', '一个触发器') #触发后继续执行下面的语句!
- # ...
复制代码 原帖看这里:http://mushclient.com/forum/?id=10283
下载在这里:http://code.google.com/p/mushpy/downloads/list
This is to announce a Python framework for Mushclient's API. It is a
more "Pythonic" way to develop MUD automations. Currently, there are
several modules available:- * terminal.py:
- Construct a Python file-like object for the Mushclient's notepads
- * objects.py:
- * Trigger
- * Alias
- * Timer
- * coroutine.py:
- * Decorate a callable to use it as a coroutine.
复制代码 The package can be downloaded from here: http://code.google.com/p/mushpy/downloads/list
Package details:
=============
Terminal
=============- Help on class McTerminal in module mushpy.terminals:
- class McTerminal
- | Construct a Python file-like object for the Mushclient's notepads.
- |
- | This is an abstraction of Mushclient's notepads for the ease of use in
- | Python. An example is better than thousand words:
- |
- | >>> import sys
- | >>> sys.stdout = McTerminal("Standard Output")
- |
- | >>> print "Hello world"
- |
- | Once sys.stdout is been replace by an McTerminal instance, all codes that
- | write to stdout (print, etc.) will be directed to a Mushclient's notepad
- | titled "Standard Output". Fancy, heh?
- |
- | When instantiating, several keyword options can be used:
- |
- | * time_stamp: (boolean) prefix a time stamp to each line, default to False
- | * prompt_to_save: (boolean) prompt to save on exit, default to False
- | * read_only: (boolean) if the notepad is readonly. default to True
- |
- | An example:
- |
- | >>> notepad = McTerminal( "An McTerminal Example", time_stamp=True, read_only=True )
- | >>> print >> notepad, "Hello world!"
- | >>> print >> notepad, "Yeah! It's so easy to use Mushclient!"
- |
- | The output:
- |
- | 05/14/10 22:01:26: Initializing...
- | 05/14/10 22:03:41: Hello world!
- | 05/14/10 22:03:57: Yeah! It's so easy to use Mushclient!
复制代码 ============
Trigger
============- Help on class Trigger in module mushpy.objects:
- class Trigger(McObject)
- | The Python wrapper of a trigger representation.
- |
- | This is a thin layer on top of Mushclient's trigger API.
- |
- | The Trigger class only can be instantiate by a name (optional):
- |
- | >> trig = Trigger("trigger_name")
- |
- | or without a name:
- |
- | >> trig = Trigger()
- |
- | One can test if a trigger object has a trigger object exists in Mushclient:
- |
- | >> trig.exists()
- |
- | A trigger w/o name will return False. If a trigger does not exists, one can
- | create one with:
- |
- | >> trig.create( "pattern", group="group_name", one_shot=1, ... )
- |
- | The options are listed in Mushclient's document under SetTriggerOption().
- |
- | If the trigger is instantiated without a name specified, a unique one will
- | be assigned to be when created in Mushclient.
- |
- | If the trigger with the specified name exists, many details about it can be
- | retreived or set, like a Python dict:
- |
- | >> print trig['group']
- | >> print trig['match']
- | >> print trig['enabled']
- | >> print trig['one_shot']
- | >> # ...
- |
- | >> trig['group'] = 'new_group_name'
- | >> trig['enabled'] = 0 # disable
- |
- | Some methods can be used:
- |
- | >>> trig.disable()
- | >>> trig.enable()
- | >>> trig.delete() # this will delete the underlying mushclient trigger
- |
- | One powerfull feature built beyond Mushclient is the callback function:
- |
- | >>> def func(name, line, wc):
- | ... pass
- |
- | >>> trig.callback = func
- |
- | Once the trigger is matched, func will be called. Callback can be accessed like an attribute:
- |
- | >>> print trig.callback
- |
- | It can also be deleted:
- |
- | >>> del trig.callback
- |
- | Note that the callback, once set, will overwrite the existing "script"
- | option. Even it is deleted, the original "script" option will not be
- | restored. However, it is more convenient to use callback so that "script"
- | option need not to be set explicitly any more.
- |
- | WARNING: Do not try to modify a trigger's "script" option once a callback
- | is used. Because MushPy uses a global dispatcher to dispatch (invoke)
- | callbacks for all triggers that has a callback registered. In other words,
- | when a callback is set for a trigger, the trigger's "script" option is set
- | to the global dispatcher. Once changed, when the trigger fires, dispatcher
- | will not be invoked, as a result, the desired call back will not be invoked
- | either.
- |
- | On top of the powerfull callback, the decorator is proudly presented:
- |
- | >>> @Trigger.make( "some pattern", group="group_name", one_shot=1, ... )
- | ... def callback( name, line, wc ):
- | ... pass
- |
- | Therefore, a trigger will be created. The function "callback" will be
- | registered as the trigger's callback.
- |
- | The trigger object is accessible as the callback's attribute. Since a
- | callback function may be used by multiple triggers, multiple aliases, and
- | multiple timers, it has a set, "mc_objects", to store all its connected
- | triggers/aliases/timers.
- |
- | >>> for obj in trig.mc_objects:
- | ... print obj['name']
复制代码 ==============
Alias
==============- Help on class Alias in module mushpy.objects:
- class Alias(McObject)
- | The Python wrapper of Mushclient's Alias
- |
- | Usage is the same as Trigger.
复制代码 =============
Timer
=============- Help on class Timer in module mushpy.objects:
- class Timer(McObject)
- | Python wrapper of Mushclient's Timer.
- |
- | Usage is similar to Trigger/Alias, with a few exceptions.
- |
- | To instantiate:
- |
- | >>> timer = Timer( hour, minute, second, option1=value1, option2=value2, ... )
- |
- | To use as a decorator
- |
- | >>> @Timer.make( hour, minute, second, [keyword options...] )
- | >>> def callback( name ):
- | ... pass
复制代码 ==============
Coroutine
==============- Help on class coroutine in module mushpy.coroutine:
- class coroutine(__builtin__.object)
- | Decorate a callable to use it as a coroutine.
- |
- | Usage:
- | @coroutine()
- | def bla():
- | pass
- |
- | or
- | def bla(): pass
- | bla = coroutine()(bla)
- |
- | To write a coroutine, there is a protocol to follow:
- |
- | 1. The decorated callable takes the arguments to generate the
- | generator. If you don't know what it is, just ignore it and use no
- | arguments.
- |
- | 2. On the first line of the coroutine, you must use the following yield
- | statement to receive the arguments from the caller.
- |
- | args, kwargs = yield
- |
- | 3. Likewise, each time you yield, the return value of the yield
- | statement will be (args, kwargs) from the caller.
- |
- | 4. (Feature) You can use the following yields to specify when to resume
- | running the code below the yields:
- |
- | # resume after 5 seconds
- | args, kwargs = yield ('timer', 0,0,5)
- |
- | # resume when the pattern matched
- | args, kwargs = yield ('match', r'some regular expression pattern')
- |
- | 5. When the coroutine returns, the caller will receive the return value
- | StopIteration. Otherwise, the caller will always receive the return
- | value None. Since it's not the attemp of a coroutine to return
- | something to the caller, but resume doing something at times, I
- | currently do not plan to provide a protocol for returning a meaningfull
- | value to the caller.
- |
- | An example of using coroutines:
- |
- | @coroutine(arg_to_aCoroutine)
- | def aCoroutine(arg_to_aCoroutine):
- | args, kwargs = yield # Must have this at the first line
- | print 'arguments of the first call', args, kwargs
- |
- | args, kwargs = yield ('timer', 0,0,3)
- | print '3 seconds have passed. Arguments:', args, kwargs
- |
- | args, kwargs = yield ('match', r'hello world')
- | print 'I see "hello world" from the MUD output. Arguments:', args, kwargs
- |
- | # Coroutine returns here. Caller will receive StopIteration
- | return
复制代码 |