python难还是ruby难

Python017

python难还是ruby难,第1张

一、异同对比选择

1、Python和ruby的相同点:

·都强调语法简单,都具有更一般的表达方式。python是缩进,ruby是类basic的表达。都大量减少了符号。

·都是动态数据类型。都是有丰富的数据结构。

·都具有C语言扩展能力,都具有可移植性,比perl的可移植性更好。也都可以作为嵌入语言。

·都是面向对象的语言,都可以作为大项目的开发工具。

·都有丰富的库支持。

·也有最宽松的版权许可,除了一些工具属于GNU世界。

·都有lisp特色的eval函数,也都能把函数作为参数。

·也有图形界面的ruby的专门编辑器。

·都获得了广泛的c库的支持。如qt、gtk、tk、SDL、FOX等,ruby计划实现SWIG接口。

·都有完善的文档。

相关推荐:《Python视频教程》

2、和python相比ruby的优点:

·具有正则表达式和嵌入html的功能。python也有正则表达式,但没有ruby的应用方便和广泛。python的嵌入html项目才刚起步。ruby还有apache的mod模块。ruby本身也实现和很多unix工具,如racc,doctools。比python更亲近Linux。

·比python功能更完整的面向对象的语法。

·ruby的整个库都是具有类继承的结构。

·他的基本的数据类型和运算符都是可以重载的。

·ruby主要的功能都是通过对象的方法调用来实现的,而不是函数。python也在向这方面发展,但没有ruby做的彻底。

·ruby的类是更规范的单继承,还有接口等概念的实现。

·python可以实现在列表内的条件语句、循环语句,而ruby用“块”的方式来实现这个功能,比python的更灵活,更具有通用性。

·ruby具有类似lisp的彻底的函数方式的条件语句、循环语句等。语句的表达能力更强。

·附带一些unix工具,如racc等。

3、和python相比ruby的不足:

·最大的不足正是因为ruby的强大所引起的。它没有python的简单性好。比较复杂的面向对象语法、“块”语法的引入、正则表达式的引入、一些简写标记都增加了语言的复杂性。

·python的缩进表达方式比ruby的basic的表达方式更让人悦目,ruby程序的满眼的end让人不舒服。当然,ruby认为end的方式比python更先进。

·ruby还没有python的“自省”的能力,没有从程序文件中生成文档的能力。

·ruby没有国际化的支持。国际化支持在ruby的计划中。这是因为ruby的历史比python要短造成的。

·ruby没有类似jython的东西。

4、python和ruby的语言的选择:

从简单的就是好的来说,选python是没错的。python适合寻找简单语言的人,这很可能造成python更流行,因此也有更多的支持。但如果要追求更强大的语法功能,则ruby是好的选择。因为ruby和python的哲学有很多相似的地方,先从python入手,尽量用python,如果python的能力不足了,可以在找ruby。

ruby和python的比较,就像五笔和拼音输入法的比较。拼音作为入门的输入法和长久使用的输入法都没有问题。五笔适合更高要求的情况。如果追求性能的不妨学学ruby。对编程语言感兴趣,想了解各种编程概念的学ruby也会很兴奋。

二、两者各有特点:

1、Python从语法上来说更质朴一些,而Ruby更性感一些

Python的语法相对其他脚本语言来说,没有太多花巧的地方,显得比较死板一点,其实从Python强制代码缩进也可以看出来Guido设计语言的取向。语法死板的一面就是不容易玩出来更性感的东西,比方说Rails这样的框架,另外Python也无法做DSL这样的事情,但是语法死板的另一面就是比较规范,相对来说,更加适应软件开发的工程性要求,更容易组织大规模的团队进行开发。

Ruby的语法非常灵活,Matz设计ruby的出发点也是为了coding for fun,因此可以用ruby玩出来很多花样,运用足够的技巧,可以用Ruby写出来逼近自然语言的DSL,对于程序员来说,玩ruby确实充满了乐趣。Rails能在ruby社区诞生,而不是Python社区诞生绝对和编程语言有直接的关系。不过ruby语法灵活的另一面就是编程实现风格的多样性,这对于大规模团队的协作和管理是一个挑战。

2、Python的解析器实现更成熟,第三方库质量高

Ruby1.9解析器尽管已经有了很大的性能提升和很多新的功能,但是从源代码实现的角度来说,基本上是通过在Ruby1.8源代码上打patch来增加功能的。从源代码的结构来说,Ruby的实现太古老了,Ruby扩展起来比较困难,只能不断打patch。这也是为什么现在Ruby社区涌现出来那么多新的Ruby解析器实现的原因。从很大程度上来说,这制约了Ruby的发展速度。相对而言,Python解析器更成熟,也比较稳定。

