对于我这个从.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 标签: , ,
posted @ 2008-08-01 01:15 MK2 阅读(35) | 评论 (0)编辑

最近都在研究如何利用最少的字节判断两个PE文件是否相同。

PE文件几个关键:

1. 在一个PE文件的开始处,我们会看到一个MS-DOS可执行体(英语叫“stub”,意为“根,存根”);它使任何PE文件都是一个有效的MS-DOS可执行文件。如图蓝色框部分。0x5A4D:MZ,每个PE文件都是以此开始。

image

 

2. 在DOS-根之后是一个32位的签名以及魔数0x00004550 (IMAGE_NT_SIGNATURE)(意为“NT签名”,也就是PE签名;十六进制数45和50分别代表ASCII码字母E和P)。

image

3.

image

 

4. DOS-根和签名(DOS-stub and Signature)

image

你可以通过确认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. 文件头

image 

开始于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的文件头

image

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: , ,
posted @ 2008-06-10 19:23 MK2 阅读(50) | 评论 (0)编辑

因经常在多台机器上使用Firefox,难免会想装一些已经习惯了的插件(晕,都依赖他们),没安装上总是用起来不顺手。于是就有了这篇文章。

1. 第一个要备忘的肯定是它:Google Browser Sync

image

可以同步些什么?看看这个截图吧:

image

很Cool吧,仿佛在那台机打开FF,都感觉是一样的,完全获取回上次的所有状态,并且支持加密传输,这样个人私隐就不会泄露了。

2. GMarks

虽然说Google Browser Sync可以同步Bookmarks,但是我还是喜欢将Bookmarks保存到互联网上,GMarks就是一个Google Bookmarks的插件,使用也非常简单,Bookmarks太多了吧,不記得放在那个位置了吧,呵呵,不怕,在自己的Bookmarks上搜索一下不就行了?

image

3. All-in-One Gestures Extension

有使用鼠标手势控制的习惯吧?怕使用了Firefox而无法拥有这个功能吗?呵呵,哪All-in-One Gestures Extension肯定是你的最爱,完全支持你想要的手势。

image

image

4. DictCN (呵呵,忘记推荐沪江小D,绝对比这个精彩多了!!!)

呵呵,像我这些英语很差但是又要经常看英文的人,这个插件肯定比钱包更加重要,放在你的FF上吧,肯定会用上的,特别是它还支持发音功能。

image image

5. AutoHide

觉得FF上方的工具栏太占位置了吗?导致看到的页面太小了吧?呵呵,这个插件绝对帮你将工具栏完全隐藏了,按Shift+F11让FF全屏吧。

image

6. Firebug 不顶不行

呵呵,这个不用我介绍了吧,太出名了!!!

image

估计每个做Web开发的人的FF上都会有它。o(∩_∩)o...

7. Showcase

经常打开几十个tab而又不想关掉它们吗?是不是要找一个tab花了很多时间?使用Showcase可以让你马上找到你想找的tab,不信?看看截图吧:

image

想用了吧?

8. IE Tab

不用IE不行啊,有时候真的没有了IE,很多事情就没法做了,于是有打开IE。很麻烦吧,如果你的系统是Windows,那么IE Tab可以很方便地设置当前页面使用IE内核访问,还可以设置更多的规则,唉,我们的世界没了IE真不容易:

image

9. Fireshot

一个页面太长了吧,是否有想将整个页面截图处理的需求呢?Fireshot可以实现,并且还有上传,直接将截图的链接发给你的朋友吧,呵呵,这样介绍网站,也是一个不错的选择。

image

image

10. Tab Scope

想预览一下tab里面是什么内容吗?看看它是不是已经加载完了?这个插件可以提高你的兴趣。

image

11. QuickDrag

可以直接拖拉页面上的链接,并在新tab中打开,不用点鼠标中键了,Cool啊!!

12. ColorZilla

可以获取页面上任意部位的颜色。

image

??. FEBE

好了,装了这么多插件,有备份这些插件的插件吗?呵呵,你都想备份了吧?用FEBE吧,你想怎样备份都可以。

image

image

这里可以查看更多截图:http://customsoftwareconsult.com/extensions/febe/febe50/FEBE5.0.html

 

呵呵,今天到此为止吧,以后用到更多好的插件我会继续补充的,:-)

 

希望对你有用!!

 

Technorati 标签: ,,,
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();
    });
 
^_^ 希望对你有用...

Technorati: , , ,

 
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

Technorati: ,

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类吧。

 

Technorati: , , ,

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来回味。

image

然后我在想,输入法能做到这样吗?为了看看英文提示的效果,我下载了google拼音输入法。

输入我们最喜欢的hello world.

image image

果然是有提示。然后我输入一个python的open方法image ,在此刻,我想到的是如果image 的正下方有open的api文档说明和使用示例该多好啊。就像VS2008的智能感知的截图一样。

