<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.feedsky.com/styles/feedsky1.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link href="http://feed.feedsky.com/lilinux" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/lilinux" type="application/rss+xml"></fs:self_link><lastBuildDate>Sat, 14 May 2011 12:51:59 GMT</lastBuildDate><title>Li's Blog</title><description>分享与成长</description><link>http://blog.lilinux.net</link><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><language>en</language><pubDate>Sat, 14 May 2011 14:26:41 GMT</pubDate><item><title>一封邮件让我郁闷了</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583656/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;一直以来，我都想好好经营这个小网站，所以从一开始就坚持原创，极少地转载一些东西。最近这段时间，因为没有做啥我觉得有价值的东西，所以我也宁愿什么都不更新，看着搜索引擎的降权再降权。好在每天都有120-200左右的访问量，让我觉得能帮助到别人就好了。&lt;/p&gt;
&lt;p&gt;所以，在抄袭这个角度上来看，我觉得自己还是不错的，文章中偶尔引用的别人的东西，即使再少，我也注明了出处。但是刚刚好不容易上了Gmail，看到一封新邮件，把我彻底搞郁闷了。&lt;/p&gt;
&lt;p&gt;是一个老外发来的，我英语不太好，乍一看，发现是在“指教”我的，他认为我抄袭了他的文章。我心里扑腾一下，马上打开，看到是一段代码，并且说我把代码broken了。我非常火大，因为这些在文章中的作用并不大，而且也不是多么复杂的东西。但我转念一想，也许人家是一个治学严谨之人，而且不管重不重要，毕竟我是我引用了他的东西（我标明了来源，否则估计也不容易找到我）&lt;/p&gt;
&lt;p&gt;我感到很羞愧，仔细地看了一遍邮件。前面一部分他的意思是，“你知道这玩意吗，知道那玩意儿吗”，然后告诉我侵犯了什么什么。我很弱，觉得真是这样的。&lt;/p&gt;
&lt;p&gt;中间一部分提出了我必须改进的：必须使用某种文章引用协议，保留原作者的一系列东西，必须添加若干链接。我的文章本来就不长，但毕竟我是错了，我也愿意这样做，文章的结构难看点总比没有好。&lt;/p&gt;
&lt;p&gt;后面一部分是“表扬”我，说我至少没有怎么样侵犯权利，至少做了我自己的工作（我有点不爽）。&lt;/p&gt;
&lt;p&gt;PS部分是说他很礼貌，是因为我至少没有完全抄袭，而不像某些“小偷”。。。&lt;/p&gt;
&lt;p&gt;……（省略若干字）&lt;/p&gt;
&lt;p&gt;于是，我把文章删了。并且回复邮件，说我很羞愧。&lt;/p&gt;
&lt;p&gt;也许被我认为微不足道的小段脚本是人家的宝贝疙瘩，那我就自己写了再重新发布吧&lt;/p&gt;
&lt;p&gt;你妹啊，哥的ppt又没做&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583656/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583656/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2011/05/i-am-thief/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>热度: 一直以来，我都想好好经营这个小网站，所以从一开始就坚持原创，极少地转载一些东西。最近这段时间，因为没有做啥我觉得有价值的东西，所以我也宁愿什么都不更新，看着搜索引擎的降权再降权。好在每天都有120-200左右的访问量，让我觉得能帮助到别人就好了。 所以，在抄袭这个角度上来看，我觉得自己还是不错的，文章中偶尔引用的别人的东西，即使再少，我也注明了出处。但是刚刚好不容易上了Gmail，看到一封新邮件，把我彻底搞郁闷了。 是一个老外发来的，我英语不太好，乍一看，发现是在“指教”我的，他认为我抄袭了他的文章。我心里扑腾一下，马上打开，看到是一段代码，并且说我把代码broken了。我非常火大，因为这些在文章中的作用并不大，而且也不是多么复杂的东西。但我转念一想，也许人家是一个治学严谨之人，而且不管重不重要，毕竟我是我引用了他的东西（我标明了来源，否则估计也不容易找到我） 我感到很羞愧，仔细地看了一遍邮件。前面一部分他的意思是，“你知道这玩意吗，知道那玩意儿吗”，然后告诉我侵犯了什么什么。我很弱，觉得真是这样的。 中间一部分提出了我必须改进的：必须使用某种文章引用协议，保留原作者的一系列东西，必须添加若干链接。我的文章本来就不长，但毕竟我是错了，我也愿意这样做，文章的结构难看点总比没有好。 后面一部分是“表扬”我，说我至少没有怎么样侵犯权利，至少做了我自己的工作（我有点不爽）。 PS部分是说他很礼貌，是因为我至少没有完全抄袭，而不像某些“小偷”。。。 ……（省略若干字） 于是，我把文章删了。并且回复邮件，说我很羞愧。 也许被我认为微不足道的小段脚本是人家的宝贝疙瘩，那我就自己写了再重新发布吧 你妹啊，哥的ppt又没做&lt;img src=&quot;http://www1.feedsky.com/t1/511583656/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583656/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>随便扯扯</category><pubDate>Sat, 14 May 2011 20:51:59 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2011/05/i-am-thief/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=496</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2011/05/i-am-thief/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583656/6171942</fs:itemid></item><item><title>主流文本编辑器的学习曲线</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583657/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;转自酷壳 &lt;a href=&quot;http://coolshell.cn&quot;&gt;http://coolshell.cn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://coolshell.cn/wp-content/uploads/2010/10/horrorstories.txt.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583657/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583657/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2011/02/horrorstories/feed/</wfw:commentRss><slash:comments>1</slash:comments><description>热度: 转自酷壳 http://coolshell.cn&lt;img src=&quot;http://www1.feedsky.com/t1/511583657/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583657/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>notepad</category><category>随便扯扯</category><category>vim</category><pubDate>Tue, 01 Feb 2011 15:27:54 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2011/02/horrorstories/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=490</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2011/02/horrorstories/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583657/6171942</fs:itemid></item><item><title>还在为Windows纠结吗？呸，那是万恶的旧社会</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583658/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;&lt;img src=&quot;http://th05.deviantart.net/fs15/PRE/f/2006/365/9/5/Che_Tux__Linux___Communism_by_yashton.jpg&quot; alt=&quot;Che Tux&quot; /&gt;&lt;br /&gt;
出自：&lt;a href=&quot;http://yashton.deviantart.com/art/Che-Tux-Linux-Communism-45730927&quot; class=&quot;liexternal&quot;&gt;http://yashton.deviantart.com/&lt;/a&gt;&lt;br /&gt;
&lt;span id=&quot;more-481&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
nat叫“共享网络连接”&lt;/p&gt;
&lt;p&gt;ad-hoc叫“计算机到计算机的特定连接&amp;#8230;”&lt;/p&gt;
&lt;p&gt;自作聪明的自动设置&lt;br /&gt;
。。。&lt;/p&gt;
&lt;p&gt;喵的，浪会锅好多时间&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583658/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583658/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2011/01/che-tux/feed/</wfw:commentRss><slash:comments>3</slash:comments><description>热度: 出自：http://yashton.deviantart.com/ nat叫“共享网络连接” ad-hoc叫“计算机到计算机的特定连接&amp;#8230;” 自作聪明的自动设置 。。。 喵的，浪会锅好多时间&lt;img src=&quot;http://www1.feedsky.com/t1/511583658/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583658/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>随便扯扯</category><pubDate>Thu, 20 Jan 2011 11:41:43 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2011/01/che-tux/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=481</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2011/01/che-tux/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583658/6171942</fs:itemid></item><item><title>能打开Google，但打不开Gmail的问题</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583659/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;&lt;img src=&quot;http://t1.gstatic.com/images?q=tbn:ANd9GcRnxkFh-dcH3Qopz-ICSmSpKMwV6lr_NP3xgv_cJd9sZtETUmil&quot; alt=&quot;Gmail&quot; /&gt;&lt;br /&gt;
据谣言说，为响应文件精神，铁通公司（现在归移动）作为全国各大ISP之执牛耳者，在某些地方（比如江西）率先推行了网络白名单制度。除了几个门户网站之外，其余网站一律打不开（直接把包DROP）。从此以后，不仅“非死不可”、“You土鳖”等境外反动网站打不开，连bbc、nytimes也打不开，使得Li锅我好久都没有看到老外对俺们繁荣昌盛的羡慕了。&lt;/p&gt;
&lt;p&gt;当然了，这样一来，我的小站也处在风雨飘摇之中。好在江西铁通宽宏大量，对“Do Evil”的google留了一个小门：只能打开&lt;a href=&quot;http://www.google.com.hk&quot;&gt;www.google.com.hk&lt;/a&gt;，其余Google服务一概打不开。&lt;/p&gt;
&lt;p&gt;这样的情况经常出现，因为Google向来是人民群众狠抓痛打的对象。所以趁现在铁通工作人员吃午饭的时间，赶紧打开我的博客，赶紧写点东西。&lt;br /&gt;
&lt;span id=&quot;more-474&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;如前所述，Google的这个问题由来以久。我对Google的云计算服务了解有限，但基本可以确定这样一个表面现象：Google的所有服务都是由所有主机构成的云平台完成的，每个接入点IP对应的主机都可以从云中得到相应的服务。也就是说，虽然google.com和mail.google.com通过dns解析出来的IP不一样，但这些IP其实都是具有“全功能”的。而Google提供给的服务类型是通过url来确定的：比如你把mail.google.com解析的IP直接输入浏览器的地址栏，Google的服务器无法从url中得到是&amp;#8221;www&amp;#8221;还是&amp;#8221;mail“，会默认的打开Google搜索的主页面。&lt;/p&gt;
&lt;p&gt;因此，即使mail.google.com的IP被禁止，我们也可以通过&lt;a href=&quot;http://www.google.com.hk&quot;&gt;www.google.com.hk&lt;/a&gt;的接入点来获取gmail服务。那么直观上的感觉可以这样做：&lt;strong&gt;把mail.google.com的解析地址改成和可以打开的&lt;a href=&quot;http://www.google.com.hk&quot;&gt;www.google.com.hk&lt;/a&gt;的地址一致即可&lt;/strong&gt; 。在Linux下，在/etc/hosts中手动添加相应的条目；在windows xp下，在\%Systemroot%\System32\Drivers\Etc\Hosts中手动添加相应的条目。&lt;/p&gt;
&lt;p&gt;OK，这样简单的操作之后，我们在浏览器的地址栏中输入“mail.google.com”时，系统会优先使用hosts中的条目，即指向了&amp;#8221;&lt;a href=&quot;http://www.google.com.hk&quot;&gt;www.google.com.hk&lt;/a&gt;&amp;#8221;的IP，并且告诉Google云，我需要gmail服务。结果在实际操作中发现，gmail打开后登录不了，它卡在了一个&amp;#8221;&lt;a href=&quot;http://www.google.com/accounts/xxooxxoo&quot;&gt;www.google.com/accounts/xxooxxoo&lt;/a&gt;“这样的阶段，这说明gmail&lt;br /&gt;
需要转到&lt;a href=&quot;http://www.google.com&quot;&gt;www.google.com&lt;/a&gt;去认证用户名和密码，而&lt;a href=&quot;http://www.google.com&quot;&gt;www.google.com&lt;/a&gt;所解析的IP也被禁止了。于是，我们只需要在hosts文件中再加上&lt;a href=&quot;http://www.google.com&quot;&gt;www.google.com&lt;/a&gt;的条目就可以了，ip还是和&lt;a href=&quot;http://www.google.com.hk&quot;&gt;www.google.com.hk&lt;/a&gt;所指向的一致。&lt;/p&gt;
&lt;p&gt;这样，gmail就可以正常打开了，在打开时可能会提示ssl的异常，只需要简单的忽略掉就可以鸟。&lt;/p&gt;
&lt;p&gt;这是一个修改hosts的简单应用，除了google这样的云服务，像我的博客这样的其它网站还是没有办法。我还是趁着铁通上班赶紧发出来吧。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583659/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583659/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2011/01/google-gmail-dns/feed/</wfw:commentRss><slash:comments>3</slash:comments><description>热度: 据谣言说，为响应文件精神，铁通公司（现在归移动）作为全国各大ISP之执牛耳者，在某些地方（比如江西）率先推行了网络白名单制度。除了几个门户网站之外，其余网站一律打不开（直接把包DROP）。从此以后，不仅“非死不可”、“You土鳖”等境外反动网站打不开，连bbc、nytimes也打不开，使得Li锅我好久都没有看到老外对俺们繁荣昌盛的羡慕了。 当然了，这样一来，我的小站也处在风雨飘摇之中。好在江西铁通宽宏大量，对“Do Evil”的google留了一个小门：只能打开www.google.com.hk，其余Google服务一概打不开。 这样的情况经常出现，因为Google向来是人民群众狠抓痛打的对象。所以趁现在铁通工作人员吃午饭的时间，赶紧打开我的博客，赶紧写点东西。 如前所述，Google的这个问题由来以久。我对Google的云计算服务了解有限，但基本可以确定这样一个表面现象：Google的所有服务都是由所有主机构成的云平台完成的，每个接入点IP对应的主机都可以从云中得到相应的服务。也就是说，虽然google.com和mail.google.com通过dns解析出来的IP不一样，但这些IP其实都是具有“全功能”的。而Google提供给的服务类型是通过url来确定的：比如你把mail.google.com解析的IP直接输入浏览器的地址栏，Google的服务器无法从url中得到是&amp;#8221;www&amp;#8221;还是&amp;#8221;mail“，会默认的打开Google搜索的主页面。 因此，即使mail.google.com的IP被禁止，我们也可以通过www.google.com.hk的接入点来获取gmail服务。那么直观上的感觉可以这样做：把mail.google.com的解析地址改成和可以打开的www.google.com.hk的地址一致即可 。在Linux下，在/etc/hosts中手动添加相应的条目；在windows xp下，在\%Systemroot%\System32\Drivers\Etc\Hosts中手动添加相应的条目。 OK，这样简单的操作之后，我们在浏览器的地址栏中输入“mail.google.com”时，系统会优先使用hosts中的条目，即指向了&amp;#8221;www.google.com.hk&amp;#8221;的IP，并且告诉Google云，我需要gmail服务。结果在实际操作中发现，gmail打开后登录不了，它卡在了一个&amp;#8221;www.google.com/accounts/xxooxxoo“这样的阶段，这说明gmail 需要转到www.google.com去认证用户名和密码，而www.google.com所解析的IP也被禁止了。于是，我们只需要在hosts文件中再加上www.google.com的条目就可以了，ip还是和www.google.com.hk所指向的一致。 这样，gmail就可以正常打开了，在打开时可能会提示ssl的异常，只需要简单的忽略掉就可以鸟。 这是一个修改hosts的简单应用，除了google这样的云服务，像我的博客这样的其它网站还是没有办法。我还是趁着铁通上班赶紧发出来吧。&lt;img src=&quot;http://www1.feedsky.com/t1/511583659/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583659/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>云计算</category><category>Hosts</category><category>Gmail</category><category>web应用</category><category>google</category><pubDate>Tue, 18 Jan 2011 14:25:25 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2011/01/google-gmail-dns/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=474</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2011/01/google-gmail-dns/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583659/6171942</fs:itemid></item><item><title>如何迁移wordpress站点</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583660/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;半个月前，我的博客被二手空间商单方面停止了，发邮件也不回。虽然我写的东西并不多，尤其是半年前不得不天天用OPNET on WinDOS来干活以来，更新更是急剧减少，但是这毕竟是我一个字一个字写的，主题也是逐字汉化，还用蹩脚的GIMP手艺改了一些图标。那种恼羞成怒的感觉相信你已经可以能体会到了。&lt;/p&gt;
&lt;p&gt;正是因为如此，即使迁移wordpress站点并不是一个多复杂的事，狂暴的心情也足以让类似我这样对web前端只略知一二的小菜没有头绪。于是，这篇文章就是写给像我这样又懒又火气大的人的。&lt;br /&gt;
&lt;span id=&quot;more-471&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt; wordpress站点的备份&lt;/h1&gt;
&lt;p&gt;众所周知，wordpress是一个优秀的blog模板，它一般运行在经典的LAMP(Linux/Apache/Mysql/PHP)平台上。LAMP的这四个要素如果要分层次的话，可以分为三层：最底层是操作系统，即Linux（少数用windows的）；中间层是Apache，用于提供web服务；最上层是Mysql和PHP分别提供数据库支持和动态请求响应。那么，对wordpress站点而言，需要备份的就是&lt;strong&gt;Mysql数据库&lt;/strong&gt;和&lt;strong&gt;PHP文件以及其它web文件&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;wordpress的数据库包含了除去wordpress源码、wordpress主题、wordpress插件等“固定”内容以后的数据，比如文章、评论（可选）和某些插件所建立的数据库表项（可选）。它也可以导入到其它wordpress站点。对数据库的备份可以选用mysqldump这样的命令行样式，也可以利用web host提供的功能进行备份。一般来说，推荐使用后面这种方法，虽然它们的操作本质上是一样的。如果你担心有一天像我一样，host突然就把你的账户删除了，那你就要自动备份数据库了。wordpress的插件&lt;a href=&quot;http://austinmatzko.com/wordpress-plugins/wp-db-backup/&quot; class=&quot;liexternal&quot;&gt;&lt;strong&gt;WordPress Database Backup&lt;/strong&gt;&lt;/a&gt;可以自动周期备份数据库，并将数据库发到指定的邮箱。这个插件的优势在于：它不要求你的web host有自动备份功能，也不要求你有cron（任务计划）的权限，只要能安装wordpress就可以了。&lt;/p&gt;
&lt;p&gt;web目录就是你的wordpress安装的目录了，比如我的blog的目录就是在lilinux.net所在主机上的/home/lilinux/www/blog/目录，将其压缩复制到本地磁盘或其它地方就算是备份了。web目录的自动备份就依赖于你所在的web host是否有自动备份文件的功能或者cron权限了，目前我也没找到相应的插件。web目录里包含了所有的页面，包括wordpress本身的页面和安装的主题及插件等，它也以web页面的形式包含了数据库中的内容。&lt;/p&gt;
&lt;p&gt;对我来说，数据库的重要性远大于web目录，好在我原来安装了备份插件，我只需要到备份邮箱里找到最新的备份就好了。&lt;/p&gt;
&lt;h1&gt;迁移&lt;/h1&gt;
&lt;p&gt;只要有备份，迁移工作就很简单了。在新的主机上把dns什么的都弄好后，把web目录都复制进相应的目录。&lt;/p&gt;
&lt;p&gt;然后新建一个数据库，新建数据库用户，赋予相应的操作权限，并导入你备份的数据库即可（这些都可以在PHPMyAdmin下完成）&lt;/p&gt;
&lt;p&gt;然后打开wordpress目录下的&lt;strong&gt;wp-config.php&lt;/strong&gt;文件，把现在的数据库位置和用户名密码重新设置即可。&lt;/p&gt;
&lt;p&gt;我的数据库备份是2010年12月29日的、web目录是2010年3月4日的（太懒了，一直没备份，好在我在3月4日之后就几乎没有修改主题了）。在把web目录恢复后，就可以打开站点，可以看到2010年3月4日以前的所有内容，但是任何与数据库有关的操作都无法完成。然后把数据库导入并修改wp-config.php文件。不过blog.lilinux.net并没有立即将数据库更新，显示的文章还是3月4日以前的，发出一篇文章后，果然，原来的文章都回来了&lt;/p&gt;
&lt;h1&gt;可能遇到的问题&lt;/h1&gt;
&lt;p&gt;从我的经历来看，wordpress确实是个不错的模板。但可能会出现一些问题，比如打开链接都是HTTP 404错误等。这些都是迁移后数据库会刷新造成的，只要重新设置wordpress就好了。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583660/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583660/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2011/01/wordpress-migration/feed/</wfw:commentRss><slash:comments>3</slash:comments><description>热度: 半个月前，我的博客被二手空间商单方面停止了，发邮件也不回。虽然我写的东西并不多，尤其是半年前不得不天天用OPNET on WinDOS来干活以来，更新更是急剧减少，但是这毕竟是我一个字一个字写的，主题也是逐字汉化，还用蹩脚的GIMP手艺改了一些图标。那种恼羞成怒的感觉相信你已经可以能体会到了。 正是因为如此，即使迁移wordpress站点并不是一个多复杂的事，狂暴的心情也足以让类似我这样对web前端只略知一二的小菜没有头绪。于是，这篇文章就是写给像我这样又懒又火气大的人的。 wordpress站点的备份 众所周知，wordpress是一个优秀的blog模板，它一般运行在经典的LAMP(Linux/Apache/Mysql/PHP)平台上。LAMP的这四个要素如果要分层次的话，可以分为三层：最底层是操作系统，即Linux（少数用windows的）；中间层是Apache，用于提供web服务；最上层是Mysql和PHP分别提供数据库支持和动态请求响应。那么，对wordpress站点而言，需要备份的就是Mysql数据库和PHP文件以及其它web文件。 wordpress的数据库包含了除去wordpress源码、wordpress主题、wordpress插件等“固定”内容以后的数据，比如文章、评论（可选）和某些插件所建立的数据库表项（可选）。它也可以导入到其它wordpress站点。对数据库的备份可以选用mysqldump这样的命令行样式，也可以利用web host提供的功能进行备份。一般来说，推荐使用后面这种方法，虽然它们的操作本质上是一样的。如果你担心有一天像我一样，host突然就把你的账户删除了，那你就要自动备份数据库了。wordpress的插件WordPress Database Backup可以自动周期备份数据库，并将数据库发到指定的邮箱。这个插件的优势在于：它不要求你的web host有自动备份功能，也不要求你有cron（任务计划）的权限，只要能安装wordpress就可以了。 web目录就是你的wordpress安装的目录了，比如我的blog的目录就是在lilinux.net所在主机上的/home/lilinux/www/blog/目录，将其压缩复制到本地磁盘或其它地方就算是备份了。web目录的自动备份就依赖于你所在的web host是否有自动备份文件的功能或者cron权限了，目前我也没找到相应的插件。web目录里包含了所有的页面，包括wordpress本身的页面和安装的主题及插件等，它也以web页面的形式包含了数据库中的内容。 对我来说，数据库的重要性远大于web目录，好在我原来安装了备份插件，我只需要到备份邮箱里找到最新的备份就好了。 迁移 只要有备份，迁移工作就很简单了。在新的主机上把dns什么的都弄好后，把web目录都复制进相应的目录。 然后新建一个数据库，新建数据库用户，赋予相应的操作权限，并导入你备份的数据库即可（这些都可以在PHPMyAdmin下完成） 然后打开wordpress目录下的wp-config.php文件，把现在的数据库位置和用户名密码重新设置即可。 我的数据库备份是2010年12月29日的、web目录是2010年3月4日的（太懒了，一直没备份，好在我在3月4日之后就几乎没有修改主题了）。在把web目录恢复后，就可以打开站点，可以看到2010年3月4日以前的所有内容，但是任何与数据库有关的操作都无法完成。然后把数据库导入并修改wp-config.php文件。不过blog.lilinux.net并没有立即将数据库更新，显示的文章还是3月4日以前的，发出一篇文章后，果然，原来的文章都回来了 可能遇到的问题 从我的经历来看，wordpress确实是个不错的模板。但可能会出现一些问题，比如打开链接都是HTTP 404错误等。这些都是迁移后数据库会刷新造成的，只要重新设置wordpress就好了。&lt;img src=&quot;http://www1.feedsky.com/t1/511583660/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583660/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>wordpress</category><category>计算机初级教程</category><category>迁移</category><category>WordPress使用</category><pubDate>Tue, 11 Jan 2011 14:09:12 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2011/01/wordpress-migration/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=471</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2011/01/wordpress-migration/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583660/6171942</fs:itemid></item><item><title>OPNET Modeler的命令行与批量仿真</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583661/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;原来我对OPNET一直存在着误解，其中最主要的一点就是：不提供命令行接口。不管是不是CLI的拥趸，都不能否认命令行接口的重要性，它可以方便的调用，以及对其批量处理。对于OPNET这样的仿真工具，如果要进行大量的仿真，那命令行接口比起图形接口“至少好五倍”（OPNET 14.5可以在GUI中批量仿真，但是仍然简陋得可怕）&lt;br /&gt;
&lt;span id=&quot;more-468&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;1. OPNET的命令行&lt;/h1&gt;
&lt;p&gt;安装OPNET Modeler和配置其环境变量本文就不再赘述，这个步骤成功的标志在于：在cmd窗口中输入“op_runsim”，会有如下返回：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p468code3'); return false;&quot;&gt;View Code&lt;/a&gt; TEXT&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p4683&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p468code3&quot;&gt;&lt;pre class=&quot;text&quot; style=&quot;font-family:monospace;&quot;&gt;&amp;lt;&amp;lt;&amp;lt; Program Abort &amp;gt;&amp;gt;&amp;gt;
  * Time:      13:49:02 Mon Jan 10 2011
  * Product:   Generic Product (32-bit)
  * Package:   Vos (Virtual Operating System) / Env (Environment Variable)
  * Function:  Vos_Env_Static_Requests
  * Error:     required env. attribute (net_name) not set&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;如果出现“&amp;#8217;op_runsim&amp;#8217; 不是内部或外部命令，也不是可运行的程序或批处理文件。” 请检查环境变量是否设置好。&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;很显然，op_runsim正是OPNET运行仿真场景的程序，你可以认为在图形界面中的仿真实际也是调用了这个程序/命令。&lt;/p&gt;
