对于我这个从.NET过来的人,对python的str和unicode会感到非常不适应。经常在一些常用的地方遇到编码异常问题。如保存字符串到文本中,是要先编码还是直接保存呢?字符串是str还是unicode呢?保存字符串到数据库是直接保存str又或是先将unicode编码得到的str呢?
好多个问号,这都是我个python初学者碰到的问题。在尝试多次痛苦后,总算有了一些思路。原来unicode早已在python实现的很好,只是我使用不当罢了。
一个很关键的并且要常记住的,就是代码中所有字符串都统一使用unicode,而不是str。这样,自己就能很清楚要处理的字符串类型了。请记住,是所有,任何地方。
例如:
>>> s1 = u'%s欢迎您!' % u'北京'
>>> s1
u'\u5317\u4eac\u6b22\u8fce\u60a8\uff01'
>>> print s1
北京欢迎你!
若像这样,就会抛异常:
>>> s2 = '%s欢迎您!' % u'北京'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 2: ordinal not in range(128)
由UnicodeDecodeError可猜想得到,解析器尝试使用ascii对'%s欢迎您!'进行解码,由于'%s欢迎您!'实际是使用utf-8编码的(这是我系统终端默认的),所以使用ascii解码肯定会错,只要如下,就可以重现这个异常了:
>>> s2 = '%s欢迎您!'.decode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 2: ordinal not in range(128)
分清encode和decode。str --> decode(c) --> unicode, unicode --> encode(c) --> str,其中编码类型c必须相同。
将unicode字符串写入文件前先使用特定编码对其进行编码(如unicodestr.encode('utf-8'))得到str,保证写入文件的是str;从文件读取到str,然后对其进行解码(如encodestr.decode('utf-8'))得到unicode。这是互逆的两个操作,编码类型一定要一致,否则会出现异常。
自己支持了unicode,但是你团队的其他人是否都使用unicode呢?你使用的其他模块是否也使用unicode呢?这个一定要清楚的,不然同样会出现许多因为编码问题的异常。
好了,晚了,随便写了点,大家晚安,2008.8.1,本世纪的第一次日全蚀,你要看吗?
Technorati 标签:
python,
unicode,
str
posted @
2008-08-01 01:15 MK2 阅读(35) |
评论 (0) |
编辑
最近都在研究如何利用最少的字节判断两个PE文件是否相同。
PE文件几个关键:
1. 在一个PE文件的开始处,我们会看到一个MS-DOS可执行体(英语叫“stub”,意为“根,存根”);它使任何PE文件都是一个有效的MS-DOS可执行文件。如图蓝色框部分。0x5A4D:MZ,每个PE文件都是以此开始。
2. 在DOS-根之后是一个32位的签名以及魔数0x00004550 (IMAGE_NT_SIGNATURE)(意为“NT签名”,也就是PE签名;十六进制数45和50分别代表ASCII码字母E和P)。
3.
4. DOS-根和签名(DOS-stub and Signature)
你可以通过确认DOS-头部分是否为一个IMAGE_DOS_HEADER(DOS头)结构来认出DOS-根,它的前两个字节必须为连续的两个字母“MZ”(有一个#define IMAGE_DOS_SIGNATURE的定义是针对这个WORD单元的)。
DOS-根的概念很早从16位windows的可执行文件(当时是“NE”格式),现在是PE。
可以通过跟在后面的签名来将一个PE二进制文件和其它含有根的二进制文件区分开来,跟在后面的签名可由头成员'e_lfanew'(它是从字节偏移地址 60(0x3C)处开始的,有32字节长)所设定的偏移地址找到。对于OS/2系统和Windows系统的二进制文件来说,签名是一个16位的word单元;对于PE 文件来说,它是一个按照8位字节边界对齐的32位的longword单元,并且IMAGE_NT_SIGNATURE(NT签名)的值已由#defined定义为0x00004550(即字母“PE/0/0”)。
即:判断一个文件是否PE:1)判断开始两字节是否 0x5A4D;2)根据0x3C~3F的得到偏移地址,然后根据偏移地址获得签名,判断该签名是否属于PE即可。
5. 文件头
开始于0x00E4,有0x14字节长,到0xF8:
Machine 4c 01 ; i386
NumberOfSections 03 00 ; 代码段和数据段
TimeDateStamp 20 84 7D 3B ;
PointerToSymbolTable 00 00 00 00 ; 未用
NumberOfSymbols 00 00 00 00 ; 未用
SizeOfOptionalHeader e0 00 ; 常量
Characteristics 0F 01(0000 0001 0000 1111B) ; 32位机器上的可执行文件
成员“Characteristics(特性)”是一个16位的,由许多标志位形成的集合组成,但大多数标志位只对目标文件和库文件有效。具体如下:
位0 IMAGE_FILE_RELOCS_STRIPPED(重定位被剥离文件) 表示如果文件中没有重定位信息,该位置1,这就表明各节的重定位信息都在它们各自的节中;可执行文件不使用该位,它们的重定位信息放在下面将要描述的“base relocation”(基址重定位)目录中。
位1 IMAGE_FILE_EXECUTABLE_IMAGE(可执行映象文件) 表示如果文件是一个可执行文件,也即不是目标文件或者库文件时,置1。如果链接器尝试创建一个可执行文件,却因为一些原因失败了,并保存映像以便下次例如增量链接时使用,此时此标志位也可能置1。
位2 IMAGE_FILE_LINE_NUMS_STRIPPED(行数被剥离文件) 表示如果行数信息被剥除,此位置1;此位也不用于可执行文件。
位3 IMAGE_FILE_LOCAL_SYMS_STRIPPED(本地符号被剥离文件) 表示如果文件中没有关于本地符号的信息时,此位置1(此位也不用于可执行文件)。
位4 IMAGE_FILE_AGGRESIVE_WS_TRIM(强行工作集修剪文件) 表示如果操作系统被假定为:通过将正在运行的进程(它所使用的内存数量)强行的页清除来修剪它的工作集时,此位置1。如果一进程是大部分时间处于等待,且一天中仅被唤醒一次的演示性的应用程序之类时,此位也应该被置1。
位7 IMAGE_FILE_BYTES_REVERSED_LO(低字节变换文件)和 位 15IMAGE_FILE_BYTES_REVERSED_HI(高字节变换文件) 表示如果一文件的字节序不是机器所预期的形式,因此它在读入前必须调换字节时,此位置1。这样做对可执行文件是不可靠的(操作系统期望可执行文件都已经被正确地按字节排整齐了)。
位8 IMAGE_FILE_32BIT_MACHINE(32位机器文件) 表示如果使用的机器被期望为32位的机器时,此位置1。现在的应用程序总将此位置1;NT5系统可能工作不同。
位9 IMAGE_FILE_DEBUG_STRIPPED(调试信息被剥离文件) 表示如果文件中没有调试信息,此位置1。此位可执行文件不用。按照其它信息([6])(这里指的是参考书目中的第[6]种----译者注),此位被称作“恒定”,并且当一个映象文件只有在被装入优先的装入地址才能运行(亦即:此文件不可重定位)时,此位置1。
位10 IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP(移动介质文件从交换文件运行) 表示如果一个应用程序不可以从可移动的介质,如软盘或CD-ROM上运行时,此位置1。在这种情况下,建议操作系统将文件复制到交换文件并从那里执行。
位11 IMAGE_FILE_NET_RUN_FROM_SWAP(网络文件从交换文件运行) 表示如果一个应用程序不可以从网络上运行时,此位置1。在这种情况下,建议操作系统将文件复制到交换文件并从那里执行。
位12 IMAGE_FILE_SYSTEM(系统文件) 表示如果文件是一个象驱动程序那样的系统文件,此位置1。此位可执行文件不用;我所见过的所有NT系统的驱动程序也不用。
位13 IMAGE_FILE_DLL(DLL文件) 表示如果文件是一个DLL文件时,此位置1。
位14 IMAGE_FILE_UP_SYSTEM_ONLY(仅但处理器系统的文件) 表示如果文件不设计运行在多处理器系统上(也就是说,因为此文件严格地依赖单一处理器的一些方式工作,所以它会发生冲突)时,此位置1。
在看来一个DLL的文件头
Characteristics 0E 21(0010 0001 0000 1110B 高-低) ; 32位机器上的DLL文件
参考:
http://bbs.pediy.com/showthread.php?threadid=21932
posted @
2008-06-23 19:32 MK2 阅读(44) |
评论 (0) |
编辑
A呵呵,一直都是用WLW写blog的,很久之前就装了
Scribefire,一直都没用,今天来个测试,呵呵,如果满意,以后就用它了。
直接帖截图测试:
edit

