python中if __name__ == "__main__":用法解析

想必很多初次接触python的同学都会见到这样一个语句,if __name__ == "__main__":

那么这个语句到底是做什么用的呢?在解释之前,首先要声明的是,不管你是多么小白,你一定要知道的是:

1.python文件的后缀为.py;

2..py文件既可以用来直接执行,就像一个小程序一样,也可以用来作为模块被导入(比如360安全卫士,就是依靠一个个功能模块来实现的,好比360安全卫士本身框架是一个桌面,而上面的图标就是快捷方式,这些快捷方式所指向的就是这一个个功能模块)

3.在python中导入模块一般使用的是import

好了,在确定知道以上几点之后,就可以开始解释if __name__ == "__main__":这个语句了。

首先解释一下if,顾名思义,if就是如果的意思,在句子开始处加上if,就说明,这个句子是一个条件语句。学习if语句的使用是很简单的,当然想要真正灵活运用还需大量的实践。

接着是 __name__,__name__作为模块的内置属性,简单点说呢,就是.py文件的调用方式。

最后是__main__,刚才我也提过,.py文件有两种使用方式:作为模块被调用和直接使用。如果它等于"__main__"就表示是直接执行。

总结:在if __name__ == "__main__":之后的语句作为模块被调用的时候,语句之后的代码不执行;直接使用的时候,语句之后的代码执行。通常,此语句用于模块测试中使用。

本文出自 “老爸的蒸面条” 博客,请务必保留此出处http://keliang.blog.51cto.com/3359430/649318

Node.js简单介绍并实现一个简单的Web MVC框架

Node.js是什么

learnNode.zip)

clip_image002clip_image004 Node.js的特性

1. 单线程

3. Google V8

http://www.slideshare.net/lijing00333/node-js

var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(8124, "127.0.0.1"); console.log('Server running at 怎么运行?

当然,是先安装node.js啦。到http://howtonode.org/how-to-install-nodejs 装好node后,就可以运行我们的hello world了:

http://127.0.0.1:8124/

//output_me.js var fs = require('fs'), fileContent = 'nothing'; fs.readFile(

这个脚本读取当前文件的内容并输出。filename是node的一个全局变量,值为当前文件的绝对路径。我们执行这个脚本看一下:

有没发现结果不对呢?打印的fileContent并不是读取到的文件内容,而是初始化的时候赋值的nothing,并且‘end readfile’最后才打印出来。前面我们提到node的一个特性就是非阻塞IO,而readFile就是异步非阻塞读取文件内容的,所以后面的代码并不会等到文件内容读取完了再执行。请谨记node的异步非阻塞IO特性。所以我们需要将上面的代码修改为如下就能正常工作了:

filename, "utf-8", function(err, file) {

    if(err) {

        console.log(err);

        return;

    }

    fileContent = file;

    //对于file的处理放到回调函数这里处理

    console.log('doSomethingWithFile: '+ fileContent +'\n');

});

console.log('我们先去喝杯茶\n');

下面我们用node来写一个小玩具:一个Web MVC框架。这个小玩具我称它为n2Mvc,它的代码结构看起来大概如下:

和hello world一样,我们需要一个http的服务器来处理所有进来的请求:

var http = require('http'),

querystring = require("querystring");