&lt;p&gt;op_runsim命令的选项风格是Linux式的，输入&amp;#8221;op_runsim -help&amp;#8221;即可看到op_runsim的完整命令行选项说明（当然你是不可能在cmd窗口下输入man op_runsim的）。op_runsim的选项非常多，甚至比OPNET Modeler的仿真GUI界面提供的还多，建议将其输出重定向后再用文本编辑器查看&lt;/p&gt;
&lt;p&gt;说到这里，对命令行有经验的朋友就不用再看下去了，因为只要知道了op_runsim这个命令，并且可以得到它的使用说明，那后面怎么做就要看具体的使用情况了。所以后面的内容是给憎恨或者对命令行和批处理陌生的读者。&lt;/p&gt;
&lt;p&gt;op_runsim的选项虽然多，但最重要的其实只有以下几个：&lt;/p&gt;
&lt;p&gt;1. &lt;strong&gt;-net_name&lt;/strong&gt; 指定仿真的场景名，由“工程名-场景名”这样的格式组成。仿真的场景名应该是已经存在的OPNET工程中的场景，例如“TrafficGenerator-GEN3”表示在TrafficGenerator工程的GEN3场景。场景当然是要用OPNET Modeler的GUI界面来建立。&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;-duration &lt;/strong&gt;仿真时间，单位为秒。&lt;/p&gt;
&lt;p&gt;3.&lt;strong&gt; -seed&lt;/strong&gt; 随机数种子。用于产生随机数的种子&lt;/p&gt;
&lt;p&gt;综合起来，你可以在cmd下面输入“op_runsim -net_name TrafficGenerator-GEN3 -duration 60 -seed 128”，如果指定的场景名有效并且可以编译通过，那么仿真就会开始运行了。&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;2. 批量处理&lt;/h1&gt;
&lt;p&gt;既然仿真能通过输入命令完成，那批量处理仿真也就不是什么难事了。批量处理可以用任何你喜欢的方式，不管是bat批处理文件、脚本文件还是C/C++这样的高级语言。对场景的批量处理的一些要求和建议是：&lt;/p&gt;
&lt;p&gt;1. 仿真结果之间不能互相影响。最常见的一种情况是：仿真后输出一个文件，但因为这个文件名是固定的，并且批量仿真了这个场景，那最后得到的输出文件是相当于是最后一次仿真得到的。解决的方法可能有这两种（1）在opnet的场景中加一些代码，使其每次输出的文件名都不一样（2）仿真完一次后，调用相应的命令（如ren、copy、move）将结果保存后再进行下一次仿真&lt;/p&gt;
&lt;p&gt;2. 对同一场景，避免使用相同的种子。对大多数数仿真而言，只要种子相同，则结果完全相同。如果需要对同一场景多次仿真，应当避免种子相同，以造成最后的统计结果出现偏差。&lt;/p&gt;
&lt;p&gt;3. 记录总的仿真状态。对OPNET进行批量仿真的一个很重要的原因就是仿真的结果可能会比较长。时间越长，则出现其它故障的概率就越高，尤其是大量进行长时间仿真时，可能会出现磁盘空间不足、断电、误操作等。记录仿真运行到那个场景是很重要的，可以在故障后，免去前面已经仿真结束的场景。如果能做到自动从断点仿真就再好不过了。&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt; 3. 实例&lt;/h1&gt;
&lt;p&gt;有这样一个场景， TrafficGenerator-GEN3。它的作用是读入一个文件，文件第一行代表将要执行的行数，然后找到这一行，读取输出文件的位置，再将生成的traffic以文本形式记录在文件中。仿真结束后，再次打开输入文件，将文件第一行的计数加1（下次仿真则从下一行开始）&lt;/p&gt;
&lt;p&gt;这样做就免去了多次改属性而可能造成的错误。但仍然需要运行这个场景数百次（输入文件有这么多行），并且每次要选用不同的种子&lt;/p&gt;
&lt;p&gt;通过Python脚本来批量仿真，脚本如下&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p468code4'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p4684&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p468code4&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #dc143c;&quot;&gt;random&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #dc143c;&quot;&gt;os&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;from&lt;/span&gt; listsrcfile &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;import&lt;/span&gt; OUTFILE  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#输入文件，里面记录了将要仿真的输出文件路径&lt;/span&gt;
&amp;nbsp;
SIM_DURATION = &lt;span style=&quot;color: #ff4500;&quot;&gt;200&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#仿真时间200秒&lt;/span&gt;
NETNAME = &lt;span style=&quot;color: #483d8b;&quot;&gt;'TrafficGenerator-GEN3'&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#仿真场景&lt;/span&gt;
MAX = &lt;span style=&quot;color: #ff4500;&quot;&gt;10000000&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#生成种子的最大数&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; control&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
	seeds = &lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#已生成的种子列表，后面随机生成的随机种子不应该与其中的相同&lt;/span&gt;
	seed = &lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;
	fp = &lt;span style=&quot;color: #008000;&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;OUTFILE&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
	lines = fp.&lt;span style=&quot;color: black;&quot;&gt;readlines&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
	fp.&lt;span style=&quot;color: black;&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
	sim_count = &lt;span style=&quot;color: #008000;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;lines&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; - &lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;
	&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;for&lt;/span&gt; i &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;, sim_count&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
		&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;True&lt;/span&gt;:
			seed=&lt;span style=&quot;color: #dc143c;&quot;&gt;random&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;randint&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;, MAX&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;# 生成将要仿真的种子&lt;/span&gt;
			&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;if&lt;/span&gt; seed &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;not&lt;/span&gt; &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;in&lt;/span&gt; seeds:
				seeds.&lt;span style=&quot;color: black;&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;seed&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;# 生成种子，直到种子不与种子列表中的种子相等为止&lt;/span&gt;
				&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;;&lt;/span&gt;
		&lt;span style=&quot;color: #dc143c;&quot;&gt;cmd&lt;/span&gt; = &lt;span style=&quot;color: #483d8b;&quot;&gt;'op_runsim -net_name '&lt;/span&gt; + NETNAME + &lt;span style=&quot;color: #483d8b;&quot;&gt;' -duration '&lt;/span&gt;\
			 + &lt;span style=&quot;color: #008000;&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;SIM_DURATION&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; + &lt;span style=&quot;color: #483d8b;&quot;&gt;' -seed '&lt;/span&gt; + &lt;span style=&quot;color: #008000;&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;seed&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;# 将要调用的命令行&lt;/span&gt;
		&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #dc143c;&quot;&gt;cmd&lt;/span&gt;
		&lt;span style=&quot;color: #dc143c;&quot;&gt;os&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;system&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #dc143c;&quot;&gt;cmd&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;# 真正开始仿真&lt;/span&gt;