上传图片测试:OK
测试其他吧,
哈哈,
乱来。
©®°±¶º¿¿¾
呵呵,看来真的可以取代WLW
Technorati Tags:
scribefire,
firefox,
wlw
posted @
2008-06-10 19:23 MK2 阅读(50) |
评论 (0) |
编辑
因经常在多台机器上使用Firefox,难免会想装一些已经习惯了的插件(晕,都依赖他们),没安装上总是用起来不顺手。于是就有了这篇文章。
1. 第一个要备忘的肯定是它:Google Browser Sync
可以同步些什么?看看这个截图吧:
很Cool吧,仿佛在那台机打开FF,都感觉是一样的,完全获取回上次的所有状态,并且支持加密传输,这样个人私隐就不会泄露了。
2. GMarks
虽然说Google Browser Sync可以同步Bookmarks,但是我还是喜欢将Bookmarks保存到互联网上,GMarks就是一个Google Bookmarks的插件,使用也非常简单,Bookmarks太多了吧,不記得放在那个位置了吧,呵呵,不怕,在自己的Bookmarks上搜索一下不就行了?
3. All-in-One Gestures Extension
有使用鼠标手势控制的习惯吧?怕使用了Firefox而无法拥有这个功能吗?呵呵,哪All-in-One Gestures Extension肯定是你的最爱,完全支持你想要的手势。
4. DictCN (呵呵,忘记推荐沪江小D,绝对比这个精彩多了!!!)
呵呵,像我这些英语很差但是又要经常看英文的人,这个插件肯定比钱包更加重要,放在你的FF上吧,肯定会用上的,特别是它还支持发音功能。
5. AutoHide
觉得FF上方的工具栏太占位置了吗?导致看到的页面太小了吧?呵呵,这个插件绝对帮你将工具栏完全隐藏了,按Shift+F11让FF全屏吧。
6. Firebug 不顶不行
呵呵,这个不用我介绍了吧,太出名了!!!

