在pylons的webhelpers是作为单独的一个组件。那么pylons的project是如何来知道调用webhelpers的模块的呢?上次说过h,是用来调用webhelpers的模块的途径,是作为一个全局的对象存在的。可运用在.myt模版中。再来看看,它是如何简单的通过一个h,来调用所有的函数和方法的。
在pylons.__init__.py中有:

m = MyghtyProxy()
c = RequestLocal()
g = GlobalsProxy()
session = SessionProxy()
request = RequestProxy()
buffet = Buffet()
params = RequestArgProxy()
h = Helpers(m=m, c=c, session=session, request=request, buffet=buffet)

Helpers传入了m,c,session,request,buffet等,
再到utils.py中看Helpers的源代码:注意其中的一些__init__,__call__,__getattr__,__setattr__

class Helpers(object):
    def __init__(self, **_pylons):
        self.__dict__['_local'] = RequestLocal()
        self.__dict__['_pylons'] = _pylons
   
    def __call__(self):
        """Initialize Helpers object for request with helpers module/object
       
        When called, the Helpers object will return itself, after initializing
        itself for the current thread/request. It is intended to be run at the
        begginning of every request to clear the thread local it uses and setup
        the helpers space that will be used for fetching helper names as well
        as translation.
        """
        self.__dict__['_local']._clear()
        project_name = CONFIG['app']['package']
        try:
            helpers = getattr(getattr(__import__(project_name+'.config.helpers'), 'config'), 'helpers')
        except:
            helpers = getattr(getattr(__import__(project_name+'.lib.helpers'), 'lib'), 'helpers')
        self.__dict__['_local'].helpers = helpers
        self.__dict__['_local'].translator = _Translator()
        self.__dict__['_local'].config = CONFIG
        if CONFIG['app'].has_key('lang'):
            self.set_lang(CONFIG['app']['lang'])
        else:
            self.__dict__['_local'].lang = None
        return self
       
    def __getattr__(self, name):
        if hasattr(self.__dict__['_local'].helpers, name):
            return getattr(self.__dict__['_local'].helpers, name)
        elif name in self.__dict__['_local'].keys() and name != '_local' and
                                len(str(name))>0 and str(name)[0] != '_':
            return getattr(self.__dict__['_local'],name)
        else:
            raise AttributeError('No such helper %s'%repr(name))

从中可以解读为,h是可以从已经通过import加载的模块中找到自己需要的函数与方法。
__call__()中有:
        project_name = CONFIG['app']['package']
        try:
            helpers = getattr(getattr(__import__(project_name+'.config.helpers'), 'config'), 'helpers')
        except:
            helpers = getattr(getattr(__import__(project_name+'.lib.helpers'), 'lib'), 'helpers')
        self.__dict__['_local'].helpers = helpers

比如project_name对应建立的pylons的project--->helloworld,在helloworld的lib中helpers.py,很简单,就是加载需要的,

"""
Helper functions
All names available in this module will be available under the Pylons h object.
"""
from webhelpers import *

webhelpers的__init__.py就是把所有rails中的模块一次性全部import进去。
这样如果在.myt中使用h时,它就会通过__getattr__到__dict__中找到相应的function或method来完成调用。

这一段真是充分展现了动态语言的威力。所有function,method的查询,定位都是缘于动态语言提供的便利。