&amp;nbsp;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;if&lt;/span&gt; __name__ == &lt;span style=&quot;color: #483d8b;&quot;&gt;'__main__'&lt;/span&gt;:
	control&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
	a = &lt;span style=&quot;color: #008000;&quot;&gt;raw_input&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'done!'&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;PS：博客重建后，写篇文章通告下搜索引擎&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583661/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583661/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2011/01/opnet-cmd/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>热度: 原来我对OPNET一直存在着误解，其中最主要的一点就是：不提供命令行接口。不管是不是CLI的拥趸，都不能否认命令行接口的重要性，它可以方便的调用，以及对其批量处理。对于OPNET这样的仿真工具，如果要进行大量的仿真，那命令行接口比起图形接口“至少好五倍”（OPNET 14.5可以在GUI中批量仿真，但是仍然简陋得可怕） 1. OPNET的命令行 安装OPNET Modeler和配置其环境变量本文就不再赘述，这个步骤成功的标志在于：在cmd窗口中输入“op_runsim”，会有如下返回： ?View Code TEXT&amp;#60;&amp;#60;&amp;#60; Program Abort &amp;#62;&amp;#62;&amp;#62; * Time: 13:49:02 Mon Jan 10 2011 * Product: Generic Product (32-bit) * Package: Vos (Virtual Operating System) / Env (Environment Variable) * Function: Vos_Env_Static_Requests * Error: required env. attribute (net_name) not set 如果出现“&amp;#8217;op_runsim&amp;#8217; 不是内部或外部命令，也不是可运行的程序或批处理文件。” 请检查环境变量是否设置好。 很显然，op_runsim正是OPNET运行仿真场景的程序，你可以认为在图形界面中的仿真实际也是调用了这个程序/命令。 op_runsim命令的选项风格是Linux式的，输入&amp;#8221;op_runsim -help&amp;#8221;即可看到op_runsim的完整命令行选项说明（当然你是不可能在cmd窗口下输入man op_runsim的）。op_runsim的选项非常多，甚至比OPNET Modeler的仿真GUI界面提供的还多，建议将其输出重定向后再用文本编辑器查看 说到这里，对命令行有经验的朋友就不用再看下去了，因为只要知道了op_runsim这个命令，并且可以得到它的使用说明，那后面怎么做就要看具体的使用情况了。所以后面的内容是给憎恨或者对命令行和批处理陌生的读者。 [...]&lt;img src=&quot;http://www1.feedsky.com/t1/511583661/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583661/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>Python</category><category>批量仿真</category><category>opnet</category><category>随便扯扯</category><pubDate>Mon, 10 Jan 2011 14:27:57 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2011/01/opnet-cmd/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=468</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2011/01/opnet-cmd/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583661/6171942</fs:itemid></item><item><title>新的开始</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583662/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;&lt;font size=4&gt;&lt;br /&gt;
