Pythonic - 装饰器正解

  Python装饰器是Python高级特性中相当重要的一部分,但由于涉及函数式编程、闭包等概念,所以相对难以理解。包括廖雪峰的教程在内,很多教程讲述的都十分晦涩,甚至有很多帖子只是贴出大量没有意义的代码,完完全全是电子垃圾。关于编程,__我们的目的是理解它的原理而写出代码,而不是通过看代码来推敲它的原理__,可偏就有很多人喜欢反其道而行。

继续阅读 >>


The 8 bit guy - 一个有趣的频道

# 8 bit guy   没错,这个频道讲述的是8位计算机兴起的那个80年代的故事。主播有个观点,就是那个年代不管是对个人计算机还是整个IT科技行业,都是一个黄金时代。虽然在现在看来8位的计算机性能相当差劲、几乎没办法做任何事情,但那是计算机科技真正蓬勃发展时代,不管硬件工业设计还是软件界的百花齐放的繁荣景象,只要经历过的人都印象深刻。举个例子,家喻户晓的《超级玛丽》就诞生于那个年代。刷一刷淘宝,你一定深有同感:那个时代就像被大屏智能手机洗牌之前的手机市场,摩托的刀锋系列、诺基亚的Ngage、7610、5700、N97等等就诞生在那个时代,同样出色的设计层出不穷;而现在给你一台撕掉LOGO的手机,你甚至一眼不能分辨不出来它是什么牌子。

继续阅读 >>


Pythonic

### 代码规范   谈及Python编程,《PEP 8》总是说不过去的,它是比较官方的代码风格的规范和建议。除此之外,还有《Google编程风格指导》之类的文档等,都是非常不错的文档。代码规范的重要性不言而喻,但这也是人们学习编程时最常忽略的章节。   在我读过的入门Python书籍里,中这部分的内容都比较少。但在进阶的书籍中,有的不惜用上两个章节专门讲述,如何写出遵循PEP 8规范的Python代码,并介绍各种工具来审查代码、管理项目结构和文档。当然,事情也没这么复杂,很多时候只要配置一个顺手的IDE就够了。这里我非常推荐PyCharm,它是一款非常优秀的IDE,而且提供免费的社区版。

继续阅读 >>


Web Server Gateway Interface (wsgiref.handlers部分)