让智能感知脱离IDE而存在,让我们这些程序员能在文本文档下编程也有智能感知的功能,只需要我们的输入法支持就可以了。

于是编程输入法的设想就这样出现,至于谁先去实现?我想谁都可以。

再看看Eclipse的智能感知:

image

同样的效果,不过条件都是需要装IDE。

相信不久的将来,我们肯定会用上这个输入法的。

 

 

Technorati 标签: ,,,
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.
image 
image
可是我用命令行运行,却发现显示出现乱码了,然后在打开文件发现文件被正确保存了,编码还是utf-8:
image 
我想问题是命令行不能自动识别字符编码吧,因为IDLE显示是正确的,它支持utf-8。
 
于是我修改了代码,在字符串前加了'u',表明content是unicode:

content = u'中华人民共和国abcd \r\nee ?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n'

可是运行发现,命令行是正确显示了,但是却出现异常:

image

很明显,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)
 
看看运行结果:
image 
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)

image

为什么不直接在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
image 
 
好了,希望对你有用。
 
本文参考:Unicode HOWTO
Technorati 标签: ,,,,,
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。”

Technorati 标签: ,,,,
posted @ 2008-04-21 13:34 MK2 阅读(131) | 评论 (0)编辑

今天在测试读取RSS时,使用到自己在博客园的RSS链接来做测试,发现使用Last-Modified方式优化时,RSS每次返回都会更新Last-Modified。

以下是用Fiddler对几次请求的截获结果:

第一次请求,客户端不会添加头If-Modified-Since头,这是肯定的。

image

服务器端返回了Last-Modified,并且响应代码是200,这样客户端可以在下次请求中使用。

 

第二次请求,客户端根据上次请求返回的Last-Modified,添加If-Modified-Since头。

image

服务器返回结果并不是我们预料中的304,却依然是200,也就是说全部内容又重新下载了一遍,If-Modified-Since请求头并未起作用。原因是什么?看看服务器返回的Last-Modified就知道,RSS内容并未更新,长度还是67672,本应该Last-Modified与第一次的Last-Modified相等才对的。

 

再进行一次测试:

image

结果和上面一样,Last-Modified有变化了。

 

呵呵,Last-Modified得到支持,将会为我们双方都节省许多带宽的。与Last-Modified类似的,就是Etag头。想详细了解什么是Last-Modified和Etag,可参考:如何利用客户端缓存对网站进行优化?

Technorati 标签: ,,,,
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设置过,才会显示。
看看一个截图吧:
image 
呵呵,看到了对Session的查询。
不错吧,这样我们可以对实际执行的SQL有底了。
Technorati 标签: ,,,,,
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

image

创建了指定app中的model对应的数据库表,如果是第一次使用此命令,会提示是否创建超级用户,输入用户名,Email和密码,接着可以看到在创建索引:

image 

2. validate

验证Model的正确性:manage.py validate,若Model全部有效,会提示:0 errors found.

3. sqlall [appname,....]

打印指定app的CREATE TABLE的语句,包括原始数据,创建索引等.

manage.py sqlall books

将会看到:

image

4. sqlreset [appname, ....]

修改了Model后,如果不需要保留原来的数据,就使用这个命令更新数据库对应的表,因为syncdb不会同步已有的表的。

manage.py sqlreset books

image

如果我们需要保留原来的数据,目前只能手动更改数据表了,可能将来会有类似updatedb的命令,帮助我们生成ALTER TABLE语句的。

Technorati 标签: ,
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代码美化插件)

 

呵呵,有时候想起某些事情是需要有导火线的。

 

Technorati 标签: ,,,
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)编辑
今晚看到了A CAPTCHA Server Control for ASP.NET , 一个非常棒的CAPTCHA控件, 因为它原来是VB写的, 我照着用C#抄了一遍....

原版下载地址:
  • Download new version - ASP.NET 2.0 source files - 27.2 Kb
  • Download old version - ASP.NET 1.1 source files - 21.9 Kb

    看不懂VB的也可下我抄的:
  • CaptchaControl CSharp.rar

    太快了!


    太慢了!


    竟然这样都输入错!?


  • PS: Asp.net 并不需要CHPTCHA.....可看看Mads Kristensen Secure your forms in ASP.NET.
    555555555555555.....白干活一个晚上了....

    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中的实现? 已经有了, MonsterID HttpHandler - Done

    马上下载: 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

     the best free css and xhtml open source template design showcase where the community gets to pick the best designs to be showcased on the front page.

    http://www.osdnetwork.org/中还有一个CSS NATURE SHOWCASE,介绍一些好的Css设计。
    posted @ 2007-08-03 09:16 MK2 阅读(517) | 评论 (0)编辑

    因为TinyMCE的FileManager是收费的, 所以自己就专门为BlogEngine.net写了一个FileManger插件.

     

    详细可查看: http://mk2.net4.com.cn/page/TinyMCE's-plugins-Ajax-File-Manager-Net-for-BlogEngineNet.aspx

    效果图

    posted @