博客重新开张&lt;/p&gt;
&lt;p&gt;不记得还丢失了些神马东西，欢迎大家提出意见和建议&lt;/p&gt;
&lt;p&gt;以后不要这么懒了&lt;br /&gt;
&lt;/font&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583662/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583662/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2011/01/new-begin/feed/</wfw:commentRss><slash:comments>3</slash:comments><description>热度: 博客重新开张 不记得还丢失了些神马东西，欢迎大家提出意见和建议 以后不要这么懒了&lt;img src=&quot;http://www1.feedsky.com/t1/511583662/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583662/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>随便扯扯</category><pubDate>Mon, 10 Jan 2011 11:27:49 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2011/01/new-begin/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=460</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2011/01/new-begin/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583662/6171942</fs:itemid></item><item><title>Li哥正在伤心中</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583663/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;blog页面只备份到2010年3月4日&lt;/p&gt;
&lt;p&gt;喵啊&lt;/p&gt;
&lt;p&gt;正在恢复中&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583663/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583663/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2011/01/so-sad/feed/</wfw:commentRss><slash:comments>0</slash:comments><description>热度: blog页面只备份到2010年3月4日 喵啊 正在恢复中&lt;img src=&quot;http://www1.feedsky.com/t1/511583663/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583663/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>悲摧</category><category>随便扯扯</category><pubDate>Mon, 10 Jan 2011 10:18:46 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2011/01/so-sad/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=457</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2011/01/so-sad/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583663/6171942</fs:itemid></item><item><title>记一次难忘的版聚</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583664/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;友情提示：流水账+小学作文体，观者自重&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-452&quot;&gt;&lt;/span&gt;&lt;br /&gt;
博客，淫淫，QQ空间、河畔同步发布：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.lilinux.net/2010/12/banju/&quot;&gt;http://blog.lilinux.net/2010/12/banju/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.renren.com/blog/227518150/503674131?isDeclare=false&quot;&gt;http://blog.renren.com/blog/227518150/503674131?isDeclare=false&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://user.qzone.qq.com/350134531/blog/1291603433&quot;&gt;http://user.qzone.qq.com/350134531/blog/1291603433&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://bbs.stuhome.net/read.php?tid=759038&amp;#038;page=e#a&quot;&gt;http://bbs.stuhome.net/read.php?tid=759038&amp;#038;page=e#a&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: medium;&quot;&gt;&lt;br /&gt;
“日落西山红霞飞，版友聚餐把清水河归，把清水河归，胸前的红花映彩霞，愉快的歌声满天飞……”&lt;/p&gt;
&lt;p&gt;伴随着欢快的歌声，我再一次拍了拍死丢猴[1]的肩膀，和他挥手告别，然后和其它几位版友一起强力插入了公交75路，踏上了回清水河的漫漫归途……这代表了本次版聚[2]的圆满结束，也表明了此次大会后各位版友对继续建设社会主义新农村[3]的殷切希望和满腔热情……&lt;/p&gt;
&lt;p&gt;本次版聚由本版资深酱油会员、本版唯一一位在物理上是MM的阿昏[4]会员策划并组织的，并由新任版主ATI[5]事先预谋、踩点和接头的。主力部队于早上9点在阳光地带集合，大家纷纷核对接头暗号和假装热情套近乎[6]。阿昏、wind[7]、tantjk[8]、lzy[9]在我来之前就已经到了。看到lzy后，我悬着的心就放下来，这次不至于是我一个人战斗，我也不想成天混迹于90后团体之中啊。紧接着，欢哥[10]、sp[11]、杜林[12]、杜林的家属[13]、若离[14]、cosfy[15]也来到了。（本段纯粹为了介绍人物，详情请看注释段）&lt;/p&gt;
&lt;p&gt;然后就是去沙河了。在坐车这种无聊的时候，毫无疑问的，阿昏肯定又要炫耀她和她家东哥的长篇系列情景喜剧。大声的交谈似乎让前排的长发MM有点不爽，在我犹豫是否要安静的时候，突然想到了本版叉叉大神[16]曾与我畅谈的猥琐哲学，顿时让我加强了信心，抛开了世俗的偏见，以大无畏的精神继续与阿昏聊着八卦直到下车到沙河。&lt;/p&gt;
&lt;p&gt;来到学校的大门着，看到已经变成废墟的工会楼、穿过拥护的南苑小道，遥望着远处不知是否还在的串串西施，我的心里感慨万千：所谓岁月如梭，造化弄人，当年我提着书包在这里左顾右盼之时，为神马就没有这么多美女呢！！来不及感慨太多，就看到了前方站在几个大妈中间的ATI、死丢猴和520[17].&lt;/p&gt;
&lt;p&gt;见到了ATI就是见到了希望，坐了两个小时的公交，我饿得眼睛都要花了，要是它是windows，那肯定早就蓝屏掉了。于是，我们冲进了xx店，二话不说坐上了桌，上了菜就马上开吃。(其实我本来是不太想来参加版聚的，因为上次版聚和这次有点像：也是一上桌就开吃，然后直到吃完，直到散开，都没怎么说话，最后实在不尽兴才去舞版围观了下下，拖鞋党的到来也影响到了舞版的“亲们”的闲情逸致。[18])眼看这次来的版友又是些猥琐不达标但闷骚过度的技术男们，担心重蹈覆辙，我连忙派阿昏过去一个一个敬酒。阿昏回来我再过去，然后是欢哥和ATI的轮番转圈。这样果然有效果多了，几杯酒下肚，气氛就起来了，大家开始有一句没一句的聊着，有的人开始勾肩搭背（我），有的人开始大声吆喝（欢哥），有的人开始基情四射（ATI和若离）……&lt;/p&gt;
&lt;p&gt;于是大会就算是开始了，首先由我做了个离职报告，因为过于装B，没什么人听。然后大家促膝长谈，讲到Linux作为我们无产阶级劳动人民自己的操作系统，应该如何又好又快发展的问题时。&lt;br /&gt;
有版友提到：以前用windows的时候受苦受难，windows作为被大资本家、大买办操纵的操作系统，它的本质是压榨劳动人民的血汗，还不能提供优质的服务，脆弱、闭源、反盗版是压在人民群众头上的三座大山，如今有了Linux，过去所有的苦难终于结束了，终端用户终于翻身做主人了，Linux是咱们技术仔自个儿的操作系统。&lt;br /&gt;
另外一位老版友语重心长的说道：发展Linux的核心思想是以用户为本，主要措施是还政于用户，要大力发扬开源社区的热爱社区、无私奉献精神，发扬Linus同志的K.I.S.S重要思想，团结在以清水渔翁同志为版主的版中央，努力建设一个资源节约型、MM友好型的社区新面貌。&lt;br /&gt;
我说：三天不学习，赶不上小若离啊。今天与会的同志都是信奉开源主义的技术仔。开源主义向来有着艰苦奋斗、团结互助的优良传统，若离MM在工作岗位上兢兢业业，不图回报，身兼多版版主，仍然不忘提升自己的业务水平，是非常值得我们在座的各位以及全版乃至全坛学习滴。&lt;br /&gt;
(会议在欢乐祥和的气氛中进行)&lt;br /&gt;
在大会结束之时，大家举杯共祝：清水渔翁万寿无疆，万寿无疆，ATI哥永远健康，永远健康 。然后由我最后一次执行版主权力，宣布在各级政府和机关的大力配合下，本次大会取得了圆成功。[19]&lt;/p&gt;
&lt;p&gt;因为喝了太多酒，还有具体细节我基本记不清了。欢哥也喝多了酒，于是才有了后面他和神曲[20]互相产生强烈共鸣的场景。&lt;/p&gt;
&lt;p&gt;吃了饭，喝了酒，扯了蛋，每个人都变得豪情万丈起来，由阿昏提议，大家前往某KTV参加歌颂祖国、歌颂本版的歌咏比赛。可惜的是，由于惧内等因素，新任版主ATI未能前往。&lt;/p&gt;
&lt;p&gt;在前往东苑某KTV的路上，阿昏偷拍了不少照片，因为刚喝完酒，大家表情比较扭曲。当然，这不表示我们赤诚的心哪怕有一点一毫的减弱。看到曝PP后某些群嘲的回复，我在此表示强烈谴责。[21]&lt;/p&gt;
&lt;p&gt;到了KTV，发现问题来了：有四分之三以上的版友基本不会唱歌的。这样的比例还是灰常吓人的。经过一番诱导和拐骗，才把场子架起来。（值得注意的是，整个下午，点歌单都没有超过1页）我作为前朝版主，为了给大家留个好印象，立马点了个《北京一夜》开嗓，结果一首没完就把嗓子吼破了。刚开始唱的几首歌典型的KTV常点的那种哀怨婉转，在我看来，这太不符合无产阶级闹革命的情怀。于是提议点一些“忠党爱国”和“农业重金属”等类型的歌。杜林及其家属含着泪水唱完了一曲《国际歌》，lzy深情地唱了几首细腻的情歌，520、wind、tantj和cosfy也都唱了一些经典曲目，号称从不开口的若离和声若蚊吟的死丢猴也硬着头皮唱了几句。倒是sp没有唱，据阿昏说是在用手机写代码。&lt;/p&gt;
&lt;p&gt;等到了“农业重金属”时，欢哥突然转职加狂暴了[22]。一曲铿锵有力的神曲《爱情买卖》下来，使得吾等皆肝胆俱裂、神游太虚。在意犹未尽之时，欢哥的一曲《我和草原有个约会》更是把全场带进了空灵的大草原，观者皆唏嘘不已，不能自拔。阿昏借故偷拍数张PP，录音无数。之后，我与欢哥合唱了公交车手机铃声排行榜第一位的《月亮之上》，不由得被曲调当中诡异莫测的爱恨情仇与悲观离合所感染，其它版友也是观者伤心，闻者掉泪。众版友对欢哥之前的豪饮与现在的纵歌都非常钦佩。&lt;/p&gt;
&lt;p&gt;时间还是过得很快滴，没过多久。我们就离开了沙河。&lt;/p&gt;
&lt;p&gt;看着夜幕降临，华灯初上。我的耳边仿佛又听到叉叉斩钉截铁的话：li哥，总有一天我们不会是非主流的[23]&lt;/p&gt;
&lt;p&gt;注释：&lt;br /&gt;
[1] 死丢猴，ID为“stuhom”，其马甲ID为“与稀离人”，也叫“离人”。因为过于闷骚，使其长期混迹本版仍然不够猥琐（最气人的是，长得还有点小帅）。即将供职于某高薪企业。&lt;br /&gt;
[2] 本次版聚，事件发生在2010年12月04日，有14个人参加，年级跨度为大二到研三。本次版聚突破了以往版聚“见面吃饭走人不说话”的传统，并制订了“人不猥琐枉少年”等一系列符合社会主义主流价值观的版内基调。&lt;br /&gt;
[3] 清水河隶属高新西区与豆瓣县之间，历来是三不管区域。在成电人“上山下乡”来到这里之后，发扬“农业学川农，工业学成理”，使得清水河旧貌换新颜。每当喜庆节日，清水河居民载歌载舞，自发的走上顺江街头………………&lt;br /&gt;
[4] 阿昏，性别女，性别男。ID为“之行”，马甲无数。江湖人称“行哥”。虽然悍勇无双，却自称为“技术仔控”，并成功attach上技术仔东哥。&lt;br /&gt;
[5] ATI，本版新任版主，ID为“ati955012m”。风流潇洒，重情重义。来自英才班，将师从院士。曾觊觎版主位多时，后来靠实际行动争取到。&lt;br /&gt;
[6] 假装热情是因为都比较腼腆。比起大家，我可以算得上流氓了。&lt;br /&gt;
[7] wind, ID为“uestc_wind”，是一朵乐于助人、热情奔放的男子。要本版会员油条化的大趋势下，他仍然保持冷静，细心地帮助别人。&lt;br /&gt;
[8] tantjk，ID就是”tantjk“。因为ID不知道怎么念，我一般都叫”tjj“。本版资深老会员之一，比死丢猴还腼腆，比较少灌水。&lt;br /&gt;
[9] lzy，ID为”lzy0001sl”，和我是同一级，也不怎么灌水，发帖都是帮助别人。作为北方汉子却有一副细腻的好嗓音。&lt;br /&gt;
[10] 欢哥，ID为“清水渔翁”，也叫“欢神”、“欢婶”、“清水MM”、“菜刀大哥”、“清水[哔][哔]”。高大威猛，技术强硬，因为受到booooss哥的高度评价而迈上了一个新的高度。&lt;br /&gt;
[11] sp, ID为“sp55aa”，计算机学院的大神，行事低调。但在阿昏曝PP后，仍然被广大网友一眼认出，可见其影响力。&lt;br /&gt;
[12] 杜林，ID为“杜林”，大二的小抵迪，非常喜欢美女。从猥琐这个层面上讲，他已经超出了很多前辈，可以在本版排上字号&lt;br /&gt;
[13] 杜林的家属，ID为“杜林的家属”，也是大二的。与杜林成双入对，形影不离，比较文静。留着漂亮的小胡子。对了，他是男生&lt;br /&gt;
[14] 若离，ID为“若离”，也叫做“若离MM”。经常用妩媚的笑容妄图掩盖他在技术上的锋芒，不仅失败了，还被ATI版主盯上了。&lt;br /&gt;
[15] cosfy，ID为“cosfy”。又是一位高大帅气的大神，技术nb，被若离引进这个猥琐团队。据说是下一任bz的有力竞争者&lt;br /&gt;
[16] 叉叉大神，ID为“xxjack”，马甲无数，且都曾经是本版优秀会员。叉叉对Linux技术本身及Linux哲学都有很深的造诣。我曾多次与他在酒桌上切蹉开源之道，并且最后是他掏钱买单的。此外，“lili姐”称号的始做俑者就是叉叉。&lt;br /&gt;
[17] 520, ID为“深夜幽魂”和“520611314”，也叫“魂妹”。为本版最不猥琐之人，比较和谐，比较有爱。曾自称“懒猪”达30余次。&lt;br /&gt;
[18] 舞版事件可到舞版搜索相关道歉帖&lt;br /&gt;
[19] 本段酒后感知系统紊乱所造成的错觉&lt;br /&gt;
[20] 欢哥与神曲。神曲录音可以找阿昏和tantjk索取&lt;br /&gt;
[21] 有MM求哪位版友资料的，可以PM我。&lt;br /&gt;
[22] 特意在此处再次顶欢哥一次&lt;br /&gt;
[23] 忘了是不是叉叉说的，反正有人说过&lt;/span&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583664/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583664/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2010/12/banju/feed/</wfw:commentRss><slash:comments>2</slash:comments><description>热度: 友情提示：流水账+小学作文体，观者自重 博客，淫淫，QQ空间、河畔同步发布： http://blog.lilinux.net/2010/12/banju/ http://blog.renren.com/blog/227518150/503674131?isDeclare=false http://user.qzone.qq.com/350134531/blog/1291603433 http://bbs.stuhome.net/read.php?tid=759038&amp;#038;page=e#a “日落西山红霞飞，版友聚餐把清水河归，把清水河归，胸前的红花映彩霞，愉快的歌声满天飞……” 伴随着欢快的歌声，我再一次拍了拍死丢猴[1]的肩膀，和他挥手告别，然后和其它几位版友一起强力插入了公交75路，踏上了回清水河的漫漫归途……这代表了本次版聚[2]的圆满结束，也表明了此次大会后各位版友对继续建设社会主义新农村[3]的殷切希望和满腔热情…… 本次版聚由本版资深酱油会员、本版唯一一位在物理上是MM的阿昏[4]会员策划并组织的，并由新任版主ATI[5]事先预谋、踩点和接头的。主力部队于早上9点在阳光地带集合，大家纷纷核对接头暗号和假装热情套近乎[6]。阿昏、wind[7]、tantjk[8]、lzy[9]在我来之前就已经到了。看到lzy后，我悬着的心就放下来，这次不至于是我一个人战斗，我也不想成天混迹于90后团体之中啊。紧接着，欢哥[10]、sp[11]、杜林[12]、杜林的家属[13]、若离[14]、cosfy[15]也来到了。（本段纯粹为了介绍人物，详情请看注释段） 然后就是去沙河了。在坐车这种无聊的时候，毫无疑问的，阿昏肯定又要炫耀她和她家东哥的长篇系列情景喜剧。大声的交谈似乎让前排的长发MM有点不爽，在我犹豫是否要安静的时候，突然想到了本版叉叉大神[16]曾与我畅谈的猥琐哲学，顿时让我加强了信心，抛开了世俗的偏见，以大无畏的精神继续与阿昏聊着八卦直到下车到沙河。 来到学校的大门着，看到已经变成废墟的工会楼、穿过拥护的南苑小道，遥望着远处不知是否还在的串串西施，我的心里感慨万千：所谓岁月如梭，造化弄人，当年我提着书包在这里左顾右盼之时，为神马就没有这么多美女呢！！来不及感慨太多，就看到了前方站在几个大妈中间的ATI、死丢猴和520[17]. 见到了ATI就是见到了希望，坐了两个小时的公交，我饿得眼睛都要花了，要是它是windows，那肯定早就蓝屏掉了。于是，我们冲进了xx店，二话不说坐上了桌，上了菜就马上开吃。(其实我本来是不太想来参加版聚的，因为上次版聚和这次有点像：也是一上桌就开吃，然后直到吃完，直到散开，都没怎么说话，最后实在不尽兴才去舞版围观了下下，拖鞋党的到来也影响到了舞版的“亲们”的闲情逸致。[18])眼看这次来的版友又是些猥琐不达标但闷骚过度的技术男们，担心重蹈覆辙，我连忙派阿昏过去一个一个敬酒。阿昏回来我再过去，然后是欢哥和ATI的轮番转圈。这样果然有效果多了，几杯酒下肚，气氛就起来了，大家开始有一句没一句的聊着，有的人开始勾肩搭背（我），有的人开始大声吆喝（欢哥），有的人开始基情四射（ATI和若离）…… 于是大会就算是开始了，首先由我做了个离职报告，因为过于装B，没什么人听。然后大家促膝长谈，讲到Linux作为我们无产阶级劳动人民自己的操作系统，应该如何又好又快发展的问题时。 有版友提到：以前用windows的时候受苦受难，windows作为被大资本家、大买办操纵的操作系统，它的本质是压榨劳动人民的血汗，还不能提供优质的服务，脆弱、闭源、反盗版是压在人民群众头上的三座大山，如今有了Linux，过去所有的苦难终于结束了，终端用户终于翻身做主人了，Linux是咱们技术仔自个儿的操作系统。 另外一位老版友语重心长的说道：发展Linux的核心思想是以用户为本，主要措施是还政于用户，要大力发扬开源社区的热爱社区、无私奉献精神，发扬Linus同志的K.I.S.S重要思想，团结在以清水渔翁同志为版主的版中央，努力建设一个资源节约型、MM友好型的社区新面貌。 我说：三天不学习，赶不上小若离啊。今天与会的同志都是信奉开源主义的技术仔。开源主义向来有着艰苦奋斗、团结互助的优良传统，若离MM在工作岗位上兢兢业业，不图回报，身兼多版版主，仍然不忘提升自己的业务水平，是非常值得我们在座的各位以及全版乃至全坛学习滴。 (会议在欢乐祥和的气氛中进行) 在大会结束之时，大家举杯共祝：清水渔翁万寿无疆，万寿无疆，ATI哥永远健康，永远健康 。然后由我最后一次执行版主权力，宣布在各级政府和机关的大力配合下，本次大会取得了圆成功。[19] 因为喝了太多酒，还有具体细节我基本记不清了。欢哥也喝多了酒，于是才有了后面他和神曲[20]互相产生强烈共鸣的场景。 吃了饭，喝了酒，扯了蛋，每个人都变得豪情万丈起来，由阿昏提议，大家前往某KTV参加歌颂祖国、歌颂本版的歌咏比赛。可惜的是，由于惧内等因素，新任版主ATI未能前往。 在前往东苑某KTV的路上，阿昏偷拍了不少照片，因为刚喝完酒，大家表情比较扭曲。当然，这不表示我们赤诚的心哪怕有一点一毫的减弱。看到曝PP后某些群嘲的回复，我在此表示强烈谴责。[21] 到了KTV，发现问题来了：有四分之三以上的版友基本不会唱歌的。这样的比例还是灰常吓人的。经过一番诱导和拐骗，才把场子架起来。（值得注意的是，整个下午，点歌单都没有超过1页）我作为前朝版主，为了给大家留个好印象，立马点了个《北京一夜》开嗓，结果一首没完就把嗓子吼破了。刚开始唱的几首歌典型的KTV常点的那种哀怨婉转，在我看来，这太不符合无产阶级闹革命的情怀。于是提议点一些“忠党爱国”和“农业重金属”等类型的歌。杜林及其家属含着泪水唱完了一曲《国际歌》，lzy深情地唱了几首细腻的情歌，520、wind、tantj和cosfy也都唱了一些经典曲目，号称从不开口的若离和声若蚊吟的死丢猴也硬着头皮唱了几句。倒是sp没有唱，据阿昏说是在用手机写代码。 等到了“农业重金属”时，欢哥突然转职加狂暴了[22]。一曲铿锵有力的神曲《爱情买卖》下来，使得吾等皆肝胆俱裂、神游太虚。在意犹未尽之时，欢哥的一曲《我和草原有个约会》更是把全场带进了空灵的大草原，观者皆唏嘘不已，不能自拔。阿昏借故偷拍数张PP，录音无数。之后，我与欢哥合唱了公交车手机铃声排行榜第一位的《月亮之上》，不由得被曲调当中诡异莫测的爱恨情仇与悲观离合所感染，其它版友也是观者伤心，闻者掉泪。众版友对欢哥之前的豪饮与现在的纵歌都非常钦佩。 时间还是过得很快滴，没过多久。我们就离开了沙河。 看着夜幕降临，华灯初上。我的耳边仿佛又听到叉叉斩钉截铁的话：li哥，总有一天我们不会是非主流的[23] 注释： [1] 死丢猴，ID为“stuhom”，其马甲ID为“与稀离人”，也叫“离人”。因为过于闷骚，使其长期混迹本版仍然不够猥琐（最气人的是，长得还有点小帅）。即将供职于某高薪企业。 [2] 本次版聚，事件发生在2010年12月04日，有14个人参加，年级跨度为大二到研三。本次版聚突破了以往版聚“见面吃饭走人不说话”的传统，并制订了“人不猥琐枉少年”等一系列符合社会主义主流价值观的版内基调。 [3] 清水河隶属高新西区与豆瓣县之间，历来是三不管区域。在成电人“上山下乡”来到这里之后，发扬“农业学川农，工业学成理”，使得清水河旧貌换新颜。每当喜庆节日，清水河居民载歌载舞，自发的走上顺江街头……………… [4] 阿昏，性别女，性别男。ID为“之行”，马甲无数。江湖人称“行哥”。虽然悍勇无双，却自称为“技术仔控”，并成功attach上技术仔东哥。 [5] ATI，本版新任版主，ID为“ati955012m”。风流潇洒，重情重义。来自英才班，将师从院士。曾觊觎版主位多时，后来靠实际行动争取到。 [6] 假装热情是因为都比较腼腆。比起大家，我可以算得上流氓了。 [7] wind, ID为“uestc_wind”，是一朵乐于助人、热情奔放的男子。要本版会员油条化的大趋势下，他仍然保持冷静，细心地帮助别人。 [8] tantjk，ID就是”tantjk“。因为ID不知道怎么念，我一般都叫”tjj“。本版资深老会员之一，比死丢猴还腼腆，比较少灌水。 [9] lzy，ID为”lzy0001sl”，和我是同一级，也不怎么灌水，发帖都是帮助别人。作为北方汉子却有一副细腻的好嗓音。 [10] 欢哥，ID为“清水渔翁”，也叫“欢神”、“欢婶”、“清水MM”、“菜刀大哥”、“清水[哔][哔]”。高大威猛，技术强硬，因为受到booooss哥的高度评价而迈上了一个新的高度。 [11] sp, ID为“sp55aa”，计算机学院的大神，行事低调。但在阿昏曝PP后，仍然被广大网友一眼认出，可见其影响力。 [12] 杜林，ID为“杜林”，大二的小抵迪，非常喜欢美女。从猥琐这个层面上讲，他已经超出了很多前辈，可以在本版排上字号 [13] 杜林的家属，ID为“杜林的家属”，也是大二的。与杜林成双入对，形影不离，比较文静。留着漂亮的小胡子。对了，他是男生 [...]&lt;img src=&quot;http://www1.feedsky.com/t1/511583664/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583664/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>猥琐</category><category>版聚</category><category>随便扯扯</category><pubDate>Mon, 06 Dec 2010 10:45:42 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2010/12/banju/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=452</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2010/12/banju/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583664/6171942</fs:itemid></item><item><title>[转帖]Python语言与设计模式</title><link>http://item.feedsky.com/~feedsky/lilinux/~8065490/511583665/6171942/1/item.html</link><content:encoded>&lt;table&gt;
&lt;tr cellpadding=0&gt;&lt;td&gt;热度:&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;td cellpadding=0&gt;&lt;img src='http://blog.lilinux.net/wp-content/plugins/statpresscn/images/sun_dark.gif' width=10 height=10 border=0 /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;p&gt;来自：&lt;a href=&quot;http://blog.csdn.net/bobseadream/archive/2010/02/01/5278950.aspx&quot;&gt;http://blog.csdn.net/bobseadream/archive/2010/02/01/5278950.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;more-444&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;设计模式是一个抽象层次，描述了在一个特定的环境中用来解决一般设计问题的对象和类之间的交互关系，其主要目的是充分利用语言的特性，设计可复用的、能够适应需求变更的软件[9]。设计模式是一种设计思想，语言是实现思想的工具。因此，不同语言的特性影响了设计模式的实现，有些语言更容易实现设计模式，而有些语言则比较难。GoF在设计模式一书中选用了两种面向对象语言—C++和Smalltalk实现软件开发中常用的23种设计模式，其中C++ 为主，Smalltalk为辅，重点突出了两种语言不同的语言特性对实现设计模式的影响。C++语言的运行时多态性的基础是虚函数机制，指向基类的指针可以指向它的任何派生类，在实现设计模式时充分利用了C++这一特性，结合继承机制，建立类和对象的层次关系，使C++最大程度的具有动态特性，将绑定关系尽可能推迟到运行时确定。&lt;/p&gt;
&lt;p&gt;在GoF的23种模式中，部分设计模式是专门为静态语言提出的，有些模式在动态语言中语言一级就提供直接的支持，如Command模式，动态语言提供的函数式编程将函数本身看作是类对象。&lt;/p&gt;
&lt;p&gt;Python 是一种完全面向对象的动态语言，提供了与传统面向对象语言截然不同的对象模型，影响了设计模式的实现和使用。Python中类也是对象，类和类的对象都有可供操作的特殊属性，在运行时还可以修改类的结构和定义，这些特性使Python具有强大的“内省”能力，利用这种能力程序员可以创建高级的、动态的和灵活的应用程序，可以更容易实现设计模式。本部分选取了几种常见的设计模式，尝试用Python语言实现，并与C++的实现方式进行比较，进一步体现动态语言中的“动态性”及其具体应用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5.1 抽象工厂（Abstract Factory）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;抽象工厂模式提供了一个不需要指定具体类就可以创建一系列相互关联或相互依赖的对象的接口。抽象工厂隔离了具体类，客户代码只需通过抽象接口创建对象，不需要访问具体的类。参考GoF的设计模式一书，对书中实现迷宫工厂的C++代码用Python实现如下：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code20'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44420&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code20&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; MazeFactory:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; MakeMaze&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; Maze&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; MakeWall&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; Wall&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; MakeRoom&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, n&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; Room&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;n&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; MakeDoor&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, r1, r2&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; Door&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;r1, r2&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;上述代码定义了一个可以创建Maze、Wall、Room和Door的MazeFactory接口，接下来创建一个魔法迷宫工厂 EnchantedFactory,EnchantedFactory继承于MazeFactory，并通过MakeRoom和MakeDoor接口创建了具有富有个性的EnchantedRoom和EnchantedDoor。&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code21'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44421&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code21&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; EnchantedFactory&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;MazeFactory&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; MakeRoom&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, n&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; EnchantedRoom&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;n&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; MakeDoor&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, r1, r2&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; EnchantedDoor&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;r1, r2&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;这段代码只是对C++代码的简单翻译，没有运用Python的语言特色。从上述的代码中可以看出，抽象工厂难以向MazeFactory中添加新的产品，假如迷宫中还需要创建陷阱（Trap），就必须在MazeFactory接口中增加MakeTrap方法，这样就造成了MazeFactory接口的不稳定，继承MazeFactory的所有子类的接口也随着基类的接口改变而改变。&lt;/p&gt;
&lt;p&gt;工厂方法（Factory Method）解决了通过引入一个的Make操作将创建所有产品类型的操作统一化，Make操作中有一个参数可以唯一标识创建对象的类型。然而，用C++ 语言实现的工厂方法仍然存在局限性，这种局限性不利于构建可复用的软件。因为创建所有的产品类型都是通过Make接口的，为了保持Make接口的返回值对所有产品的兼容性，就不得不迫使所有产品类型必须继承于一个公共的基类，然后Make接口返回该基类，这样保证了Make返回的类型都可以转换成特定的产品类型。但是，同一系列不同类型的产品在逻辑上可能不存在明确的公共基类，比如MazeFactory中的Maze和Wall，而且，使用公共基类导致了大量的向下强制转换，这种转换往往是不安全的，有时还不可行。[9]Pyhon语言的动态类型特性为解决该问题提供良好的方案，Python允许一个变量在运行时绑定到不同类型的对象上，所以不必要求不同类型的产品具有公共基类，Make接口不必声明其返回类型，调用时具体的返回值类型在运行时交给解释器去完成。Python实现工厂方法的代码如下：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code22'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44422&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code22&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; Maze:…
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; Wall:…
…
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; MazeFactory&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; make&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, typename, &lt;span style=&quot;color: #66cc66;&quot;&gt;*&lt;/span&gt;args&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
         &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;if&lt;/span&gt; typename == &lt;span style=&quot;color: #483d8b;&quot;&gt;'maze'&lt;/span&gt;: &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; Maze&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
         &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;elif&lt;/span&gt; typename == &lt;span style=&quot;color: #483d8b;&quot;&gt;'wall'&lt;/span&gt;: &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; Wall&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
         &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;elif&lt;/span&gt; typename == &lt;span style=&quot;color: #483d8b;&quot;&gt;'room'&lt;/span&gt;:
               &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; Room&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;args&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
         &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;elif&lt;/span&gt; typename == &lt;span style=&quot;color: #483d8b;&quot;&gt;'door'&lt;/span&gt;: &lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
               &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; Door&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;args&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;, args&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;self是MazeFactory实例对象的引用参数，typename标识创建对象的类型，*args是创建具体对象时所需的参数列表。魔法迷宫的代码:&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code23'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44423&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code23&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; EnchantedFactory&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;MazeFactory&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; make&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, typename, &lt;span style=&quot;color: #66cc66;&quot;&gt;*&lt;/span&gt;args&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;if&lt;/span&gt; typename == &lt;span style=&quot;color: #483d8b;&quot;&gt;'room'&lt;/span&gt;: &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; EnchantedRoom&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;args&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;elif&lt;/span&gt; typename == &lt;span style=&quot;color: #483d8b;&quot;&gt;'door'&lt;/span&gt;: &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; EnchantedDoor&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;args&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;,args&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;else&lt;/span&gt;: &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;EnchantedFactory, &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;make&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;typename, args&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;make方法中的return super(EnchantedFactory, self).make(typename, args)表示调用父类的操作创建其它类型的对象。&lt;/p&gt;