django ### wsgiref.handlers   这个模块是WSGI服务器和网关的实现。只要给予一个类CGI的环境,以及输入、输出和错误流,就可以用WSGI应用程序处理绝大部分的网络连接。 * __class__ wsgiref.handlers.__CGIHandler__ 使用sys.stdin、sys.stdout和sys.stderr流的基于CGI的调用。可以用在你想以一个CGI脚本来运行你写的WSGI应用程序时。它会直接调用```CGIHandler().run(app)```,这里的app就是你想调用的对象。 这个class是把wsgi.run_once设置为True、把wsgi.multithread设置为False,而且总是使用sys和os来获取必要的CGI流和环境变量的BaseCGIHandler的派生类。 * __class__ wsgiref.handlers.__BaseCGIHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)__ 与CGIHandler类似,但不使用sys和os,而是显式的指定CGI环境和IO流。*multithread*和*multiprocess*的值是用来给任何通过此实例来运行的应用程序设置*wsgi.multithread*和*wsgi.multiprocess*标志位的。 这个类是一个随非HTTP "origin servers"软件而使用的SimpleHandler的派生类。如果你想写一个网关接口的实现,比如CGI、FastCGI、SCGI等,使用```Status: ```头来发送一个HTTP的状态码,那您肯定很想用这个实例而不是SimpleHandler的实例。 * __class__ wsgiref.handlers.__SimpleHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)__ 和上述BaseCGIHandler类似,但为了HTTP origin servers来设计的。如果你正在写一个HTTP服务器的实现,那使用这个类的实例就比BaseCGIHandler要好得多。 这个类基于BaseHandler,但覆写了__init__()、get_stdin()、get_stderr()、add_cgi_vars()、_write()和_flush()方法来支持通过这个构造器来显式设置环境和流。支持的环境和流被存储在stdin、stdout、stderr和environ属性里。 * __class__ wsgiref.handlers.__BaseHandler__ 这是一个用来运行WSGI应用程序的抽象类,虽然原则上你可以派生出一个类来复用,使得他能接收多个请求,但每个实例都应该只处理一个HTTP请求。 __BaseHandler__只有一个用于外部调用的方法: - run(*app*) 运行指定的WSGI应用程序,如*app*。 所有其他的方法都只被这个方法调用,用来辅助这个app的运行。这样从根本上可以定制处理过程。 - _write(*data*) 给字符串*data*做缓冲用来传送到client。如果这个方法发送了data,是OK的,BaseHandler只是区分了写和刷新的操作用于给特定的系统提升效率。 - _flush() 强制把缓冲区中的数据发送到client。 - get_stdin()/get_stderr() 返回WSGI请求正在处理之时对应的流。 - get_stdvars() 插入当前的请求中的CGI变量到environ的属性中。 另外,有一些方法和属性你肯定想重写它。这里仅列举出一部分,而且在打算基于BaseHandler来定制自己的类之前, 应该翻阅更官方的文档和源码来获得更确切的信息。 用来定制WSGI环境的属性和方法如下: - wsgi_multithread 用于wsgi.multithread的环境变量。在BaseHandler中默认为真,但亦可能为不同的默认值,因为有可能被别的派生类的构造器设置成了别的值。 - wsgi_multiprocess 用于wsgi.multiprocess环境变量。在BaseHandler中默认为真,但亦可能为不同的默认值,因为有可能被别的派生类的构造器设置成了别的值。 - wsgi_run_once 用于wsgi.run_once环境变量.在BaseHandler中默认为False,但CGIHandler中默认为True。 - os_environ 是每一个请求的WSGI环境中的默认环境变量。默认情况下它是当wsgiref.handlers被import的时候os.environ的拷贝,但派生类也可以在class或者实例层单独创建它们。需要注意的是,这个dict应该被设计成只读的,因为这个默认值是被多个类和实例共享的。 - server_software 如果设置origin_server属性,它的值将用于设置默认的SERVER_SOFTWARE WSGI环境变量,也会在HTTP响应中设置默认的```Server:```头. 他被非 HTTP origin servers忽略,比如BaseCGIHandler和CGIHandler。 - get_scheme() 用来返回当前请求的URL方案。默认的实现是使用guess_scheme()方法从wsgiref.util中判定当前的方案是“http”还是“https”,它是基于当前请求的environ变量的。 - setup_environ() 设置*environ*属性为fully-populated的WSGI环境。默认的实现是使用上述所有的方法加上get_stdin()、get_stderr()、和add_cgi_vars()方法,以及wsgi_file_wrapper属性。如果不存在SERVER_SOFTWARE的key,并且origin_server属性设置为真而且server_software是有值的,它也会插入这个key。 用来定制处理过程的方法和属性如下: - log_exception(*exc_info*) 给*exc_info*元组加上log。*exc_info*是(type, value, traceback) 元组,默认的实现是单纯的写入到wsgi.errors流中,然后flush。派生类可以重写这个方法来改变格式或者重定向输出、发送信息给管理员等等。 - traceback_limit 定义log_exception()中包含tracebacks输出信息的最大的帧的大小。如果为None,就会包含所有的帧。 - error_output(*environ, start_response*) 这个方法时一个WSGI应用程序来给用户产生一个error页面。它仅在发送Header之前发生错误时调用。 这个方法可以使用sys.exc_info()来进入当前错误信息。并且在被调用时,应当pass这条信息到start_response,在PEP 333中的“Error Handling”章节定义。 默认的实现就是使用```error_status```、```error_headers```和```error_body```属性来产生输出的页面。派生类可以重写它来产生更多动态的信息。 需要注意的是,从安全的角度来输出诊断信息是不推荐的,要做一些额外的工作来启用诊断输出。这就是为什么默认的实现没有包含任何东西的原因。 - error_status 用来做HTTP错误回复的状态码。这里应该是PEP 333中定义的一个字符串。默认是一个500的错误码和信息。 - error_headers 用于错误回复的HTTP headers。它应当是PEP 333中定义的WSGI响应头元组的list,比如[(name, value)]。默认的就是设置“content type”为“text/plain”。 - error_body 错误回复的body。应该是HTTP响应的body字符串,默认的是纯文本“A server error occurred. Please contact the administrator.”。 PEP 333中定义的“Optional Platform-Specific File Handling”特性相关的方法和属性: - wsgi_file_wrapper 为wsgi.file_wrapper的factory,或者为None。默认的值是wsgiref.util中的__FileWrapper__的属性。 - sendfile() 重写以实现平台特异的文件传输。这个方法只会在应用程序返回的值为wsgi_file_wrapper属性指定的类的实例时被调用。如果成功传送了一个文件它应该返回一个Ture,这样默认的传送代码就不会执行。默认的实现就是返回一个False。 其他的方法和属性: - origin_server 当handler的_write()和_flush()被用来与客户端直接连接,而不是通过类CGI的希望在特殊的```Status:```头中到HTTP状态码网关接口时,这个属性应该被设置为True。 在BaseHandler中,这个属性的默认值为True,在BaseCGIHandler和CGIHandler中为假。 - http_version 如果origin_server为真,这个字符串属性被用来给client设置HTTP版本。默认的是”1.0“。 ### 示例用法:   一个“Hello World”的WSGI应用程序: ``` from wsgiref.simple_server import make_server # Every WSGI application must have an application object - a callable # object that accepts two arguments. For that purpose, we're going to # use a function (note that you're not limited to a function, you can # use a class for example). The first argument passed to the function # is a dictionary containing CGI-style environment variables and the # second variable is the callable object (see PEP 333). def hello_world_app(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain')] # HTTP Headers start_response(status, headers) # The returned object is going to be printed return ["Hello World"] httpd = make_server('', 8000, hello_world_app) print "Serving on port 8000..." # Serve until process is killed httpd.serve_forever() ```