在第三方类库的数量上来说,Ruby并不比Python少,但是高性能高质量久经考验的第三方类库Python要明显比Ruby多,事实上很多Ruby的第三方类库都不太成熟,因此这也很大程度上制约了Ruby的发展。

3、Python的应用领域非常广泛,而Ruby目前主要局限在在Web领域

Python应用的领域非常广泛,除了web开发以外,还被广泛用在服务器后端的高性能服务器实现,服务器后端的各种密集运算,全文检索,各种文本处理,系统管理等等,另外桌面应用领域wxPython也是一个很成熟的跨平台GUI框架。对于某些特殊的应用,比方说调用操作系统内核API,Python也可以完成的很好,比方说大量小文件的实时同步方案,就是用Python直接调用linuxKernel的inotify特性来实现的。所以可以说Python是软件开发领域的瑞士军刀,什么事情都可以做。

正是由于Ruby解析器和Ruby类库的制约,Ruby的应用主要局限在Web开发领域,目前Ruby的应用还无法延伸到web开发领域以外的很多地方。据说豆瓣早期就考虑过Ruby on Rails,但是因为Ruby不能做其他事情,而Python可以大包大揽,最后放弃Ruby选择了Python。

4、在Web领域Ruby是王者

随着互联网应用更进一步渗透到软件开发的各个领域,其实web开发占整个软件行业开发的比重也是越来越大。尽管Ruby在其他领域很受制约,但是在Web开发领域就是绝对的王者了。Rails框架的领先程度已经远远甩开了任何一个潜在的竞争对手十万八千里。因此尽管Ruby可能有这样那样的问题,但是说到Web开发,Rails几乎就是无可争议的唯一选择。

而Python尽管十分全面,却偏偏在web开发领域不彰,web框架虽然众多,却没有一个真正可以挑大梁,Django虽然在Python社区比较流行,但很多方面也有缺陷。现在的互联网应用往往都是多种语言混合编程,Ruby在Web以外的缺陷也可以用其他语言来弥补。

5、Python的包管理不如Ruby

尽管Python的第三方类库更高质量更成熟,但是Python社区缺乏Ruby Gem这样一个良好的包管理软件和包发布的网站。因此应用的构建显得不如Ruby那么方便,那么人性化。特别是在类库的版本升级上,就会遇到很多麻烦,不如Ruby Gem那么简单。

不过总的来说,Python和Ruby还是相似度极高的两种编程语言,即使两种编程语言都学习一下也不会浪费太多时间。如果我个人选择的话,会首选用Rails来构建web应用,再根据情况选择Python或者Java处理一些服务器后端的运算。总之,未来还是一个混合编程的时代,我们需要多了解一些编程工具,然后根据需要看菜吃饭才行。

这个我们期末考试考过。

inotify只能监控单层目录变化,不能监控子目录中的变化情况。

如果需要监控子目录,需要在调用inotify_add_watch(int fd, char *dir, int mask):int建立监控时,递归建立子目录的监控,伪代码如下

void addwatch(int fd, char *dir, int mask)

{

wd = inotify_add_watch(fd, dir, mask)

向目录集合加入(wd, dir)

for (dir下所有的子目录subdir)

addwatch(fd, subdir, mask)

}

这样就可以得到一个目录集合,其中每一个wd对应一个子目录。

当你调用read获取信息时,可以得到一个下面的结构体

struct inotify_event

{

int wd /* Watch descriptor. */

uint32_t mask /* Watch mask. */

uint32_t cookie /* Cookie to synchronize two events. */

uint32_t len/* Length (including NULs) of name. */

char name __flexarr /* Name. */

}

其中,通过event->wd和刚才记录的目录集合可以知道变动的具体子目录。

event->name为具体的文件名称。

event->name是一个char name[0]形式的桩指针,具体的name占据的长度可以由event->len得出

我的监控部分代码如下:

enum {EVENT_SIZE = sizeof(struct inotify_event)}

enum {BUF_SIZE = (EVENT_SIZE + 16) <<10}

void watch_mon(int fd)

{

int i, length

void *buf

struct inotify_event *event

buf = malloc(BUF_SIZE)

while ((length = read(fd, buf, BUF_SIZE)) >= 0)

{

i = 0

while (i <length)

{

event = buf + i

if (event->len)

具体处理函数(event)

i += EVENT_SIZE + event->len

}

}

close(fd)

exit(1)

}

在你的具体处理函数中,通过wd辨识子目录,通过name辨识文件

这是利用C++STLmap写的一个范例,可以监视当前目录下(含子目录)的变化,创建,删除过程(新建立的目录不能监视,只能通过监视到创建新目录的事件后重新初始化监视表)

新版1.1.0,可以监视创建的子目录,方法是,当do_action探测到新目录创建的动作时,调用inotify_add_watch追加新的监视