&lt;p&gt;那么创建一个具体的EnchantedFactory实例的代码：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code24'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44424&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code24&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;mf = EnchantedFactory&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
mz = mf.&lt;span style=&quot;color: black;&quot;&gt;make&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'maze'&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
r1 = mf.&lt;span style=&quot;color: black;&quot;&gt;make&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'room'&lt;/span&gt;, &lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
r2 = mf.&lt;span style=&quot;color: black;&quot;&gt;make&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'room'&lt;/span&gt;, &lt;span style=&quot;color: #ff4500;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
dr = mf.&lt;span style=&quot;color: black;&quot;&gt;make&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'door'&lt;/span&gt;, r1, r2&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;当需要在MazeFactory添加一个Trap新类型时，只需要在Make方法中添加标示新类型的参数即可：&lt;/p&gt;
&lt;p&gt;elif typename == “trap”: return Trap()&lt;/p&gt;
&lt;p&gt;这种做法不但保持了MazeFactory对外接口的稳定性，而且不需要类型的向下转换。但这里同样存在一个问题：每添加一个新类型，都要修改Make的实现代码。能不能不用修改Make的代码即可添加一个新类型呢？原型模式（Prototype）提供了一种更好的解决方案——编制产品字典。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5.2 原型模式（Prototype）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;原型模式使用一个原型实例指定创建对象的类型，并且通过复制原型创建新的对象。原型模式的优点是可以在运行时动态的增加和删除产品类型，减少了子类化，还可以动态的配置应用程序。使用原型管理器（Prototype Manager）可以方便实现运行时类型的增加和删除，管理器中有个类型的注册表，注册表是个关联存储结构的表，对于给定类型的键值可以唯一确定一个类型，增加一个新类型时就是在表中注册该类型，客户程序在使用一个类型前先访问注册表检索它的原型。实现迷宫MazeFactory原型的Python代码如下：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code25'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44425&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code25&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; MazeFactory:
   &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000cd;&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;index&lt;/span&gt; = &lt;span style=&quot;color: black;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'maze'&lt;/span&gt;: Maze,
                      &lt;span style=&quot;color: #483d8b;&quot;&gt;'wall'&lt;/span&gt;: Wall,
                      &lt;span style=&quot;color: #483d8b;&quot;&gt;'room'&lt;/span&gt;: Room,
                      &lt;span style=&quot;color: #483d8b;&quot;&gt;'door'&lt;/span&gt;: Door&lt;span style=&quot;color: black;&quot;&gt;&amp;#125;&lt;/span&gt;
   &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; make&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, typename, &lt;span style=&quot;color: #66cc66;&quot;&gt;*&lt;/span&gt;args&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
      &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; apply&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;typename&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;, args&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
   &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; registtype&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, typename, instance&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
      &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;typename&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt; = instance
   &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; unregisttype&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, typename&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
      &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;del&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;typename&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;在 MazeFactory中，数据成员self.index={…}是个字典类型，存放MazeFactory产品类型，方法registtype和 unregisttype实现了产品类型的动态增加和删除，参数instance表示需要添加或删除类型的实例名。假如创建了一个MazeFactory 实例mf=MazeFactory()，实例Trap的定义如下：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code26'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44426&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code26&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; Trap:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000cd;&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, radius, height&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
       &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;radius&lt;/span&gt; = radius
       &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;height&lt;/span&gt; = height
    …&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;向mf中添加实例Trap的代码：mf.registtype(‘trap’,Trap)，而相应的删除代码为mf.unregisttype(‘trap’,Trap)。&lt;/p&gt;