继续阅读 >>


Web Server Gateway Interface (simple_server和validate部分)

django ### wsgiref.simple_server   这个模块实现了一个基于__BaseHTTPServer__的轻量级WSGI应用程序的服务器。每个server实例只能在设定的主机和端口上调用一个单一的WSGI应用程序,如果要想调用多个WSGI应用程序,必须手动解析PATH_INFO来给每个request做路由,然后决定调用哪个应用程序。 * wsgiref.simple_server.__make_server(*host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler*)__ 创建一个WSGI server 来监听主机的端口,给*app*接收请求。返回的是*server_class *的实例,并且用指定的*handler_class *来处理request。app必须为PEP 333中定义的WSGI 应用程序对象。 示例用法: from wsgiref.simple_server import make_server, demo_app httpd = make_server('', 8000, demo_app) print "Serving HTTP on port 8000..." # Respond to requests until process is killed httpd.serve_forever() # Alternative: serve one request, then exit httpd.handle_request() * wsgiref.simple_server.__demo_app(*environ, start_response*)__ 一个小但完整的WSGI应用程序,返回一个text的页面包含“Hello world!”和一个在*environ *中提供的键值对构成的list,这个主要用来测试WSGI 服务器能否正确的运行一个WSGI应用程序。 * __class__ wsgiref.simple_server.__WSGIServer(*server_address, RequestHandlerClass*)__ 创建一个WSGIServer的实例,*server_address*必须为(host, port)的元组,并且*RequestHandlerClass*也必须为__BaseHTTPServer.BaseHTTPRequestHandler__的派生类,否则不能正确的处理请求。 通常这个方法不需要被调用,因为*make_server()*方法可以处理所有的细节。 __WSGIServer__是以__BaseHTTPServer.HTTPServer__为基类的,所以所有BaseHTTPServer.HTTPServer支持的方法都是可用的,比如*server_forever()*、*handle_request()*。__WSGIServer__也提供了专有的方法,比如: * __get_environ()__ 返回WSGI环境变量的dict。默认的实现是,拷贝WSGIServer对象的base_environ dict的内容,然后加上HTTP请求Header导出来的变量再返回。每次请求都会返回PEP 333中定义的包含全部CGI相关的环境变量的全新的dict。 * __get_stderr()__ 返回必须用wsgi.errors流的对象。默认的实现其实就是返回__sys.stderr__。 * __handle()__ 处理HTTP请求。默认的实现是创建一个句柄实例使用__wsgiref.handlers__类来实际的WSGI API。 ### wsgiref.validate   这个模块主要用来检查代码与规范的的一致性。它创建一个在服务器或者网关和应用程序之间检查一致性的function,用以确保两边都相符。   需要注意的是,这个模块并不能保证全部的的PEP 333的规范,它没有报错并不意味错误不存在。但一旦它抛出错误,则服务器或者应用程序端必有错误。   这个模块基于Ian Bicking的 “Python Paste” 库中的__parse.lint__扩展的。 * wsgiref.validate.__validator(*application*)__ 装饰一个*application*并且返回一个新的application,返回的application会跟随原application所有的request,并且检查两边的处理是否都符合WSGI和 RFC 2616 中的定义。 任何检测到的不服从一致性的错误都将以AssertionError抛出来,但需要注意的是,怎么抛出错误和处理是取决于服务器的。比如__simple_server__和其他基于__handlers__的服务器在错误发生时,会输出一个简单的消息,但如果其他的覆盖了错误处理和做了类似处理的服务器就可能不会抛出。 这个装饰器也会用__warnings__模块生成警告,来标识没有明确在PEP 333中禁止但存在问题的行为。除非这些警告被命令行或者__warnings__ API禁止,否则都会被写入到__sys.stderr__。 示例用法: from wsgiref.validate import validator from wsgiref.simple_server import make_server # Our callable object which is intentionally not compliant to the # standard, so the validator is going to break def simple_app(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain')] # HTTP Headers start_response(status, headers) # This is going to break because we need to return a list, and # the validator is going to inform us return "Hello World" # This is the application wrapped in a validator validator_app = validator(simple_app) httpd = make_server('', 8000, validator_app) print "Listening on port 8000...." httpd.serve_forever()  

继续阅读 >>