exports.runServer = function(port){

    port = port || 8080;

    var server = http.createServer(function(req, res){

        var _postData = '';

        //on用于添加一个监听函数到一个特定的事件

        req.on('data', function(chunk)

        {

            _postData += chunk;

        })

        .on('end', function()

        {

            req.post = querystring.parse(_postData);

            handlerRequest(req, res);

        });

    }).listen(port);

    console.log('Server running at 

   

   这里定义了一个runServer的方法来启动我们的n2Mvc的服务器。有没注意到runServer前面有个exports?这个exports相当于C#中的publish,在用require导入这个模块的时候,runServer可以被访问到。我们写一个脚本来演示下node的模块导入系统:

   

   
//moduleExample.js

var myPrivate = '艳照,藏着';

exports.myPublish = '冠西的相机';

this.myPublish2 = 'this也可以哦';

console.log('moduleExample.js loaded \n');

clip_image002[9]clip_image004[7]

1、/home/qleelulu/.node_modules/http

2、/home/qleelulu/.node_modules/http.js

3、/home/qleelulu/.node_modules/http.node

4、/home/qleelulu/.node_modules/http/index.js

5、/home/qleelulu/.node_modules/http/index.node

6、/home/qleelulu/.node_libraries/http

7、/home/qleelulu/.node_libraries/http.js

8、参考前面

再看回前面的代码,http.createServer中的回调函数中的request注册了两个事件,前面提到过node的一个特点是事件驱动的,所以这种事件绑定你会到处看到(想想jQuery的事件绑定?例如$('a').click(fn))。关于node的事件我们在后面再细说。request对象的data事件会在接收客户端post上来的数据时候触发,而end事件则会在最后触发。所以我们在data事件里面处理接收到的数据(例如post过来的form表单数据),在end事件里面通过handlerRequest 函数来统一处理所有的请求并分发给相应的controller action处理。 handlerRequest的代码如下:

var parseURL = require('url').parse;

//根据http请求的method来分别保存route规则

var routes = {get:[], post:[], head:[], put:[], delete:[]};

/*

 注册route规则

 示例:

 route.map({

     method:'post',

     url: /\/blog\/post\/(\d+)\/?$/i,

     controller: 'blog',

     action: 'showBlogPost'

 })

/

exports.map = function(dict){

    if(dict && dict.url && dict.controller){

        var method = dict.method ? dict.method.toLowerCase() : 'get';

        routes[method].push({

            u: dict.url, //url匹配正则

            c: dict.controller,

            a: dict.action || 'index'

        });

    }

};

exports.getActionInfo = function(url, method){

    var r = {controller:null, action:null, args:null},

        method = method ? method.toLowerCase() : 'get',

        // url: /blog/index?page=1 ,则pathname为: /blog/index

        pathname = parseURL(url).pathname;

    var m_routes = routes[method];

    for(var i in m_routes){

        //正则匹配

        r.args = m_routes[i].u.exec(pathname);

        if(r.args){

            r.controller = m_routes[i].c;

            r.action = m_routes[i].a;

            r.args.shift(); //第一个值为匹配到的整个url,去掉

            break;

        }

    }

    //如果匹配到route,r大概是 {controller:'blog', action:'index', args:['1']}

    return r;

};

map方法用于注册路由规则,我们新建一个config.js的文件,来配置route规则:

            var ct = new controllerContext(req, res);

            //动态调用,动态语言就是方便啊

            //通过apply将controller的上下文对象传递给action

            controller[actionInfo.action].apply(ct, actionInfo.args);

这里会通过apply将controllerContext作为action的this,并传递args作为action的参数来调用action。 ontrollerContext封装了一些action会用到的方法:

var viewEngine = {

    render: function(req, res, viewName, context){

        var filename = path.join(dirname, 'views', viewName);

        try{

            var output = Shotenjin.renderView(filename, context);

        }catch(err){

            handler500(req, res, err);

            return;

        }

        res.writeHead(200, {'Content-Type': 'text/html'});

        res.end(output);

    },

    renderJson: function(res, json){

        //TODO:

    }

};


 

这里viewEngine主要负责模板解析。node有很多的可用的模块,模板解析模块也有一大堆,不过这里我们是要“玩”,所以模板解析系统我们这里使用

//shotenjin.js 增加的代码 //模板缓存,缓存解析后的模板 Shotenjin.templateCatch = {}; //读取模板内容 //在模板中引用模板使用: {# ../layout.html #} Shotenjin.getTemplateStr = function(filename){ //console.log('get template:' + filename); var t = ''; //这里使用的是同步读取 if(path.existsSync(filename)){ t = fs.readFileSync(filename, 'utf-8'); }else{ throw 'View: ' + filename + ' not exists'; } t = t.replace(/{#[\s]([.\/\w-]+)[\s]#}/ig, function(m, g1) { var fp = path.join(filename, g1.trim()) return Shotenjin.getTemplateStr(fp); }); return t; }; Shotenjin.renderView = function(viewPath, context) { var template = Shotenjin.templateCatch[viewPath]; if(!template){ var template_str = Shotenjin.getTemplateStr(viewPath); var template = new Shotenjin.Template(); template.convert(template_str); //添加到缓存中 Shotenjin.templateCatch[viewPath] = template; } var output = template.render(context); return output; }; global.Shotenjin = Shotenjin;
 

增加的代码主要是读取模板的内容,并解析模板中类似 {# ../layout.html #} 的标签,递归读取所有的模板内容,然后调用jstenjin的方法来解析模板。 这里读取文件内容使用的是fs.readFileSync,这是同步阻塞读取文件内容的,和我们平时使用的大多编程语言一样,而fs.readFile的非阻塞异步读。 这里的shotenjin.js原来是给客户端web浏览器javascript解析模板用的,现在拿到node.js来用,完全不用修改就正常工作。Google V8真威武。 现在基本的东西都完成了,但是对于静态文件,例如js、css等我们需要一个静态文件服务器:

blog/index.html的内容为:

嗯嗯,一切正常。 好,接下来我们再写一个获取新浪微博最新微博的页面。首先,我们在config.js中增加一个route配置:
 

var http = require('http'),

    events = require("events");

var tsina_client = http.createClient(80, "api.t.sina.com.cn");

var tweets_emitter = new events.EventEmitter();

// action: tweets

exports.tweets = function(blogType){

    var _t = this;

    var listener = tweets_emitter.once("tweets", function(tweets) {

        _t.render('blog/tweets.html', {tweets: tweets});

    });

    get_tweets();

};

function get_tweets() {

    var request = tsina_client.request("GET", "/statuses/public_timeline.json?source=3243248798", {"host": "api.t.sina.com.cn"});

    request.addListener("response", function(response) {

        var body = "";

        response.addListener("data", function(data) {

            body += data;

        });

        response.addListener("end", function() {

            var tweets = JSON.parse(body);

            if(tweets.length > 0) {

                console.log('get tweets \n');

                tweets_emitter.emit("tweets", tweets);

            }

        });

    });

    request.end();

}

 

这里使用http.createClient来发送请求获取新浪微博的最新微博,然后注册相应事件的监听。这里详细说下node的事件系统:EventEmitter。 EventEmitter可以通过require('events'). EventEmitter来访问,创建一个 EventEmitter的实例emitter后,就可以通过这个emitter来注册、删除、发出事件了。 例如上面的代码中,先创建来一个EventEmitter的实例:
 

    var listener = tweets_emitter.once("tweets", function(tweets) {

        _t.render('blog/tweets_data.html', {tweets: tweets});

    });

 

once注册的事件在事件被触发一次后,就会自动移除。 最后,通过emit来发出事件:
 

 

#{tweet.text}

<?js if(tweet.thumbnail_pic){ ?>

clip_image008[6] 附一个简单的和Django的对比测试

Modules可以用,也有比较成熟的web框架learnNode.zip

http://nodejs.org/api.html

tornado web 非阻塞技术 具体是指什么

tornado的非阻塞是指的底层的Socket IO, 非阻塞(读写), 当HTTPServer 有socket接入时, socket fd 将被注册到操作系统事件轮询的系统调用中, Linux中的Epoll, 当socket有可读数据时就会触发读事件, 可写时就触发写事件, 不会把整个应用阻塞到某个函数上. 

 

epoll使用详解

http://blog.csdn.net/ljx0305/article/details/4065058

网上看到的觉得写的还挺好的 这就是目前的眼光不足 所以记录下来

看到前人的文章,总结自己的学习心得,颇有感悟,下面是自己的总结,平时就拿出来多问问自己。仅供参考 1.首先看了PHP的源码API函数,对于许多口水仗的争论一笑而过,只是停留在脚本级别上的什么效率,安全。。。之争完全就是无稽之谈,没有深入理解API,所有的争论都是臆测和不科学的态度。你做了吗?

 

2.不再把PHP看作一门后台语言,而是一门类似JS的脚本,页面表现级的语言,更多的是尝试使用一种软件来做后台,PHP做前台,尝试真正的B/S开发。你的看法呢?

 

3.知识更新。PHP中的接口你懂了吗?反射你听过吗?JS中的事件冒泡你懂了吗?原型链知道吗?一切函数都是对象,你能理解否?MYSQL里面的视图,存储过程你尝试过么有?

 

4.扎实的学知识。你是不是离开了JQ框架就连个DOM操作的原生JS都不会写了?你是不是离开了DB类,就连个简单的查询都不会写了?你是不是离开了IDE,连个表格都画不出来?你是不是到现在多表查询,子查询都还不会?你是不是到现在就只知道索引是用来加快查询的? 你是不是到现在连个PHP5的稍微复杂点的OO类都还不会写?你会正则吗?你的E文水平咋样?

 

5.扎实的算法基础。你知道选择排序,插入排序,冒泡排序,二分排序,希尔排序并且能写出来吗?你知道怎么遍历二叉树吗?知道霍夫曼吗?你知道图吗?你知道龙格-库塔,迭代,插值,雅戈尔,牛顿下山法吗?知道ZIP压缩原理吗?你是不是可爱到以为加减乘除加上循环判断就搞定了算法?你知道概率论,微积分,线性方程组在算法中是非常非常基础的吗?

 

6.学习的主动性。你是不是自己的网站连个拿的出手的JS都没有写过?你网站的效果是不是都是你下载的JQ插件弄出来的?到现在都还没有看过JQ的代码?你现在的模板引擎是谁的?DB类是谁的?框架是谁的?你是不是一直都很鄙视重复造轮子的事情,就像中国现在,“拿来主义”,永远是MADE IN CHINA,而不是Created in China?

 

7.广泛的基础。你会汇编吗?那C总该会点吧。。那C++呢,那简单的JAVA总该会吧。。。那。。那傻瓜化的VB,NET,PY。。。?什么,你只会PHP?其他啥都不会?JS总该会吧?啊,不会,只会用网上下来的JQ?你除了PHP还会点啥?那假如PHP垮台了或者你所在的公司不用PHP了你吃什么?如果老板让你学J2SE你怕不怕?

 

8.你是不是就准备一辈子做个coder?你的知识如果让你传授给别人的话,能支撑三个月吗?三个月后你还能讲得出点其他的东西吗?

 

9.你现在的水平和你刚开始学的时候进步了多少?你有过自己的作品吗?有多少代码是你自己写的?你认为是不是只要会写PHP代码就够了?这样的话一个初中生三个月后也就能达到你的水平了,你认为呢?你准备一直停留在这个水平吗?

 

10.最后一问,你除了会写仅会的PHP代码,还会点其他的吗?你有把握做其他工作吗?你能养活自己老婆孩子吗?能给他们幸福吗? 问我自己,也问所有PHPER。仅供参考。 醒醒吧,雄起吧!最可爱的人!仅以此文激励自己永不放弃,奋发学习,激流勇进!!!! 还有一点,不要老灌水,老闲聊,老YD,时间不多了,夜色没事还是少来点吧。大家2010努力。

PHP array_splice() 函数

$aColumns = array(
 array( 'ta'=>'c', 'f'=>'po_id', 'hd'=>'Y')
 ,array('d'=>'is_delete_able', 'hd'=>'Y')
 ,array('ta'=>'a', 'f'=>'create_time','d'=>'Creation Date','so'=>array('desc','asc'), 'dso'=>'desc')
 ,array('ta'=>'b', 'f'=>'prefix','d'=>'Prefix','so'=>array('desc','asc'), 'se'=>'like')
 ,array('ta'=>'a', 'f'=>'voucher_no','d'=>'Voucher No.','so'=>array('desc','asc'))
 ,array('ta'=>'b', 'f'=>'suffix','d'=>'Suffix','so'=>array('desc','asc'), 'se'=>'like', 'hd'=>'Y')
 ,array('ta'=>'a', 'f'=>'voucher_value','d'=>'Value','so'=>array('desc','asc'))
 ,array('ta'=>'b', 'f'=>'total_vouchers','d'=>'Quantity','so'=>array('desc','asc'))
 ,array('ta'=>'b', 'f'=>'total_value','d'=>'Total Value','so'=>array('desc','asc'))
 ,array('ta'=>'c', 'f'=>'po_number','d'=>'P.O. Number','so'=>array('desc','asc'), 'se'=>'like')
 ,array('d'=>'Action')
);

$splice = array(array('ta'=>'b', 'f'=>'suffix','d'=>'Suffix','so'=>array('desc','asc'), 'se'=>'like'));
array_splice($aColumns, 5, 1, $splice);

 

该函数如果不加第4个参数是删除start ~ length的内容

加上第4个参数之后用第4个参数替代原位置的内容