&lt;p&gt;显然，这种实现方式便于动态管理类型，具有良好的可扩展性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5.3 单件模式（Singleton）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;单件模式提供了一种将系统中类的实例个数限制为一个的机制，保证了一个类只有一个实例，并提供了该实例的一个全局访问点。程序的不同模块通常会共享同一个对象。单件模式隐藏了实际的全局变量，对外提供了访问的接口，是一种很好的访问全局变量的方法。首先我们来看一下C++是怎样实现单件模式的。 Singleton类的定义如下：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code27'); return false;&quot;&gt;View Code&lt;/a&gt; C&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44427&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code27&quot;&gt;&lt;pre class=&quot;c&quot; style=&quot;font-family:monospace;&quot;&gt;class Singleton &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
public&lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt;
    &lt;span style=&quot;color: #993333;&quot;&gt;static&lt;/span&gt; Singleton&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; Instance&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
protected&lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt;
    Singleton&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
private&lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt;
    &lt;span style=&quot;color: #993333;&quot;&gt;static&lt;/span&gt; Singleton&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; _instance&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; 
&amp;nbsp;
&lt;span style=&quot;color: #666666; font-style: italic;&quot;&gt;//对应的实现：&lt;/span&gt;
Singleton&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; Singleton&lt;span style=&quot;color: #339933;&quot;&gt;::&lt;/span&gt;_instance &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
Singleton&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; Singleton&lt;span style=&quot;color: #339933;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #202020;&quot;&gt;Instance&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;_instance &lt;span style=&quot;color: #339933;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
        _instance &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; new Singleton&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; _instance&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;在单件类中，静态数据成员_instance指向已经创建的实例，静态成员函数Instance()为单件类提供了全局访问点，客户程序只能通过 Instance()接口创建单件类，如果_instance不为0，则直接返回已创建的实例，注意Singleton类的构造函数声明为 protected属性防止客户程序不通过Instance()接口创建它，保证了单件类的唯一性。&lt;/p&gt;
