Tutorial
========
Overview
--------
Welcome to the circuits tutorial. Let's get a few things out of the way...
As mentioned in the README (*included in the circuits distribution*) and in
the introduction to this documentation, circuits is:
a **Lightweight** **Event** driven **Framework** for the
`Python Programming Language <http://www.python.org/>`_ with a
strong **Component** Architecture.
There is a certain style to programming with the circuits framework. It might
be a little foreign at first, but once you get the hang of it, it's actually
fairly straight forward.
In circuits, you implement a functional system by implementing smaller
functional components that interact together to produce more complex
behavior. For example, Component A might be responsible for doing a set
of tasks, while Component B is responsible for another set of tasks. The
two components might occasionally communicate some information (*by passing
messages/events*) to cooperate accomplishing bigger tasks. Designing your
system/application this way encourages a decoupled design and components
in circuits are designed to help accomplish this.
This is called the **Component Architecture**.
The three most important things in circuits are;
* Events
* Components
* Interaction between components
Oh and by the way... In case you're confused, circuits is completely
asynchronous in nature. This means things are performed in a highly
concurrent way and circuits encourages concurrent and distributed
programming.
Without further ado, let's start introducing concepts in circuits...
Events
------
In circuits, information is passed around components in the form of events
(*or messages*). circuits defines an Event class which is used to create an
actual Event object which holds Event data and properties about that event.
The Event object is what is passed around a system of components and also
what is passed to other processes or remote nodes (*by using a Bridge*).
Creating an event
~~~~~~~~~~~~~~~~~
To create an event, simply create an instance of the Event class and pass
any required data to its constructor. For example:
.. code-block:: python
e = Event(1, 2, 3, op="add")
This creates an Event object containing two pieces of data:
* A list containing the numbers: 1, 2, 3
* A string "add" whoose key is ``op`` (*stored as kwargs*).
The Event class's constructor is defined as:
.. code-block:: python
class Event(object):
def __init__(self, ``*args, **kwargs``):
...
**Note**: Normally you would subclass ``Event`` and create your own classes of
events with appropriate docstrings describing what the event is and
what it's used for. You may even create constraints in the args and
keyword args that can be passed to it during initialization.
Using an Event
~~~~~~~~~~~~~~
Once an Event object is created, you can push/fire it into a system by calling
the ``.push(...)`` or ``.fire(...)`` method on any Component in the system or
Manager. For example:
.. code-block:: python
:linenos:
from circuits import Event, Manager
m = Manager()
e = Event("foo")
m.push(e)
m.push(Event("bar"))
Now this doesn't do anything very useful by itself, but we'll get to more
useful things later...
Event Handlers
--------------
In order to do useful things with events and components we need a way to
create **Event Handlers** that react to events. In circuits there are two
types of handlers: **Listeners** and **Filters**.
A Listener is an Event Handler that simply "listens" for an Event while a
Filter is an Event Handler with a higher priority than Listeners and is
capable of filtering the Event from other handlers.
To create an Event Handler (*a Listener*) simply use the ``handler(...)``
decorator on a Component:
.. code-block:: python
:linenos:
from circuits import handler, Component
class System(Component):
@handler("hello")
def onHello(self):
print "Hello World!"
This will create a Component called ``System`` that defines an Event Handler
that listens to the channel "hello".
**Note:**
* The Component automatically defines methods to be Event Handlers that listen
to a channel that is the name of the method. If a Component defines a method
called ``foo``, an an Event Handler will be created that listens to the
channel "foo".
Components
----------
What makes circuits unique in its own way is its **Component Architecture**.
The "circuits way" (tm) is to create components that represent different
functional parts of your system or application. One of the key concepts
is to create more complex components from simpler components. This is a bit
different to subclassing and using multiple inheritance in OOP
(*Object Orientated Programming*). Components are registered to one another
in a directed graph/structure giving a system/application great flexibility.
Components can be registered and unregistered at run-time and even modified.
A Component is also a Manager and every Component can be run independently.
There are three ways in which you can start a Component/Manager:
* ``.run()``: running in the main thread.
* ``.start()``: running in a new separate thread.
* ``.start(process=True)``: running in a new separate process.
Let's look at a few common things that components are used for...
Defining a new Component
~~~~~~~~~~~~~~~~~~~~~~~~
To define a new (*more complex*) Component, simply create a new class that
derives from ``Component``:
.. code-block:: python
:linenos:
from circuits import Component
class System(Component):
"""My System Component"""
Registering Components
~~~~~~~~~~~~~~~~~~~~~~
Components are registered to one another or a Manager by simply calling
the ``.register(...)`` method of a Component or by using the short-hand
``+`` or ``+=`` syntax. For example:
.. code-block:: python
:linenos:
from circuits import handler, Event, Component, Debugger
class Add(Event):
"""Add Event"""
class Print(Event):
"""Print Event"""
end = "print_ended",
class Adder(Component):
@handler("add")
def onAdd(self, x, y):
self.push(Print(x + y))
class Printer(Component):
@handler("print")
def onPrint(self, s):
print s
class System(Component):
def __init__(self):
super(System, self).__init__()
Debugger().register(self)
self += (Adder() + Printer())
def started(self, component, mode):
self.push(Add(4, 5))
def print_ended(self, e, h, v):
raise SystemExit, 0
System().run()
Although this example above seems quite complex and uses quite a few of
circuits' features, it is actually quite simple. You can learn more
about some of the features used above in later documentation but the key
things here are lines 28 and 29 showing the different ways of registering
components.
Here's the output of the above example system/application:
.. code-block:: sh
$ python demo.py
<Registered[*:registered] [<Debugger/* (queued=0, channels=1, handlers=1) [S]>, <System/* (queued=0, channels=5, handlers=5) [R]>] {}>
<Registered[*:registered] [<Printer/* (queued=0, channels=1, handlers=1) [S]>, <Adder/* (queued=0, channels=2, handlers=2) [S]>] {}>
<Registered[*:registered] [<Adder/* (queued=0, channels=2, handlers=2) [S]>, <System/* (queued=0, channels=5, handlers=5) [R]>] {}>
<Started[*:started] [<System/* (queued=0, channels=5, handlers=5) [R]>, None] {}>
<Add[*:add] [4, 5] {}>
<Print[*:print] [9] {}>
9
<End[*:print_ended] [<Print[*:print] [9] {}>, <bound method Printer.onPrint of <Printer/* (queued=0, channels=1, handlers=1) [S]>>, None] {}>
Don't worry about understanding the output above right now. Most of this is
events flowing through the system and printed to the screen by the Debugger
Component so you can see what's going on.
Running/Starting Components
~~~~~~~~~~~~~~~~~~~~~~~~~~~
As stated, y
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
PyPI 官网下载 | circuits-1.3.1.tar.gz (388个子文件)
features.rst.bak 10KB
make.bat 3KB
.buildinfo 230B
BulletList 40B
setup.cfg 188B
CheatSheet 2KB
basic.css 8KB
default.css 4KB
pygments.css 4KB
pygments.css 3KB
screen.css 3KB
base.css 2KB
base.css 50B
DefinitionList 31B
tutorial.doctree 62KB
index.doctree 31KB
introduction.doctree 27KB
features.doctree 15KB
installing.doctree 8KB
gettingstarted.doctree 8KB
downloading.doctree 7KB
telnet.doctree 7KB
foreword.doctree 6KB
basics.doctree 6KB
quickstart.doctree 6KB
ircbot.doctree 5KB
echoserver.doctree 4KB
web.doctree 4KB
manual.doctree 3KB
web.doctree 3KB
gettingstarted.doctree 3KB
examples.doctree 3KB
deployment.doctree 2KB
howtos.doctree 2KB
components.doctree 2KB
dispatchers.doctree 2KB
controllers.doctree 2KB
handlers.doctree 2KB
workers.doctree 2KB
manager.doctree 2KB
futures.doctree 2KB
events.doctree 2KB
values.doctree 2KB
tools.doctree 2KB
FrontPage 2KB
vcss.gif 2KB
rss.gif 1KB
HeadingsPage 55B
.hgignore 130B
.hgtags 1KB
HorizontalLine 22B
tutorial.html 40KB
telnet.html 14KB
index.html 13KB
introduction.html 10KB
ircbot.html 10KB
gettingstarted.html 8KB
installing.html 6KB
features.html 6KB
echoserver.html 6KB
downloading.html 6KB
web.html 5KB
quickstart.html 5KB
gettingstarted.html 5KB
basics.html 5KB
web.html 5KB
manual.html 5KB
foreword.html 5KB
examples.html 4KB
controllers.html 4KB
deployment.html 4KB
howtos.html 4KB
dispatchers.html 4KB
manager.html 4KB
components.html 4KB
handlers.html 4KB
workers.html 4KB
events.html 4KB
futures.html 4KB
values.html 4KB
tools.html 4KB
search.html 3KB
genindex.html 3KB
edit.html 1KB
base.html 1010B
view.html 973B
index.html 822B
index.html 635B
favicon.ico 1KB
favicon.ico 857B
MANIFEST.in 82B
Indented 53B
objects.inv 204B
Image.jpg 5KB
jquery.js 118KB
jquery.js 70KB
searchtools.js 14KB
searchindex.js 8KB
underscore.js 8KB
doctools.js 7KB
共 388 条
- 1
- 2
- 3
- 4
资源评论
挣扎的蓝藻
- 粉丝: 13w+
- 资源: 15万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功