scouter

Watching Data with Callback!


License
BSD-1-Clause
Install
pip install scouter==0.1.2

Documentation

scouter

定义一群类似 Python 内置数据结构的一群数据结构,数据结构发生变化的时候,发生回调。

同时 scouter 还包含了一个易于配置的装饰器模式的 FSM,可以支持 SOP 与 OOP 的结合。

安装方法:

pip install scouter

或者 easy_install

或者下载源代码:

cd scouter
python setup.py install

使用方法:

SVar 使用回调函数监视变量

from scouter import SVar

def callback(now, orig):
    print 'Orig:{} Now:{}'.format(orig, now)

var = SVar(4, callback)
var.value = 5

对于一个 SVar 对象,在定义的时候,可以添加一个回调函数,这个回调函数只接受两个参数:

  • 第一个参数为当前新的值
  • 第二个参数为原来的值

SList 使用回调函数监视列表结构

from scouter import SList

def print_cb(obj, index):
    print obj, index

def print_new(_new, orig):
    print 'new:{} orig:{}'.format(_new, orig)

_list = SList(value=['aaaaaaaa',2,3,4,5],
              add_new_item_callback=print_cb,
              del_new_item_callback=print_cb,
              new_list_value_callback=print_new)

_list.append('asdf')
_list.pop(0)

for i in _list:
    print i

assert 4 == _list[2]

del _list[2]

_list.value = [1,2,3,4,5,]

对于一个 SList 对象,在定义的时候,可以添加三个回调函数,这三个回调函数的参数都有两个参数:

  • 对于 add_new_item_callback 来说,第一个参数是添加的新值,第二个参数是索引
  • 对于 del_new_item_callback 来说,第一个参数是被删除的值,第二个参数是索引
  • 对于 new_list_value_callback 来说,第一个参数是现在的新值,第二个参数是之前的 value
from scouter import SDict

def print_kv(key, value):
    print 'key:{} value:{}'.format(key, value)

def print_new(new, orig):
    print 'new:{}, orig:{}'.format(new, orig)

_dict = SDict({1:2,'key':'value'},
              new_kv_callback=print_kv,
              del_kv_callback=print_kv,
              new_value_callback=print_new)

_dict['key'] = 'hhhhhhhhhvalue1'
_dict['key1'] = 'hhhhhhhhhvalue12'
del _dict[1]


_dict.value = {5:4}

基本同上,只是对于 new_kv_callback/del_kv_callback 来说两个参数分别为 key 和 value。

SOP FSM

更加容易定义更加容易使用的 FSM。

下面是测试用例中的例子

def test_fsm(self):
    """"""
    state_START = 'start'
    state_RUNNING = 'running'
    state_END = 'end'

    class FSMDemo(FSMBase):

        _fsm = FSM()

        #----------------------------------------------------------------------
        def config(self):
            """"""
            self._fsm.preset_all_states(state_END, state_RUNNING, state_START)
            self._fsm.set_start(state_START)
            self._fsm.set_end(state_END)


        @_fsm.transfer(orig=state_START, dest=state_RUNNING)
        def action_run(self):
            """"""
            print('Run!')

        @_fsm.onstate(state_RUNNING, state_START)
        def say_tired(self):
            """"""
            print('I am tired')
            self.action_stop()

        @_fsm.transfer(orig=state_RUNNING, dest=state_END)
        def action_stop(self):
            """"""
            print('Stop working!')


    s = FSMDemo()
    print(s.state)
    assert s.state == state_START
    s.action_run()
    assert s.state == state_RUNNING
    s.say_tired()
    self.assertRaises(FSMError, callableObj=s.say_tired)

关键点在定义一个类变量为 FSM 对象,然后在 config 中配置这个 FSM 对象的预设状态和起始状态,然后定义回调函数通过修饰调用,如果需要限制某一个方法只能在某个特殊状态下使用,需要使用 onstate 这个特殊修饰器修饰。当然,onstate 的参数为你想执行你的这个放在所在的状态:比如你想让你的方法执行在 run/waiting/watching 中,你就需要 @_fsm.onstate(run, waiting, watching) 。当你执行 @_fsm.transfer 修饰过的方法的时候,状态转换被直接执行

当然,FSM 和 FSMBase 都有一个 state 属性来标记当前的状态。