&lt;p&gt;Python语言中的类和函数的定义可以在运行时改变，借助这一语言特性给出实现Singleton模式Python版本：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code28'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44428&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code28&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; Singleton&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
   &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000cd;&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;cls&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
      cls.&lt;span style=&quot;color: black;&quot;&gt;instance&lt;/span&gt; = &lt;span style=&quot;color: #008000;&quot;&gt;object&lt;/span&gt;.&lt;span style=&quot;color: #0000cd;&quot;&gt;__new__&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;cls&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
      cls.&lt;span style=&quot;color: #0000cd;&quot;&gt;__new__&lt;/span&gt; = cls.&lt;span style=&quot;color: black;&quot;&gt;Instance&lt;/span&gt;
      cls.&lt;span style=&quot;color: black;&quot;&gt;instance&lt;/span&gt;.&lt;span style=&quot;color: black;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
      &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; cls.&lt;span style=&quot;color: black;&quot;&gt;instance&lt;/span&gt;
   &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; Instance&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;cls,&lt;span style=&quot;color: #008000;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
      &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; cls.&lt;span style=&quot;color: black;&quot;&gt;instance&lt;/span&gt;
   Instance = &lt;span style=&quot;color: #008000;&quot;&gt;classmethod&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;Instance&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
   &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; init&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
       &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;pass&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Singleton 类重载了object的内置方法__new__，object是Python中所有数据类型的基类，包括内置数据类型和用户自定义类型，所有的数据类型都继承了object的属性和方法。在Python中，类方法和静态方法是两个不同的概念。类的静态方法相当于C++中的静态成员函数，调用方式也类似。而类方法隐式地将类本身作为第一个参数，在声明和调用的格式方面与静态方法都不同。而__new__方法是类的一个静态方法，不是一个类方法，它在调用类的初始化方法__init__之前调用，创建对象的第一步就是调用__new__方法。__new__方法的第一个参数必须是一个类，并返回该类的一个新的实例，其余的参数是调用__init__所需的参数。[11] getInstance是Singleton类的类方法，定义了Singleton实例的全局访问点。在重载的__new__方法中，首先调用了父类 object的__new__方法返回一个新的Singleton的实例cls.instance，参数cls实际是对Singleton类本省的引用，instance是类的一个数据成员，保存了当前的单件对象。语句：&lt;br /&gt;
cls.__new__ = cls.getInstance是将getInstance赋给__new__方法，执行后，Singleton类的__new__方法变成了 getInstance。第一次创建Singleton实例对象时，调用__new__方法生成Singleton的一个新的实例，试图再次创建 Singleton实例对象时，调用的__new__的方法实际上被“偷偷的“调包成getInstance,__new__方法的代码不再被执行，而是执行getInstance方法返回已经创建的实例对象cls.instance，从而保证了只存在一个Singleton实例对象。 cls.instance.init()说明了__new__方法在__init__之前调用，为了进一步初始化Singleton子类。&lt;/p&gt;
&lt;p&gt;Singleton的子类继承了Singleton的__new__方法，每个子类也是单件的，只能有一个实例对象，无论调用多少次构造函数，子类重载了init方法，例如：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code29'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44429&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code29&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; MySingleton&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;Singleton&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; init&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;&amp;quot;call init...&amp;quot;&lt;/span&gt;
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000cd;&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;&amp;quot;call __init__...&amp;quot;&lt;/span&gt;
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;&amp;quot;Initilizing My singleton&amp;quot;&lt;/span&gt; 
&amp;nbsp;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&lt;/span&gt; a = MySingleton&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;       &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#创建一个新的MySingleton实例对象&lt;/span&gt;
call init...                &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#调用父类Singleton的__new__方法&lt;/span&gt;
call &lt;span style=&quot;color: #0000cd;&quot;&gt;__init__&lt;/span&gt;...            &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#调用自己的__init__方法&lt;/span&gt;
Initilizing My singleton
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&lt;/span&gt; b = MySingleton&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;        &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#试图再创建一个MySingleton对象&lt;/span&gt;
call &lt;span style=&quot;color: #0000cd;&quot;&gt;__init__&lt;/span&gt;...             &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#没有调用__init__方法，说明__new__被“调包”&lt;/span&gt;
Initilizing My singleton
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #66cc66;&quot;&gt;;&lt;/span&gt; a == b                    &lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#a和b实际上指向同一个实例对象&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;True&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;在 C++中子类化Singleton相对比较麻烦，不能直接继承Singleton将子类定义为单件类，有三种方法创建Singleton的子类：在 Singleton的Instance操作中设置一个参数指定需要创建的单件；将Instance操作从父类分离到它的各个子类中；使用单件注册表。这些方法都可以子类化单件类，但没有Python版本来得直观。Python中利用了在运行时可以改变类定义的动态特性，&lt;/p&gt;
&lt;p&gt;在运行时将自身的静态方法 __new__改成另外一个方法getInstance，这种“偷梁换柱”的做法确实为某些应用带来了便利。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5.4 代理模式（Proxy）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;从面向对象设计的角度看，限制访问属性给一些旧问题提供了一种新的解决办法。代理模式就是一个很好的例子。代理模式用于隔离对象和访问它的客户，比如引用计数、不同等级的授权访问以及对象的惰性赋值等。代理模式的结构如下：&lt;/p&gt;
&lt;p&gt;客户程序不需要直接访问实际的对象，换句话说，代理替代了实际的对象，客户通过代理去访问实际的对象。在C++中，这就意味着Proxy和 RealSubject必须要有一个公共的基类。在Python中，通过提供相同的方法接口，Proxy可以达到冒充Subject的效果。以下 Python代码中Proxy类是基于小型的通用包装类，它的主要功能就是为多个特定代理的实现提供一个基类，在Proxy类中可以重载 __gettattr__方法处理不同的方法。&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code30'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44430&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code30&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#Proxy Base Class&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; Proxy:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000cd;&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, subject &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.__subject = subject
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000cd;&quot;&gt;__getattr__&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, name &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;getattr&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.__subject, name &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#Subject class&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; RGB:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #0000cd;&quot;&gt;__init__&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;, red, green, blue &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.__red = red
        &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.__green = green
        &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.__blue = blue
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; Red&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.__red
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; Green&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.__green
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; Blue&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;.__blue
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;# More specific proxy implementation&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; NoBlueProxy&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; Proxy &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; Blue&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;考虑以下情况：首先我们需要直接访问RGB类的实例对象，然后使用一个通用的代理实例作为一个包装类，最后传递给NoBlueProxy类:&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code31'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44431&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code31&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; rgb = RGB&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span style=&quot;color: #ff4500;&quot;&gt;100&lt;/span&gt;, &lt;span style=&quot;color: #ff4500;&quot;&gt;192&lt;/span&gt;, &lt;span style=&quot;color: #ff4500;&quot;&gt;240&lt;/span&gt; &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; 
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; rgb.&lt;span style=&quot;color: black;&quot;&gt;Red&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; 
&lt;span style=&quot;color: #ff4500;&quot;&gt;100&lt;/span&gt; 
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; proxy = Proxy&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; rgb &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; 
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; proxy.&lt;span style=&quot;color: black;&quot;&gt;Green&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; 
&lt;span style=&quot;color: #ff4500;&quot;&gt;192&lt;/span&gt; 
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; noblue = NoBlueProxy&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt; rgb &lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; 
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; noblue.&lt;span style=&quot;color: black;&quot;&gt;Green&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; 
&lt;span style=&quot;color: #ff4500;&quot;&gt;192&lt;/span&gt; 
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; noblue.&lt;span style=&quot;color: black;&quot;&gt;Blue&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt; 
&lt;span style=&quot;color: #ff4500;&quot;&gt;0&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;代理模式在Python中应用很广泛，Python语言提供的机制中有一些就是代理模式实现的，比如垃圾收集中的简单引用计数。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5.5命令模式（Command）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;用过集成开发环境的人都知道，开发基于窗口图形界面的应用程序时，一般要用到按钮和菜单等控件对象响应用户的输入，但在集成环境的工具箱提供的按钮和菜单并没有显式地实现该请求，也就是按钮和菜单不知道关于请求的操作和请求的接受者的任何信息，这些请求特定于具体应用，只用控件的使用者才知道该由哪个对象响应哪个操作，工具箱的设计者无法知道请求的接受者和执行的操作。那么工具箱的设计者是如何实现按钮和菜单的这种功能的呢？用Command模式。&lt;br /&gt;
Command 模式解耦了调用操作的对象（如按钮、菜单）和实现该操作的对象（如文档）。C++利用继承组合机制实现Command模式，通过定义一个带有 Execute接口的Command抽象类，特定应用相关的Command派生于此类，在Command类的子类显式定义接受者的对象。Command类在调用操作的对象(Invoker)和实现该操作的对象（Receiver）之间充当了桥梁作用， Invoker请求某个Command类，由Command类的Execute接口执行Receiver的具体操作并将返回结果告诉Invoker，对于 Invoker根本不知道是谁执行了该操作，也不需要知道，从而实现了两者的解耦。而Python具有运行时可以改变类的结构、函数的定义的动态特性，很简单地就实现了Command模式：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code32'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44432&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code32&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; Button:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; click&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;pass&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;class&lt;/span&gt; document:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;&amp;quot;open document...&amp;quot;&lt;/span&gt;
btn = Button&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
doc = document&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
btn.&lt;span style=&quot;color: black;&quot;&gt;click&lt;/span&gt; = doc.&lt;span style=&quot;color: #008000;&quot;&gt;open&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;执行btn.click()时实际上相当于调用了doc.open()的方法，实现了Button和document两者的解耦，比C++的继承组合机制要简单。&lt;br /&gt;
有时一个按钮要求执行一系列命令，这种宏命令（MacroCommand）在应用中也是很常见的。Python支持lamda匿名函数定义，运用函数式编程方式也可以很简便的实现MacroCommand模式。我们先来看看用C++是怎样实现的。C++用一个命令列表管理命令系列，执行宏命令实际上是遍历一次命令列表：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code33'); return false;&quot;&gt;View Code&lt;/a&gt; C&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44433&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code33&quot;&gt;&lt;pre class=&quot;c&quot; style=&quot;font-family:monospace;&quot;&gt;class Command &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
public&lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt;
    virtual ~Command&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
    virtual &lt;span style=&quot;color: #993333;&quot;&gt;void&lt;/span&gt; Execute&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #0000dd;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
