Karrigell 中文版官方文档 P02

6. Programming

在Karrigell中有好几种写程序的方式:

  • 纯Python脚本,使用简单的变量,还有HTML Inside Python
  • Karrigell Services方式,这是一个Python脚本它可以处理整个站点(或者一些部分页面)
  •  像PHP一样混和HTML与代码的方式,即Python Inside HTML

这些不同的编程方式都使用相同的方式访问HTTP环境变量和表单数据,这些都会在下面的文档里分别描述。

我们也可以使用其它几种受支持的脚本:如果想使用.foo来管理脚本,我们可以写一个叫作mod_foo的模块。可以参见使用mod_tmpl.py管理Cheetah模板系统管理的例子。

6.1 Accessing HTTP environment

在Karrigell脚本运行的名字空间里提供通过全局变量来访问HTTP环境变量:

  • HEADERS是一个带有HTTP头数据的字典:它的健值是头名字,值是相应头的值。比如HEADERS["accept-language"]将返回accept-language头值
  • RESPONSE是一个用来设置响应头以发送到服务器端的字典。这个字典键的名字是不区别大小写的:RESPONSE['Content-type']与RESPONSE['CONTENT-type']返回同样的结果
  • AUTH_USER和AUTH_PASSWORD是用于身份认证的值
  • COOKIE是一个与Python的Cookie模块中的SimpleCookie对象相同的字典,它存储的cookies随着HTTP请求被web浏览器发送到服务器端
  • SET_COOKIE是另一个SimpleCookie对象,我们可以设置它的键和值它将被当作cookies存储在客户端的浏览器中
  • ACCEPTED_LANGUAGES是一个客户端浏览器可接受的语言列表,它按优先顺序排序。列表中的项都是根据ISO 639规范使用两个字符的字符串来标识一种语言(如en代表English,fr代表French,等)
  • 在更高级的应用中,REQUEST_HANDLER代表当前RequestHandler实例。它暴露出一些属性如client_address它使用一个元组来表示客户端的IP地址和端口。参见Python标准分发包文档中的BaseHTTPServer和SimpleHTTPServer模块
  • THIS是一个代表当前脚本的脚本类的实例
6.2 Form fields

QUERY是一个字典变量代表着当使用HTTP GET方法或HTTP POST方法提交表单数据时的查询字符串。QUERY的键名字就是表单中的字段名,它的值就是字符串形式的字段值,或当字段名以[ ]结尾时使用列表来表示字段的值(比如一个<SELECT MULTIPLE>表单字段)

假设我们有这样一个HTML表单:

<form action="myScript.py">
  Spam <input name="spam">
  <br><select multiple name="animal[]">
  <option value="dog">Dog
  <option value="cat">Cat
  <option value="frog">Frog
  </select>
  <br><input type="submit" value="Ok">
</form>

在myScript.py中input字段将会这样被显示:
print "<br>Spam is ",QUERY["spam"]
if QUERY.has_key("animal"):
    print "<br>Animal is ",str(QUERY["animal"])

可以通过一种快捷方式来访问这些数据,即使用_与字段名组合起来。下面的代码将会像这样写:

 print "<br>Spam is ",_spam
if QUERY.has_key("animal"):
    print "<br>Animal is ",str(_animal)

使用下划线是为了避免字段名与Python保留字或相同的模块名字冲突
6.3 Smart urls

通常情况下往一个脚本里传递参数是在url里使用查询字符串或者post数据,而另一种选择是把参数作为url的一部分来传递,就像http://host/path/script.py/foo/bar ,这里的参数就是foo和bar

在脚本里我们可以通过一个列表来访问这些参数,它是THIS的一个属性即THIS.subpath:

print "The parameters are %s" %THIS.subpath
这个url存在的问题是当我们使用Include或写一个相关的链接或插入一个图像或JavaScript,如果调用这个脚本没有使用subpath或subpath中有一些参数这时url肯定会有所不同.
例如在脚本里写这样一个相关的url:
print '<IMG SRC="images/pic.png">'
然后调用这个脚本http://host/path/script.py/foo/bar,浏览器将会计算绝对路径,点击这个链接后:
http://host/path/script.py/foo/images/pic.png,使用参数foo,images,pic.png执行相同的脚本显然这不是我们想要的。
因此如果我们计划在一个子路径里传递一个参数,将必须像这样写相关的url:
print '<IMG SRC="%simages/pic.png">' %THIS.up
THIS.up代表着有多少参数就会有多少个字符串'../'
我们也可以使用baseurl属性,它将会返回当前的路径path/
6.4 File uploads
为了从客户端上传一个文件到服务器端,表单中的input标签必须有一个类型为'file'的。比如有一个表单像这样:
<FORM ENCTYPE="multipart/form-data" ACTION="fileUpload.py" METHOD=POST>
File to process: <INPUT NAME="myfile" TYPE="file">
<INPUT TYPE="submit" VALUE="Send File">
</FORM>
那个脚本使用变量QUERY['myfile']或_myfile来处理要上传的文件,它是cgi模块内置类FieldStorage的一个实例。
这个对象有两个属性:
 
 
  • filename:文件的名字
  • file:一个像file的对象可用来读取文件的内容