/*

Copyright (C) 2010-2011 LIU An ([email protected])

This program is free software: you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation, either version 3 of the License, or

(at your option) any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTYwithout even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program. If not, see <http://www.gnu.org/licenses/>.

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/inotify.h>

#include <errno.h>

#include <dirent.h>

#include <map>

#include <string>

using namespace std

void addwatch(int, char*, int)

static int filter_action(uint32_t mask)

int watch_init(int mask, char *root)

void addwatch(int fd, char *dir, int mask)

static void do_action(int fd, struct inotify_event *event)

void watch_mon(int fd)

static void send_mess(char *name, char *act, int ewd)

void append_dir(int fd, struct inotify_event *event, int mask)

map<int, string>dirset

enum{MASK = IN_MODIFY | IN_CREATE | IN_DELETE}

int main(int argc, char **argv)

{

int fd

if (argc != 2)

{

fprintf(stderr, "Usage: %s dir\n", argv[0])

exit(1)

}

fd = watch_init(MASK, argv[1])

watch_mon(fd)

return 0

}

int watch_init(int mask, char *root)

{

int i, fd

if ((fd = inotify_init()) <0)

perror("inotify_init")

addwatch(fd, root, mask)

return fd

}

void addwatch(int fd, char *dir, int mask)

{

int wd

char subdir[512]

DIR *odir

struct dirent *dent

if ((odir = opendir(dir)) == NULL)

{

perror("fail to open root dir")

exit(1)

}

wd = inotify_add_watch(fd, dir, mask)

dirset.insert(make_pair(wd, string(dir)))

errno = 0

while ((dent = readdir(odir)) != NULL)

{

if (strcmp(dent->d_name, ".") == 0

|| strcmp(dent->d_name, "..") == 0)

continue

if (dent->d_type == DT_DIR)

{

sprintf(subdir, "%s/%s", dir, dent->d_name)

addwatch(fd, subdir, mask)

}

}

if (errno != 0)

{

perror("fail to read dir")

exit(1)

}

closedir (odir)

}

enum {EVENT_SIZE = sizeof(struct inotify_event)}

enum {BUF_SIZE = (EVENT_SIZE + 16) <<10}

void watch_mon(int fd)

{

int i, length

void *buf

struct inotify_event *event

buf = malloc(BUF_SIZE)

while ((length = read(fd, buf, BUF_SIZE)) >= 0)

{

i = 0

while (i <length)

{

event = (struct inotify_event*)(buf + i)

if (event->len)

do_action(fd, event)

i += EVENT_SIZE + event->len

}

}

close(fd)

exit(1)

}

static char action[][10] =

{

"modified",

"accessed",

"created",

"removed"

}

enum{NEWDIR = IN_CREATE | IN_ISDIR}

static void do_action(int fd, struct inotify_event *event)

{

int ia, i

if ((ia = filter_action(event->mask)) <0)

return

if ((event->mask &NEWDIR) == NEWDIR)

append_dir(fd, event, MASK)

send_mess(event->name, action[ia], event->wd)

}

void append_dir(int fd, struct inotify_event *event, int mask)

{

char ndir[512]

int wd

sprintf(ndir, "%s/%s", dirset.find(event->wd)->second.c_str(),

event->name)

wd = inotify_add_watch(fd, ndir, mask)

dirset.insert(make_pair(wd, string(ndir)))

}

static int filter_action(uint32_t mask)

{

if (mask &IN_MODIFY)

return 0

if (mask &IN_ACCESS)

return 1

if (mask &IN_CREATE)

return 2

if (mask &IN_DELETE)

return 3

return -1

}

static void send_mess(char *name, char *act, int ewd)

{

char format[] = "%s was %s.\n"

char file[512]

sprintf(file, "%s/%s", dirset.find(ewd)->second.c_str(), name)

printf(format, file, act)

}

参考资料是我们作业的提交,没有考虑递归创建子目录监控的问题。

本人是用ubuntu作开发机器。

一天偶然发现linux有notify-send这个神器。于是乎,crontab + notify-send 建了各种提醒,这是初级。

最近由于qq装在虚拟机的win下面,无法及时收到消息,特别困扰。notify-send是不是应该派上用场了。

可是qq怎么通知到notify-send呢?1、监控qq聊天记录的文件;2、利用qq自有的通知功能。为了不辜负qq,选择了后者的通知功能。然后在qq设置那边发现了设置提示音,通过监控音频文件的读取事件来通知notify-send。

具体通过虚拟机自身的文件共享,把提示音设置成linux上面的音频文件;通过inotify监控该文件的访问。

立马晒上简短的几行脚本。

mon-qq.sh 完成。设置开机启动。

本文只是抛砖引玉,notify-send和inotify在一起,可以有很多花样,欢迎一起分享。

原文 http://www.baozy.com/archives/12084.html