protected&lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt;
    Command&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
class MacroCommand &lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt; public Command &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
public&lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt;
    MacroCommand&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
    virtual ~MacroCommand&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
    virtual &lt;span style=&quot;color: #993333;&quot;&gt;void&lt;/span&gt; Add&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;Command&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
    virtual &lt;span style=&quot;color: #993333;&quot;&gt;void&lt;/span&gt; Remove&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;Command&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
    virtual &lt;span style=&quot;color: #993333;&quot;&gt;void&lt;/span&gt; Execute&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
private&lt;span style=&quot;color: #339933;&quot;&gt;:&lt;/span&gt;
    List&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; _cmds&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #666666; font-style: italic;&quot;&gt;//命令列表&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #993333;&quot;&gt;void&lt;/span&gt; MacroCommand&lt;span style=&quot;color: #339933;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #202020;&quot;&gt;Execute&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
    ListIterator i&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;_cmds&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;span style=&quot;color: #b1b100;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;i.&lt;span style=&quot;color: #202020;&quot;&gt;First&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #339933;&quot;&gt;!&lt;/span&gt;i.&lt;span style=&quot;color: #202020;&quot;&gt;IsDone&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt; i.&lt;span style=&quot;color: #202020;&quot;&gt;Next&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span style=&quot;color: #666666; font-style: italic;&quot;&gt;//遍历命令列表&lt;/span&gt;
    &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#123;&lt;/span&gt;
        Command&lt;span style=&quot;color: #339933;&quot;&gt;*&lt;/span&gt; c &lt;span style=&quot;color: #339933;&quot;&gt;=&lt;/span&gt; i.&lt;span style=&quot;color: #202020;&quot;&gt;CurrentItem&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
        c&lt;span style=&quot;color: #339933;&quot;&gt;-&amp;amp;&lt;/span&gt;gt&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;Execute&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #339933;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #009900;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;在Python中，假设已经定义了一个Button类和一个Document类，Button类有一个Click方法，Document包含Paste和Replace方法，以下代码实现了点击按钮后同时执行Paste和Replace操作：&lt;/p&gt;

&lt;div class=&quot;wp_codebox_msgheader&quot;&gt;&lt;span class=&quot;right&quot;&gt;&lt;sup&gt;&lt;a href=&quot;http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples&quot; target=&quot;_blank&quot; title=&quot;WP-CodeBox HowTo?&quot;&gt;&lt;span style=&quot;color: #99cc00&quot;&gt;?&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;left&quot;&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;javascript:showCodeTxt('p444code34'); return false;&quot;&gt;View Code&lt;/a&gt; PYTHON&lt;/span&gt;&lt;div class=&quot;codebox_clear&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;wp_codebox&quot;&gt;&lt;table&gt;&lt;tr id=&quot;p44434&quot;&gt;&lt;td class=&quot;code&quot; id=&quot;p444code34&quot;&gt;&lt;pre class=&quot;python&quot; style=&quot;font-family:monospace;&quot;&gt;doc = Document&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
btn = Button&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
macrcocmd = &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;lambda&lt;/span&gt; cmds : &lt;span style=&quot;color: #008000;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;lambda&lt;/span&gt; &lt;span style=&quot;color: #dc143c;&quot;&gt;cmd&lt;/span&gt;：&lt;span style=&quot;color: #dc143c;&quot;&gt;cmd&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;,cmds&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
btn.&lt;span style=&quot;color: black;&quot;&gt;Click&lt;/span&gt; = &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;lambda&lt;/span&gt;: macrcocmd&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;doc.&lt;span style=&quot;color: black;&quot;&gt;Paste&lt;/span&gt;, doc.&lt;span style=&quot;color: black;&quot;&gt;Replace&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;  函数map是个Python内置函数，其作用是将列表cmds作为参数传递给匿名函数lambda cmd : cmd()执行并返回一个元组作为匿名函数macrocmd的参数，调用btn.Click（）执行了匿名函数macrocmd()，该函数接受元组 [doc.Paste, doc.Replace] 作为它的输入参数，执行doc.Paste()和doc.Replace()命令。 &lt;/p&gt;
&lt;p&gt;    以上我们只选取了GoF的23种模式的5种模式，展示了如何利用Python语言的动态特性实现设计模式。Python的灵活性和动态性为实现一些不同的、优美的解决方案提供了一个良好的基础。Python的无类型化解决了静态语言实现工厂方法中需要不安全的强制类型转换等问题，既减少了程序中类的设计，又避免了静态语言中的向下转换问题。原型模式为创建不同类型的对象提供一种更好的方法，利用了Python 可以运行时改变类的定义的特性，可以动态地增删类型，提高了程序的可扩展性。而单件模式则利用了类的静态方法__new__以及动态改变类的结构和定义的特点，巧妙地实现了限制了单件类的实例对象个数的功能。在Proxy模式中，充分体现了Python中同一个类的多个实例对象之间可以拥有不同的结构以及可以监视和限制属性访问的语言机制，这些机制为个实现多个通用类提供了一个相当完美的解决方法。在C++中不支持匿名函数，命令模式初步展现了 Python中lamda匿名函数在实现某些问题的简便性。其他的模式，如职责链（Chain Of Responsibility）、策略模式（Strategy）、装饰模式（Decorator），利用Python语言特性，也可以写出Python的实现版本。&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/511583665/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583665/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://blog.lilinux.net/2010/11/python-design-pattern/feed/</wfw:commentRss><slash:comments>2</slash:comments><description>热度: 来自：http://blog.csdn.net/bobseadream/archive/2010/02/01/5278950.aspx 设计模式是一个抽象层次，描述了在一个特定的环境中用来解决一般设计问题的对象和类之间的交互关系，其主要目的是充分利用语言的特性，设计可复用的、能够适应需求变更的软件[9]。设计模式是一种设计思想，语言是实现思想的工具。因此，不同语言的特性影响了设计模式的实现，有些语言更容易实现设计模式，而有些语言则比较难。GoF在设计模式一书中选用了两种面向对象语言—C++和Smalltalk实现软件开发中常用的23种设计模式，其中C++ 为主，Smalltalk为辅，重点突出了两种语言不同的语言特性对实现设计模式的影响。C++语言的运行时多态性的基础是虚函数机制，指向基类的指针可以指向它的任何派生类，在实现设计模式时充分利用了C++这一特性，结合继承机制，建立类和对象的层次关系，使C++最大程度的具有动态特性，将绑定关系尽可能推迟到运行时确定。 在GoF的23种模式中，部分设计模式是专门为静态语言提出的，有些模式在动态语言中语言一级就提供直接的支持，如Command模式，动态语言提供的函数式编程将函数本身看作是类对象。 Python 是一种完全面向对象的动态语言，提供了与传统面向对象语言截然不同的对象模型，影响了设计模式的实现和使用。Python中类也是对象，类和类的对象都有可供操作的特殊属性，在运行时还可以修改类的结构和定义，这些特性使Python具有强大的“内省”能力，利用这种能力程序员可以创建高级的、动态的和灵活的应用程序，可以更容易实现设计模式。本部分选取了几种常见的设计模式，尝试用Python语言实现，并与C++的实现方式进行比较，进一步体现动态语言中的“动态性”及其具体应用。 5.1 抽象工厂（Abstract Factory） 抽象工厂模式提供了一个不需要指定具体类就可以创建一系列相互关联或相互依赖的对象的接口。抽象工厂隔离了具体类，客户代码只需通过抽象接口创建对象，不需要访问具体的类。参考GoF的设计模式一书，对书中实现迷宫工厂的C++代码用Python实现如下： ?View Code PYTHONclass MazeFactory: def MakeMaze&amp;#40;self&amp;#41;: return Maze&amp;#40;&amp;#41; def MakeWall&amp;#40;self&amp;#41;: return Wall&amp;#40;&amp;#41; def MakeRoom&amp;#40;self, n&amp;#41;: return Room&amp;#40;n&amp;#41; def MakeDoor&amp;#40;self, r1, r2&amp;#41;: return Door&amp;#40;r1, r2&amp;#41; 上述代码定义了一个可以创建Maze、Wall、Room和Door的MazeFactory接口，接下来创建一个魔法迷宫工厂 EnchantedFactory,EnchantedFactory继承于MazeFactory，并通过MakeRoom和MakeDoor接口创建了具有富有个性的EnchantedRoom和EnchantedDoor。 ?View Code PYTHONclass EnchantedFactory&amp;#40;MazeFactory&amp;#41;: def MakeRoom&amp;#40;self, n&amp;#41;: return EnchantedRoom&amp;#40;n&amp;#41; def MakeDoor&amp;#40;self, r1, r2&amp;#41;: return EnchantedDoor&amp;#40;r1, r2&amp;#41; 这段代码只是对C++代码的简单翻译，没有运用Python的语言特色。从上述的代码中可以看出，抽象工厂难以向MazeFactory中添加新的产品，假如迷宫中还需要创建陷阱（Trap），就必须在MazeFactory接口中增加MakeTrap方法，这样就造成了MazeFactory接口的不稳定，继承MazeFactory的所有子类的接口也随着基类的接口改变而改变。 工厂方法（Factory [...]&lt;img src=&quot;http://www1.feedsky.com/t1/511583665/lilinux/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/lilinux/~8065490/511583665/6171942/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>设计模式</category><category>Code</category><category>Python</category><pubDate>Mon, 15 Nov 2010 22:23:37 +0800</pubDate><author>Li哥</author><comments>http://blog.lilinux.net/2010/11/python-design-pattern/#comments</comments><guid isPermaLink="false">http://blog.lilinux.net/?p=444</guid><dc:creator>Li哥</dc:creator><fs:srclink>http://blog.lilinux.net/2010/11/python-design-pattern/</fs:srclink><fs:srcfeed>http://blog.lilinux.net/feed/</fs:srcfeed><fs:itemid>feedsky/lilinux/~8065490/511583665/6171942</fs:itemid></item></channel></rss>