估计每个做Web开发的人的FF上都会有它。o(∩_∩)o...
7. Showcase
经常打开几十个tab而又不想关掉它们吗?是不是要找一个tab花了很多时间?使用Showcase可以让你马上找到你想找的tab,不信?看看截图吧:
想用了吧?
8. IE Tab
不用IE不行啊,有时候真的没有了IE,很多事情就没法做了,于是有打开IE。很麻烦吧,如果你的系统是Windows,那么IE Tab可以很方便地设置当前页面使用IE内核访问,还可以设置更多的规则,唉,我们的世界没了IE真不容易:
9. Fireshot
一个页面太长了吧,是否有想将整个页面截图处理的需求呢?Fireshot可以实现,并且还有上传,直接将截图的链接发给你的朋友吧,呵呵,这样介绍网站,也是一个不错的选择。
10. Tab Scope
想预览一下tab里面是什么内容吗?看看它是不是已经加载完了?这个插件可以提高你的兴趣。
11. QuickDrag
可以直接拖拉页面上的链接,并在新tab中打开,不用点鼠标中键了,Cool啊!!
12. ColorZilla
可以获取页面上任意部位的颜色。
??. FEBE
好了,装了这么多插件,有备份这些插件的插件吗?呵呵,你都想备份了吧?用FEBE吧,你想怎样备份都可以。
这里可以查看更多截图:http://customsoftwareconsult.com/extensions/febe/febe50/FEBE5.0.html
呵呵,今天到此为止吧,以后用到更多好的插件我会继续补充的,:-)
希望对你有用!!
posted @
2008-06-09 10:49 MK2 阅读(216) |
评论 (2) |
编辑
在没有使用AjaxForm前,我做的一个小小的评论提交的Web form,评论内容使用了TinyMCE做文本编辑。为了增加一点点的用户体验,就顺手拿AjaxForm来实现Ajax提交。可是发现出现了一个意外的事情。就是每次提交,第一次提交时,AjaxForm会无法获得当前编辑的评论内容,即TextArea里面的内容,要再点击一次提交,才能将TextArea的内容提交上去。
关键是TinyMCE上的内容没有在提交前更新到TextArea中。于是想看看AjaxForm是否有在提交前的事件绑定,发现在beforeSubmit事件中,formData的内容已经被填充,虽然可以在此处自行将当前的TinyMCE的内容填充上去(详细可查看这里),可是总觉得是不太漂亮的解决方案。
为了找是否有其它途径解决此问题,我查看了一下AjaxForm的源代码,发现原来AjaxForm作者已经为这问题提出了统一的解决方案,具体源代码如下:
// hook for manipulating the form data before it is extracted;
// convenient for use with rich editors like tinyMCE or FCKEditor
var veto = {};
this.trigger('form-pre-serialize', [this, options, veto]);
if (veto.veto) {
log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
return this;
}
果然,真的有对应的事件让我们可以在formData被序列号前将TinyMCE的数据更新到TextArea中。只要我们绑定form的form-pre-serialize事件即可。
于是一个我的代码就这样出来了:(对应FCKEditor类似)
// bind form using 'ajaxForm'
$('#commentForm').ajaxForm(options);
// 绑定form-pre-serialize事件,在触发form-serilaize事件前保存tinyMCE的数据到textarea中
$('#commentForm').bind('form-pre-serialize', function(event, form, options, veto) {
tinyMCE.triggerSave(); });
^_^ 希望对你有用...
posted @
2008-06-08 20:38 MK2 阅读(230) |
评论 (2) |
编辑
最近在收集PE的FileInfo信息,发现不是每个PE都会有,而且有也不一定全部都有,总结了样本,基本上包含一下信息:
LegalCopyright :版权信息
InternalName: 内部名称
FileVersion:文件版本
CompanyName:公司名称
LegalTrademarks:注册商标
Comments:注释
ProductName:产品名称
ProductVersion:产品版本
FileDescription:文件描述
OriginalFilename:原始文件名
PrivateBuild:私有编译 (见样本3)
SpecialBuild:特殊编译
几个特殊的信息:
BuildDate: 编译日期 (见样本1)
BuildNumber: 编译号(见样本1)
FileType: 文件类型 (本应该出现在VS_FIXEDFILEINFO中的,却又出现在FileInfo中,造成冲突,以VS_FIXEDFILEINFO中的为准)(见样本1)
OLESelfRegister: (见样本2)
文件的分析信息列表:
样本1:http://www.cnblogs.com/Files/fengmk2/35d417aa12d58edfc4ed0156e8ee855f.Nap.txt
样本2:http://www.cnblogs.com/Files/fengmk2/OLESelfRegister_QQ.exe.txt
样本3:http://www.cnblogs.com/Files/fengmk2/PrivateBuild_8c26cc7d912ab9568b44a62291f7ac51.dll.txt
posted @
2008-06-06 10:40 MK2 阅读(32) |
评论 (0) |
编辑
在threading module中,有一个非常特别的类local。一旦在主线程实例化了一个local,它会一直活在主线程中,并且又主线程启动的子线程调用这个local实例时,它的值将会保存在相应的子线程的字典中。
我们先看看测试代码:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Description: test the threading.local class
# Create: 2008-6-4
# Author: MK2[fengmk2@gmail.com]
from threading import local, enumerate, Thread, currentThread
local_data = local()
local_data.name = 'local_data'
class TestThread(Thread):
def run(self):
print currentThread()
print local_data.__dict__
local_data.name = self.getName()
local_data.add_by_sub_thread = self.getName()
print local_data.__dict__
if __name__ == '__main__':
print currentThread()
print local_data.__dict__
t1 = TestThread()
t1.start()
t1.join()
t2 = TestThread()
t2.start()
t2.join()
print currentThread()
print local_data.__dict__
运行结果:
<_MainThread(MainThread, started)>
{'name': 'local_data'}
<TestThread(Thread-1, started)>
{}
{'add_by_sub_thread': 'Thread-1', 'name': 'Thread-1'}
<TestThread(Thread-2, started)>
{}
{'add_by_sub_thread': 'Thread-2', 'name': 'Thread-2'}
<_MainThread(MainThread, started)>
{'name': 'local_data'}
主线程中的local_data并没有被改变,而子线程中的local_data各自都不相同。
怎么这么神奇?local_data具有全局访问权,主线程,子线程都能访问它,但是它的值却是各当前线程有关,究竟什么奥秘在这里呢?
查看了一下local的源代码,发现就神奇在_path()方法中:
def _patch(self):
key = object.__getattribute__(self, '_local__key')
d = currentThread().__dict__.get(key)
if d is None:
d = {}
currentThread().__dict__[key] = d
object.__setattr__(self, '__dict__', d)
# we have a new instance dict, so call out __init__ if we have
# one
cls = type(self)
if cls.__init__ is not object.__init__:
args, kw = object.__getattribute__(self, '_local__args')
cls.__init__(self, *args, **kw)
else:
object.__setattr__(self, '__dict__', d)
每次调用local实例的属性前,local都会调用这个方法,找到它保存值的地方.
d = currentThread().__dict__.get(key) 就是这个地方,确定了local_data值的保存位置。所以子线程访问local_data时,并不是获取主线程的local_data的值,在子线程第一次访问它是,它是一个空白的字典对象,所以local_data.__dict__为 {},就像我们的输出结果一样。
如果想在当前线程保存一个全局值,并且各自线程互不干扰,使用local类吧。
posted @
2008-06-04 22:46 MK2 阅读(78) |
评论 (0) |
编辑
先来看看我们之前是怎样获取到当前登录user的:在view中,我们常常就会通过request对象来获取当前用户user的引用:
def comment_add(request):
# do something...
user = request.user
# to do .....
这样,确实很方便就能获取多用户的信息。可是,如果要做别的地方获取user呢?例如要在model中获取user呢?
class Post(models.Model):
title = models.CharField('Post标题', maxlength=100, db_index=True)
create_date = models.DateTimeField('发布时间', default=datetime.now(), editable=False)
modified_date = models.DateTimeField('最后修改时间', default=datetime.now(), editable=False)
author = models.ForeignKey(User, verbose_name="作者", editable=False)
content = models.TextField('内容')
last_visitor_IP = models.IPAddressField('最后的访问者IP', null=True, blank=True, editable=False)
tags = models.ManyToManyField(Tag, verbose_name="the list of tags", null=True, blank=True)
slug = models.SlugField('自定义url', maxlength=100, null=True, blank=True)
hits = models.IntegerField('点击数', editable=False, default=0)
可以看到,author是editable=False的,即我们想Post被保存是自动设置author为当前登录用户user。而这里没有request,怎样获取到这个user呢?找了一下django的文章,提到了使用middleware来解决这个需求。
好吧,先在项目中创建一个"middleware"模块(即带有一个空__init__.py文件的目录),接着创建"threadlocals.py"到此目录,代码如下:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Description: thread locals middleware
# Create: 2008-6-4
try:
from threading import local
except ImportError:
from django.utils._threading_local import local
_thread_locals = local()
def get_current_user():
return getattr(_thread_locals, 'user', None)
class ThreadLocals(object):
"""Middleware that gets various objects from the
request object and saves them in thread local storage."""
def process_request(self, request):
_thread_locals.user = getattr(request, 'user', None)
接着将此middleware添加到项目中,打开setting.py,修改代码如下:
MIDDLEWARE_CLASSES = (
"django.middleware.common.CommonMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"yourproject.middleware.threadlocals.ThreadLocals",
)
写到这里,发现这不类似与asp.net中的HttpModule吗?
然后为了自动设置author为当前用户,我们需要重载post的save方法:
先导入middleware
from net4.middleware import threadlocals
def save(self):
if self.id is None:
self.author = threadlocals.get_current_user()
super(Post, self).save()
编码工作完成了,还不快点进入admin看看是否可以正常工作了呢?
其实大部分都是算直接在参考文章里哪过来的,呵呵,反正是花了点时间才找到,呵呵,就拿来主义,让大家一齐分享咯。
希望对你有用! ^_^
本文参考:
Making User info available outside requests
posted @
2008-06-04 16:52 MK2 阅读(88) |
评论 (2) |
编辑
今天在群聊的时候,有同学发了最新版Google拼音的功能介绍,其中英文提示:打英文时只需输入前几个字母,输入法自动提示您可能要找的单字。
就是这个功能,我联想到了每天都要做的事情:编程。第一个浮现在脑海里的是VS里的智能感知,于是打开很久没打开的VS2008来回味。
然后我在想,输入法能做到这样吗?为了看看英文提示的效果,我下载了google拼音输入法。
输入我们最喜欢的hello world.
果然是有提示。然后我输入一个python的open方法
,在此刻,我想到的是如果
的正下方有open的api文档说明和使用示例该多好啊。就像VS2008的智能感知的截图一样。
让智能感知脱离IDE而存在,让我们这些程序员能在文本文档下编程也有智能感知的功能,只需要我们的输入法支持就可以了。
于是编程输入法的设想就这样出现,至于谁先去实现?我想谁都可以。
再看看Eclipse的智能感知:
同样的效果,不过条件都是需要装IDE。
相信不久的将来,我们肯定会用上这个输入法的。
posted @
2008-05-31 14:31 MK2 阅读(42) |
评论 (1) |
编辑
昨天在保存一些中文字符到文本文档时,发现一个很奇怪的现象。先看看代码:
#coding=utf-8
import os
def write_use_open(filepath):
try:
file = open(filepath, 'wb')
try:
content = '中华人民共和国abcd \r\nee ?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n'
print file.encoding
print file.newlines
print file.mode
print file.closed
print content
file.write(content)
finally:
file.close()
print file.closed
except IOError, e:
print e
if __name__ == '__main__':
filepath = os.path.join(os.getcwd(), 'file.txt')
write_use_open(filepath)
开始我是IDLE编写的,并直接按F5运行,没发现问题,文件也被正确地保存,文件的编码类型也是utf-8.
可是我用命令行运行,却发现显示出现乱码了,然后在打开文件发现文件被正确保存了,编码还是utf-8:
我想问题是命令行不能自动识别字符编码吧,因为IDLE显示是正确的,它支持utf-8。
于是我修改了代码,在字符串前加了'u',表明content是unicode:
content = u'中华人民共和国abcd \r\nee ?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n'
可是运行发现,命令行是正确显示了,但是却出现异常:
很明显,content里包含了非ASCII码字符,肯定不能使用ASCII来进行编码的,write方法是默认使用ascii来编码保存的。
很容易就可以想到,在保存之前,先对unicode字符进行编码,我选择utf-8
#coding=utf-8
import os
def write_use_open(filepath):
try:
file = open(filepath, 'wb')
try:
content = u'中华人民共和国abcd \r\nee ?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n'
print file.encoding
print file.newlines
print file.mode
print file.closed
print content
print unicode.encode(content, 'utf-8')
file.write(unicode.encode(content, 'utf-8'))
finally:
file.close()
print file.closed
except IOError, e:
print e
if __name__ == '__main__':
filepath = os.path.join(os.getcwd(), 'file.txt')
write_use_open(filepath)
看看运行结果:
OK了打开文档也是正确的。
读取文件又怎样?同样道理,只是这次不是编码了,而解码:
def read_use_open(filepath):
try:
file = open(filepath, 'rb')
try:
content = file.read()
content_decode = unicode(content, 'utf-8')
print 'original text'
print content
print 'decode using utf-8'
print content_decode
finally:
file.close()
except IOError, e:
print e
if __name__ == '__main__':
filepath = os.path.join(os.getcwd(), 'file.txt')
write_use_open(filepath)
print 'read file ---------------------------'
read_use_open(filepath)
为什么不直接在open的时候就解码呢?呵呵,可以啊,可以使用codecs的open方法
import codecs
def read_use_codecs_open(filepath):
try:
file = codecs.open(filepath, 'rb', 'utf-8')
try:
print 'using codecs.open'
content = file.read()
print content
finally:
file.close()
except IOError, e:
print e
好了,希望对你有用。
本文参考:Unicode HOWTO
posted @
2008-05-31 13:36 MK2 阅读(147) |
评论 (0) |
编辑
先来看个例子:
def foo(*args, **kwargs):
print 'args = ', args
print 'kwargs = ', kwargs
print '---------------------------------------'
if __name__ == '__main__':
foo(1,2,3,4)
foo(a=1,b=2,c=3)
foo(1,2,3,4, a=1,b=2,c=3)
foo('a', 1, None, a=1, b='2', c=3)
输出结果如下:
args = (1, 2, 3, 4)
kwargs = {}
---------------------------------------
args = ()
kwargs = {'a': 1, 'c': 3, 'b': 2}
---------------------------------------
args = (1, 2, 3, 4)
kwargs = {'a': 1, 'c': 3, 'b': 2}
---------------------------------------
args = ('a', 1, None)
kwargs = {'a': 1, 'c': 3, 'b': '2'}
---------------------------------------
可以看到,这两个是python中的可变参数。*args表示任何多个无名参数,它是一个tuple;**kwargs表示关键字参数,它是一个dict。并且同时使用*args和**kwargs时,必须*args参数列要在**kwargs前,像foo(a=1, b='2', c=3, a', 1, None, )这样调用的话,会提示语法错误“SyntaxError: non-keyword arg after keyword arg”。
呵呵,知道*args和**kwargs是什么了吧。还有一个很漂亮的用法,就是创建字典:
def kw_dict(**kwargs):
return kwargs
print kw_dict(a=1,b=2,c=3) == {'a':1, 'b':2, 'c':3}
其实python中就带有dict类,使用dict(a=1,b=2,c=3)即可创建一个字典了。
“人生苦短,我用python。”
posted @
2008-04-21 13:34 MK2 阅读(131) |
评论 (0) |
编辑
今天在测试读取RSS时,使用到自己在博客园的RSS链接来做测试,发现使用Last-Modified方式优化时,RSS每次返回都会更新Last-Modified。
以下是用Fiddler对几次请求的截获结果:
第一次请求,客户端不会添加头If-Modified-Since头,这是肯定的。
服务器端返回了Last-Modified,并且响应代码是200,这样客户端可以在下次请求中使用。
第二次请求,客户端根据上次请求返回的Last-Modified,添加If-Modified-Since头。
服务器返回结果并不是我们预料中的304,却依然是200,也就是说全部内容又重新下载了一遍,If-Modified-Since请求头并未起作用。原因是什么?看看服务器返回的Last-Modified就知道,RSS内容并未更新,长度还是67672,本应该Last-Modified与第一次的Last-Modified相等才对的。
再进行一次测试:
结果和上面一样,Last-Modified有变化了。
呵呵,Last-Modified得到支持,将会为我们双方都节省许多带宽的。与Last-Modified类似的,就是Etag头。想详细了解什么是Last-Modified和Etag,可参考:如何利用客户端缓存对网站进行优化?
posted @
2008-04-19 16:10 MK2 阅读(1536) |
评论 (7) |
编辑
究竟在一次Request中,Django对数据库执行了那些查询和操作呢?呵呵,Django早就为我们想好了这个问题,使用django.core.context_processors.debug模块即可。
在setting中设置:
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.debug", #debug 一次请求调用到多少SQL语句",
)
并设置能看到次debug信息的请求IP:
INTERNAL_IPS = ('127.0.0.1',)
我们就可以在模板中设置一下,即可:
{% endblock %}
{% if sql_queries %}
<h3>SQL excute in this Request</h3>
<!-- debug: show the sql excute in this request -->
{% for query in sql_queries %}<h3>Excute times: {{query.time}}</h3>
<p>
<code>
{{query.sql}}
</code>
</p>
{% endfor %}<!-- debug ends here -->
{% endif %}
以上只会在你设置了TEMPLATE_DEBUG = DEBUG,和请求IP在INTERNAL_IPS设置过,才会显示。
看看一个截图吧:
呵呵,看到了对Session的查询。
不错吧,这样我们可以对实际执行的SQL有底了。
posted @
2008-04-18 21:38 MK2 阅读(107) |
评论 (4) |
编辑
1. 创建app
manage.py startapp users
2. 编写profile model
from django.db import models
from django.contrib.auth.models import User
GENDER_CHOICES = (
('M', '男'),
('F', '女'),
)
class UserProfile(models.Model):
# 这个字段是必须的,并且只能为user,且要添加外键关联到User
user = models.ForeignKey(User, unique=True, verbose_name='用户的额外信息')
# 以下可以按各自需求来定义
tel = models.CharField('电话', maxlength=20, blank=True, null=True)
mobile = models.CharField('移动电话', maxlength=20, blank=True, null=True)
address = models.CharField('家庭地址', maxlength=100, blank=True, null=True)
website = models.URLField('个人主页', blank=True, null=True)
birthday = models.DateField('出生日期', blank=True, null=True)
gender = models.CharField('性别', maxlength=1, choices=GENDER_CHOICES, radio_admin=True, default='M')
blog = models.URLField('个人主页', blank=True, null=True)
QQ = models.CharField('QQ', maxlength=50, blank=True, null=True)
MSN = models.CharField(maxlength=50, blank=True, null=True)
IM = models.CharField(maxlength=50, blank=True, null=True)
position = models.CharField('目前所在地', maxlength=200, blank=True, null=True)
country = models.CharField('目前所在国家', maxlength=50, blank=True, null=True, default='中国')
3. 设置AUTH_PROFILE_MODULE
AUTH_PROFILE_MODULE = 'users.UserProfile' #不区分大小写的
4. 添加INSTALLED_APPS
INSTALLED_APPS = (
...............
'web.users',
)
5. 同步数据库
manage.py syncdb
只需使用User.get_profile()方法即可返回对应的UserPrfile对象实例了。
posted @
2008-04-10 17:18 MK2 阅读(81) |
评论 (0) |
编辑
首先,写Python代码的IDE有许多,呵呵,至于功能强大的肯定是Eclipse + pydev了,以下是pydev的显著的特性:
Some feature-highlights
接着,我选择使用Django框架做Web开发的话,怎么能少了对HTML, CSS, JavaScript的编辑器呢?呵呵,同样是Eclipse的插件:Aptana ,强大的智能提示,肯定帮助我们加快开发的速度和提高开发体验的(呵呵,我们也要良好的用户体验喔)。
最后不用说,就是SVN,Eclipse的SVN插件:subclipse,这样3样工具,足够了。
PS: 还有个可选的,就是UML建模工具:EclipseUML
posted @
2008-04-10 10:12 MK2 阅读(82) |
评论 (0) |
编辑
1. syncdb
最简单而又令人兴奋的命令: manage.py syncdb
创建了指定app中的model对应的数据库表,如果是第一次使用此命令,会提示是否创建超级用户,输入用户名,Email和密码,接着可以看到在创建索引:
2. validate
验证Model的正确性:manage.py validate,若Model全部有效,会提示:0 errors found.
3. sqlall [appname,....]
打印指定app的CREATE TABLE的语句,包括原始数据,创建索引等.
manage.py sqlall books
将会看到:
4. sqlreset [appname, ....]
修改了Model后,如果不需要保留原来的数据,就使用这个命令更新数据库对应的表,因为syncdb不会同步已有的表的。
manage.py sqlreset books
如果我们需要保留原来的数据,目前只能手动更改数据表了,可能将来会有类似updatedb的命令,帮助我们生成ALTER TABLE语句的。
Technorati 标签:
django,
python
posted @
2008-04-09 20:33 MK2 阅读(83) |
评论 (1) |
编辑
今天看到Lulu的闪存问到Cookie的问题,然后引发更多问题,突然想到昨晚使用Fiddler调试是否使用gzip压缩时,发现IE7下的localhost无法被捕获了。呵呵,然后就直接搜索了“Fiddler localhost”,找到了原因。
以下引用至:http://www.fiddlertool.com/Fiddler/help/knownissues.asp
I don't see IE7 or .NET traffic sent to localhost or 127.0.0.1.
IE7 and the .NET Framework are hardcoded not to send requests for Localhost through proxies. Fiddler runs as a proxy. The workaround is to use your machine name as the hostname instead of Localhost or 127.0.0.1.
So, for instance, rather than hitting http://localhost:8081/mytestpage.aspx, instead visit http://machinename:8081/mytestpage.aspx. Alternatively, you can use http://localhost.:8081/mytestpage.aspx (note the trailing dot after localhost). Alternatively, you can customize your Rules file like so:
static function OnBeforeRequest(oSession:Fiddler.Session){
if (oSession.host.ToUpper() == "MYAPP") { oSession.host = "127.0.0.1:8081"; }
}
...and then navigate to http://myapp, which will act as an alias for 127.0.0.1:8081.
我比较喜欢localhost. 方式。
如果你使用IIS7的话,还可以自己定制
<system.net>
<defaultProxy>
<proxy proxyaddress="http://127.0.0.1:8888" />
</defaultProxy>
</system.net>
这样,就会通过代理来访问了,从而Fiddler就能捕获到数据了。
最后还联想到以前DF介绍的一款Fiddler的插件,帮助我们查看被去空白的Javascript代码插件-- Fiddler2 - JavaScript Beautifier Plugin (Fiddler 2的JavaScript代码美化插件)。
呵呵,有时候想起某些事情是需要有导火线的。
posted @
2008-03-31 16:25 MK2 阅读(177) |
评论 (1) |
编辑
1. 验证用户输入;
2. 转化必要的字符,避免脚本攻击;
3. 防止用户估计禁止掉浏览器中的Javascript进行提交。
4. 防止用户恶意频繁输入。
5. 防止广告机器人。
6. asp.net Ajax访问页面静态方法或WebService时,要注意是否需要进行身份验证。
[WebMethod]
public static bool DeleteMessage(int id)
{
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
throw new System.Security.SecurityException("没有权限.");
}
//do something.
}
7. 禁止用户手动输入input[type="file"]的文件路径,最简单的方式是
<input type="file" ContentEditable="false" />
posted @
2008-03-28 17:40 MK2 阅读(83) |
评论 (0) |
编辑
摘要: 昨天对自己的Blog添加动态更换皮肤功能时,还有一个问题没解决,就是子域名共享Cookie。例如我访问Blog的子域名是:fengmk2.cnblogs.com, 而页面很多链接的是在www.cnblogs.com/fengmk2/下进行访问的,而皮肤的设置保存在cookie中,导致访问两域名时,皮肤显示不同。今天搜索了一下博客园,发现Dudu已经给出了完全的解决方法。解决方法:"将cookie关...
阅读全文
posted @
2007-12-29 20:04 MK2 阅读(135) |
评论 (0) |
编辑
摘要: 见08年快到了,呵呵,之前那个皮肤从一开始到博客园用到现在,想了很久,总算学决心给我的小博客园换上新衣了。
呵呵,一看就知道皮肤不是我做的,在http://www.freecsstemplates.org 看中这个黑白主题的模板,就试着改了。
感谢Dudu,已经换上新装了。
凌晨添加了“皮肤切换功能:在导航栏上有<原版皮肤>和<当前皮肤>切换”
阅读全文
posted @
2007-12-28 21:15 MK2 阅读(99) |
评论 (0) |
编辑
摘要: 哈哈,今晚在班群,奶仔的突然间说了一句“要修改路由表”后,引发了班里人的关注,哈哈,我也学到了一些鸡毛。
需求大概是这样:目前电脑中有两张网卡,而宿舍又有AD和校园网,为了同时使用AD和校园网访问,但访问的站点是校园网时,使用连接着校园网那张网卡进行访问,其它网站就使用AD那张网卡访问。
思路是,将已知的校园网段的IP手动添加到路由表,并指定网关为连接校园网的那个网关(这里假设为192.168.2.1),其它IP段使用默认网关(即AD,这里假设为192.168.3.1)访问。
阅读全文
posted @
2007-12-18 21:53 MK2 阅读(391) |
评论 (0) |
编辑
2007-9-24
遗憾啊....刚刚翻译好的, 却发现已经有人翻译了.
不过还我是将自己的更新一下....
下载简体中文包:
labels.zh-CN.rar(2007-9-24 Verson: 1.2)
翻译参考:
blog程序的考量标准
Avatars
posted @
2007-09-19 20:32 MK2 阅读(302) |
评论 (0) |
编辑
摘要: 基于目前我们学校教务处的管理系统, 依靠Javascript的帮忙, 我们可以很方便地计算成绩.
阅读全文
posted @
2007-09-05 22:33 MK2 阅读(328) |
评论 (2) |
编辑
摘要: 做IE平台下的Web页面设计开发, 通常都会遇到许多CSS和XHTML上的问题, 如果有一些辅助软件帮手, 肯定会事半功倍的.
1. Multiple IEs
想在一个系统中拥有IE3.0 到IE7.0所有版本的IE吗? 很简单, 首先系统默认安装的是IE7.0, 然后运行Multiple IE installer即可.
阅读全文
posted @
2007-08-30 14:17 MK2 阅读(860) |
评论 (2) |
编辑
摘要: 在一个特殊应用中, 我们需要将内存中的一个对象持久化, 而这个对象是来自一个模板类实例化出来的, 不能保存到数据库中, 数据库中只存有此对象的模板.
由于使用到泛型的Dictionary, 而XmlSerializer却不支持默认的泛型的Dictionary, 为此我找了些资料, 并在此文中以三种不同的方式实现. 本文中约定:
方案1: 不序列化泛型的Dictionary
方案2: 定义支持泛型的Dictionary
方案3: 让每个类实现IXmlSerializable接口
本文内容:
1. 类图及类之间的关联
2. 方案1: 不序列化泛型的Dictionary
3. 方案2: 定义支持泛型的Dictionary
4. 方案3: 让每个类实现IXmlSerializable接口
5. 总结
阅读全文
posted @
2007-08-17 01:14 MK2 阅读(1132) |
评论 (4) |
编辑
摘要: 最近在确定项目架构模型时, 出现了一些问题, 参考了许多文章和设计, 以下记录着这些文章和设计, 以便以后总结:
阅读全文
posted @
2007-08-14 21:37 MK2 阅读(322) |
评论 (1) |
编辑
摘要: 在一款很有趣的开源VS2005插件:CopySourceAsHtml 看到CopySourceAsHtml , 安装发现中文的VS2005会出现问题, 还有, 它是开源的, 在修正 CopySourceAsHTML 插件无法用于中文 VS2005 的Bug 中可以找的解决方法,.
我自己也修改了一些, 加上了相邻行背景色可设置,
并做一些自己觉得需要的修改, 我修改后的DLL可在此下载: CopySourceAsHtml.dll.
添加样式表: 其中.cf的样式来自Dflying Chen 老大的博客.
阅读全文
posted @
2007-08-13 13:20 MK2 阅读(216) |
评论 (2) |
编辑
摘要: 注意,我使用了ScriptManager.RegisterClientScriptBlock,若你没有使用Asp.net Ajax,请改为ClientScript.RegisterClientScriptBlock() ,因为ClientScript.RegisterClientScriptBlock()在使用了ScriptManager时会失效的。
阅读全文
posted @
2007-08-12 22:04 MK2 阅读(212) |
评论 (1) |
编辑
摘要: 使用NBearMapping做测试,才发现SQL中的float不能被自动Map到实体类型为float字段中。
搜索了一下,才发现SQL中的float对应到C#的double,我晕了。
http://www.cnblogs.com/xkforever/archive/2007/04/27/729858.html
阅读全文
posted @
2007-08-12 04:22 MK2 阅读(276) |
评论 (0) |
编辑
摘要: 只需要在Web.config进行几个简单设置, 即可通过health monitoring将没有处理的错误信息发送到指定Email.
请关注:
和
两个节点的设置.
阅读全文
posted @
2007-08-10 16:00 MK2 阅读(159) |
评论 (0) |
编辑
posted @
2007-08-10 05:05 MK2 阅读(310) |
评论 (0) |
编辑
你只需要一个非常小的类和在global.asax中添加14行代码. 这就是使你的Asp.net应用程序具有可扩展性的全部要求. 扩展仅仅是标记了Extension属性的类, 没有任何法术.
详细请继续看:
Make your ASP.NET application extendable
posted @
2007-08-09 03:00 MK2 阅读(188) |
评论 (0) |
编辑
什么是
MansterID呢?
MonsterID is a method to generate a unique monster image based upon a certain identifier (IP address, email address, whatever). It can be used to automatically provide personal avatar images in blog comments or other community services.
详细介绍请查看: MansterID, http://www.levitated.net/bones/walkingFaces/index.html, Visual Security: 9-block IP Identification
至于MansterID在Asp.net中的实现? 已经有了,
马上下载: http://blog.furred.net/blog/file.axd?file=MonsterID/MonsterID.zip
或者在线测试: Demo page
哈哈, MK2 Manster来了!!!!

posted @
2007-08-09 02:13 MK2 阅读(124) |
评论 (0) |
编辑
今天看了
umbraco 的源代码, 发现了这个非常漂亮的Singleton模板
惟一的不足是, 构造函数是public, 只能靠开发人员自己控制了.
/// <summary>
///
/// Threadsafe Singleton best practice design pattern template
///
/// Sample:
///
/// public class Demo
/// {
/// public static Form1 instance1
/// {
/// get
/// {
/// return Singleton<Form1>.Instance;
/// }
/// }
/// }
/// </summary>
/// <typeparam name="T">Any class that implements default constructor</typeparam>
public sealed class Singleton<T> where T : new()
{
private Singleton()
{
}
public static T Instance
{
get { return Nested.instance; }
}
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly T instance = new T();
}
}
posted @
2007-08-07 16:41 MK2 阅读(170) |
评论 (0) |
编辑
1.
http://www.oswd.org RSS
Open Source Web Design is a site to
download free web design templates and share yours with others. We help make the internet a prettier place.
2.
http://www.opensourcetemplates.org
Open Source Templates
posted @
2007-08-03 09:16 MK2 阅读(517) |
评论 (0) |
编辑