例如我们想在服务器端的文件系统使用相同的文件名保存文件:
import os
f = _myfile.file # file-like object
dest_name = os.path.basename(_myfile.filename)
out = open(dest_name,'wb')
# copy file
import shutil
shutil.copyfileobj(f,out)
out.close()
6.5 Exceptions

在Karrigell的Python脚本中可以触发特殊的异常来处理脚本

SCRIPT_END

当我们想停止发送数据到浏览器又不想让脚本执行到文件末尾可以使用这个异常。这个异常在我们调试脚本或想让它某个

地方停止运行以查看脚本状态或变量值时非常有用

myVar=10
...
print myVar
raise SCRIPT_END
... (rest of code - won't be run)

SCRIPT_ERROR
使用raise SCRIPT_ERROR,msg来停止脚本的执行并输出msg
HTTP_ERROR
raise HTTP_ERROR,(errorCode,errorMessage)将导致Karrigell使用一个特定的错误代码和信息发送一个HTTP错误信息
HTTP_REDIRECTION
raise HTTP_REDIRECTION,url将导致Karrigell重定向一个请求到一个给定的URL
6.6 HTMLStream

HTMLStream是HIP模块里面的一个类它比重复使用print语句要容易。它的设计像HTML Inside Python但使用不同的实现方式

创建这个类的一个实例:

import HIP
H = HIP.HTMLStream()

然后使用"+"和"-"来打印数据到标准输出:使用"+"数据将当作字符串被打印出来,使用"-"将使用cgi-escaped格式输出

aDict={"one":"unan","two":"daou","three":"tri"}
H + aDict - type(aDict)

它们和下面的代码是一样的:
aDict={"one":"unan";"two":"daou";"three":"tri"}
print str(aDict),cgi.escape(type(aDict))

7. Debugging

7.1 Debug mode

当我们测试新版本程序时,我们要重新导入改变后的模块通常会有些情形。考虑到性能的原因,标准Python解释器会导入模块已编译过的版本,而不会检查它的源代码是否修改过

我们可以设置配置文件里的reloadModules选项为1,它会强制加载这个模块最后一次修改的版本

一旦这个程序正式工作后,我们可以设置它的调试模式为0

7.2 Error handling and debugging

当我们调用一个URL发生错误时,将会在浏览器里显示一个调用栈

这些信息包括以下几个部分:

  • 调用的url
  • 在一个表格里显示错误发生的地方:也有可能显示的不是脚本代码而是一个名字匹配的url,在这种情况下一般是错误发生在使用Include()函数被包含的脚本里。这时会显示一个树状的结构。表格里会显示脚本名字,异常名字,在错误脚本里的行号与所在行的文本
  • 未经过处理的Python调用栈
  • 如果配置文件里的debug选项设置为1还会显示一个"Debug"按钮

例如:

Error in /demo/errors/ErrorInIncludedTest1.py
/demo/errors/ErrorInIncludedTest1.py
 includes /demo/errors/ErrorInIncludedTest2.py
Script /demo/errors/ErrorInIncludedTest1.py
      
      
NameError: name 'bonjour' is not defined
Line 1   
print 'Script 1'
Traceback (most recent call last):
  File "C:/cygwin/home/Karrigell/Template.py", line 153, in render
    exec self.pythonCode() in ns
  File "<string>", line 1, in ?
NameError: name 'bonjour' is not defined

 点击这个"Debug"按钮我们还可以得到关于这个错误的更多信息:

  • 会语法加亮显示源代码,并且在错误发生的地方会高亮显示
  • 一个环境变量的视图,我们可以在这个视图里浏览并查找变量的值和函数或方法的源代码等

屏幕截图:

 如果我们不想让用户看到这些信息,我们可以设置配置文件里的debug选项为0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值