今天看到微博上@hellodba发的一个帖子:“内部晋升越来越困难,但是外部来的大P越来越多,所以很多人都选择跳槽”,之后我从三个方面简要的进行 了回答:“外面来的总是有包装的,内部的都是肉身PK,此一输;外面来的总是小股人马,内部的一批批的,升谁都伤感情,此二输;外面来的通常都是大佬推荐 的,没有特别重大机会,人不会来,内部的就不解释了,成果都被大佬吸收,难有机会,此三输”。之后讨论不断,我也余兴未了,继续写来。
这个世界上有一类人特别苦逼,苦逼到什么程度呢?他们省吃俭用攒钱买房,结果房价越来越贵;公司外部竞争激烈,他们工作异常繁忙,披星戴月,日复一日;技 术更新行业罕见,他们要随时调整心情,随时学习知识;他们长期和机器为伍,大多比较呆傻,比较单纯;还有很多不一一例举,这一类人就是程序员。
而就是这么一类程序员过着这么苦逼的生活,在公司内部却难以获得公平的晋升机会,外来的和尚总是在不断打破平衡,甚至是刚毕业的新和尚拿得都比老和尚多,这是全行业都罕见的奇观,IT人有幸经历了。
某创业公司,某个程序员要离职,老板甚至不问问他直接领导的意见,就同意了,没有挽留,之后大骂不忠诚,这个人拿3k,拿了2年,他走了以后,老板用5k雇了个新面孔,但就是不愿意给这个老人晋升,不愿意给加到哪怕是4k。
某上市公司,游戏部门突然从外部空降了一个领导,原因是原大佬被挖走以后,剩下的人升谁都有意见,难以服众,不从外部请人来镇不住局面,这个人一来,大家是团结了,团结起来和这个人斗,但最后还是和解了。
某国际大公司,某人伪造简历,包装的如花似玉,获得高职,工作主要有下属完成,他只需要汇众汇报即可,越混路越宽,直到某天事发,依然是高官。
某IT企业,某清华同学离职时语重心长的对我说,XX(可以理解为网游,搜索,电商任意一种)是00-02年毕业的这些人清华人的机会, 我们就是比某人强十倍也没有机会,也得从下面做起,搜索的天时不属于我,此人去了某金融分析软件公司,目前是高管,同期留在某IT企业的其他同学依然过着 苦逼的生活。
举了这么多例子,我想说得是为什么不给你晋升这个问题,或者晋升很难,为什么?
1)大佬的问题
你晋升困难,最大的主观原因在你自己,最大的客观原因在你的直接上司。付责任人的说,目前很多企业的领导是不合格的,他们大多80后,没有为他人着想的思 想基础,一味的考虑自己,不顾下属,曾经我对某人说,你说你是合格的领导,你说出你下属每个员工租房在哪里,每月多少房租,我就同意你是合格的领导,结果 他羞愧不言。你晋升不了,很大程度上是你的领导没有帮你,连你每月房租多少都不知道,你指望他帮助你提高技术水平,帮助你晋升?
2)大佬的大佬的问题
你大佬的大佬,level很高,他需要引入新鲜血液,他知道这个队伍缺什么,这个是他思考的问题,他需要找牛的人来补这个缺口,于是一个光鲜照人的牛人进 来了(虽然两年后也会泯为众人)给队伍带来了新鲜的血液,但你的大佬升不上去,你大佬边上的位置被这个人占了,你的位置在哪?
3)公司的问题
各大企业给员工的再教育和培训都是不尽相同的,但大多口号是一致的,在工作中锻炼成长,这句话是最扯淡的,国外很多大公司是有很完善的培训和再教育计划 的,会给员工一个充电的机会,并且给其一个完善的培训后,以便于让他在新升职的岗位上能够很好的胜任。在国内大公司都在找牛人,就是不愿意自己培养,原因 是什么,不解释,你懂得。
4)你的兄弟
很多时候让你升不了职恰恰是因为和你一起战斗的兄弟,他们工作也很不错,你升职了,他们怎么办?这也是一个平衡的问题,你很努力,为什么你没有带动你的兄 弟一起努力,你上去了,需要你这帮兄弟的支持,他们会支持你吗?曾有一个说了一句话,我觉得很值得回味,“当大家都认为你该升职了,就是你升职的时候 了”,细细品味,很有道理。
5)你自己的问题
最后你升不了职是你自己的问题,每天工作很忙,没时间充电,每天工作压力很大,来不及学习,每天这个那个,一年下来碌碌无为。你提高了自己的效率了嘛?你 周围有朋友再帮你吗?你知道你要学什么嘛?你知道什么样的工作才能超出领导的期望?,你超出领导期望后却没有升职和领导沟通过吗?我曾在某企业,我周围的 几乎所有人加薪升职都是和领导沟通后才获得的。指望主动给你加薪升职,不如指望自己的沟通。
6)还是你自己的问题
你选择的这个行业是不是对的,公司是不是对的,就好像我说的这个清华的同学这个例子。如果你能耐大可以选大公司,PK到一票牛人上去,如果你能耐不大,去成熟大公司,还心理期盼高薪升职就不现实了,不如去一个有前途的中小公司,开创自己的事业。
从企业角度出发,如何创建一个合理公平的晋升机制呢?
1)第一流大佬才会招第一流的人,第二流大佬只会招第三流的人,因此公司一把手必须是第一流的,价值观才能靠谱,制度才靠谱,没熟读历史,不理解中国文化的,建议不要做公司一把手。
2)晋升的制度必须公平,面向每一个人,每一个层次,这往往很难做到,做前端的和做后台的不好比,但做前端的可以和做前端的比。必须要有公开公平的比拼,已获得升职机会。例如某公司做一个高维矩阵分解的难题,大家机会均等,性能最快,效果最好,胜出者升职,带领团队。
3)鼓励公司职员交流,传播和帮助他人的文化,一个人如果乐于助人,帮助他人提高技术水平,这个人升职升上来,大家都会顶,反之,你保守,不帮助他人,水平再牛,升职上来也没人支持。
4)可以给职员一些挑战的机会,提供更多的资源,比如某公司的闪电计划,超越了谷歌搜索效果,就是一个很好的例子,要敢于给一些勇于挑战的职员更多的资源,在严酷的战斗中考验,并提供充分弹药。
5)给予内训机会,邀请业界牛人讲座,送职员去美帝考察开会乃至工作等等。培训机会是发达国家企业的一种非常好的激励措施,一个岗位5个人培训,最好的上岗,这是一个很公平的机会,培训机构足够独立。
方法有很多,只要这第一流的大佬,心中有着这帮打生打死的兄弟,办法总是有的,不要总是考虑自己的业绩,考虑自己的乌纱帽,做到这一点很难很难,但制度不是只有这位大佬可以制定,任何职员都应该积极投身到制度建立的过程中,要敢于提出自己的观点,毕竟公司是大家的公司。
我就写这么多,我是一个十年一线程序员的身份写这篇博客的,我努力做到客观,但我相信我更多代表的是劳方立场。
作者:梁斌
来源:http://blog.sina.com.cn/s/blog_593af2a70100w0iv.html
为什么程序员/工程师难升职?
作者:ciniao 时间:2012-04-16 分类:记录 No Comments
程序员也敢吃10元的盒饭
作者:ciniao 时间:2011-12-23 分类:记录 1 Comments
又是一个阳光灿烂的中午,看了一上午的报纸,茶水也顺带喝了不少,肚子早已经咕咕作响了,今天中午吃点什么了,貌似楼下的新开张的盒饭还不错,于是我来到楼下准备买上一盒。
菜色还不错,价格有6元,8元,10元,12元,20元的,像哥这样的精英管理人才,怎么着也的吃最高级的才配合身份,就在我准备购买时,一个响亮的声音响起,
"老板,给我一份10元的盒饭!"
顺势撇了一眼,一个小伙子,眉开眼笑的靠近盒饭铺,今天是1号,看样子是发工资了。就当他走近时,看到了我,刚才的欢愉的表情瞬时黯淡下去,他知道我认出了他,靠,满头白里带一点黑的头发,永远没睡醒的眼神,以及那凌乱的胡渣子,都出卖了他的身份。我继续狠狠的盯着他,他越发的羞愧了,我犀利的眼神正在和他做着底层通信,我默默的向他传达一个信息:"你,也配吃10元的盒饭?".
他哀怜的眼神似乎在祈求我不要拆穿他的身份,可惜,哥这么有正义感的人,怎么能在这个时候放弃原则!
"你不是隔壁公司的程序员么?"
就这一瞬间,他整个人似乎崩溃下去,刚才欢愉的表情彻底变为哭丧,周围的小摊贩以及路人甲乙丙丁,都纷纷投来了鄙视的眼光,他瘟鸡一样的双手抓着头发,痛苦的蹲了下去。
就在这时,人群中终于有人忍不住了,大声呵骂到:"呸,程序员也敢吃10元的盒饭,真不要脸"
一位老大娘好心的提醒到:"小伙子啊,你一个程序员,挣点钱不容易啊,怎么吃10元的盒饭啊"
一名打扮妖艳入时的姑娘说到:"人家当小姐的都才吃10元,你也敢要10元的?"
我义正言辞的给他说到:"我说一句话顶你写一万行代码,也才吃20元的盒饭,你竟敢吃10元的"
老板也发话了:"是程序员啊,太不好意思了,你吃6元的吧,不然人家知道我卖了你10元的,我这生意就做不了啊"
他终于发出颤抖的声音说到:"对不起,我刚才说错了,给我一份6元的"。
这时人群中爆发出激烈的掌声,我知道,这是我又一次坚持原则,换来的荣誉的赞赏!
菜色还不错,价格有6元,8元,10元,12元,20元的,像哥这样的精英管理人才,怎么着也的吃最高级的才配合身份,就在我准备购买时,一个响亮的声音响起,
"老板,给我一份10元的盒饭!"
顺势撇了一眼,一个小伙子,眉开眼笑的靠近盒饭铺,今天是1号,看样子是发工资了。就当他走近时,看到了我,刚才的欢愉的表情瞬时黯淡下去,他知道我认出了他,靠,满头白里带一点黑的头发,永远没睡醒的眼神,以及那凌乱的胡渣子,都出卖了他的身份。我继续狠狠的盯着他,他越发的羞愧了,我犀利的眼神正在和他做着底层通信,我默默的向他传达一个信息:"你,也配吃10元的盒饭?".
他哀怜的眼神似乎在祈求我不要拆穿他的身份,可惜,哥这么有正义感的人,怎么能在这个时候放弃原则!
"你不是隔壁公司的程序员么?"
就这一瞬间,他整个人似乎崩溃下去,刚才欢愉的表情彻底变为哭丧,周围的小摊贩以及路人甲乙丙丁,都纷纷投来了鄙视的眼光,他瘟鸡一样的双手抓着头发,痛苦的蹲了下去。
就在这时,人群中终于有人忍不住了,大声呵骂到:"呸,程序员也敢吃10元的盒饭,真不要脸"
一位老大娘好心的提醒到:"小伙子啊,你一个程序员,挣点钱不容易啊,怎么吃10元的盒饭啊"
一名打扮妖艳入时的姑娘说到:"人家当小姐的都才吃10元,你也敢要10元的?"
我义正言辞的给他说到:"我说一句话顶你写一万行代码,也才吃20元的盒饭,你竟敢吃10元的"
老板也发话了:"是程序员啊,太不好意思了,你吃6元的吧,不然人家知道我卖了你10元的,我这生意就做不了啊"
他终于发出颤抖的声音说到:"对不起,我刚才说错了,给我一份6元的"。
这时人群中爆发出激烈的掌声,我知道,这是我又一次坚持原则,换来的荣誉的赞赏!
python可变参数与标准输出的重定位
作者:ciniao 时间:2011-09-27 分类:python 2 Comments
使用python的内置函数print时,大家会发现它是支持任意多个参数,也就是说,print的调用参数是不固定的。例如:
这得益与python的“可变参数”,在Python里,可以使用*和**来设置可变参数,它们的区别是*传递一个参数元组,**传递一个参数字典,二者可以同时混合使用。混合使用时要加些小心,因为python中他们的次序是重要的。参数归为4类,不是所有的类别都需要。他们必须按下面的次序定义,不用的可以跳过。
1)必须的参数
2)可选的参数
3)过量的位置参数
4)过量的关键字参数
这个次序是必须的,因为*args和**kwargs只接受那些没有放进来的其他任何参数。没有这个次序,当你调用一个带有位置参数的函数,python就不知道哪个值是已声明参数想要的,也不知道哪个被作为过量参数对待。
也要注意的是,当函数能接受许多必须的参数和可选的参数,那它只要定义一个过量的参数类型即可。看下面的例子:
注意这个例子的最后几行,特别留意当传递一个元组作为可变参数时,是否要显式的传递关键字参数。因为python使用次序规则来扩展过量的参数,那位置参数要放在前面。这个例子中,最后两个调用是相同的,python不能决定那个值是给a的。
下面举一个例子来模仿print的实现:
print默认是输出到stdout中,在终端运行的程序,无重定向的情况下,print输出到控制台。如果要做代码里实现把print的输出写入到log文件中,可以通过修改stdout的文件对象来实现。同理,重定位标准输入和标准错误输出分别修改stdin和stderr的文件对象即可。
下面的例子捕捉所有print的输出,让输出的每一行前增加一个时间的显示:
运行效果如下图:
本文部分内容来源于:http://xiaoxia.org/?p=4270
print "你好"
print "我是",name
print "现在是", time , " 你在干什么呢", name , "!"这得益与python的“可变参数”,在Python里,可以使用*和**来设置可变参数,它们的区别是*传递一个参数元组,**传递一个参数字典,二者可以同时混合使用。混合使用时要加些小心,因为python中他们的次序是重要的。参数归为4类,不是所有的类别都需要。他们必须按下面的次序定义,不用的可以跳过。
1)必须的参数
2)可选的参数
3)过量的位置参数
4)过量的关键字参数
def funName(a, b=None, *c, **d):这个次序是必须的,因为*args和**kwargs只接受那些没有放进来的其他任何参数。没有这个次序,当你调用一个带有位置参数的函数,python就不知道哪个值是已声明参数想要的,也不知道哪个被作为过量参数对待。
也要注意的是,当函数能接受许多必须的参数和可选的参数,那它只要定义一个过量的参数类型即可。看下面的例子:
def add(a, b, c):
return a + b + c
>>> add(1, 2, 3)
6
>>> add(a=4, b=5, c=6)
15
>>> args = (2, 3)
>>> add(1, *args)
6
>>> kwargs={'b': 8, 'c': 9}
>>> add(a=7, **kwargs)
24
>>> add(a=7, *args)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() got multiple values for keyword argument 'a'
>>> add(1, 2, a=7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() got multiple values for keyword argument 'a'注意这个例子的最后几行,特别留意当传递一个元组作为可变参数时,是否要显式的传递关键字参数。因为python使用次序规则来扩展过量的参数,那位置参数要放在前面。这个例子中,最后两个调用是相同的,python不能决定那个值是给a的。
下面举一个例子来模仿print的实现:
>>> import sys
>>> def myprint(*argv):
sys.stdout.write(" ".join([str(i) for i in argv]) + "\n")
>>> print "I believe", 2012, "is the end of the world."
I believe 2012 is the end of the world.
>>> myprint("I believe", 2012, "is the end of the world.")
I believe 2012 is the end of the world.
>>> print "tuple:", (1, 2, 3), "list:", [1, 2, 3], "dict:", {"begin":-2012, "end":2012}
tuple: (1, 2, 3) list: [1, 2, 3] dict: {'begin': -2012, 'end': 2012}
>>> myprint("tuple:", (1, 2, 3), "list:", [1, 2, 3], "dict:", {"begin":-2012, "end":2012})
tuple: (1, 2, 3) list: [1, 2, 3] dict: {'begin': -2012, 'end': 2012}print默认是输出到stdout中,在终端运行的程序,无重定向的情况下,print输出到控制台。如果要做代码里实现把print的输出写入到log文件中,可以通过修改stdout的文件对象来实现。同理,重定位标准输入和标准错误输出分别修改stdin和stderr的文件对象即可。
下面的例子捕捉所有print的输出,让输出的每一行前增加一个时间的显示:
import sys, time
class MyOutput():
def __init__(self, fd):
self.formatTime()
self.out = fd
self.newLine = True
def formatTime(self):
return time.strftime("%H:%M:%S ", time.localtime())
def write(self, s):
if self.newLine:
self.out.write(self.formatTime())
self.newLine = False
self.out.write(s)
if s.endswith("\n"):
self.newLine = True
def flush(self):
self.out.flush()
sys.stdout = MyOutput(sys.stdout)
print "Program begin."
mylist = [5, 4, 3, 2, 1]
print "prev: ", mylist
mylist.sort()
print "after: ", mylist
time.sleep(3)
print "Program end."运行效果如下图:
本文部分内容来源于:http://xiaoxia.org/?p=4270
python中的异常处理
作者:ciniao 时间:2011-09-24 分类:python No Comments
Python的异常处理能力是很强大的,可向用户准确反馈出错信息。在Python中,异常也是对象,可对它进行操作。所有异常都是基类Exception的成员,所有异常都从基类Exception继承,而且都在exceptions模块中定义,Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。
一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。
一、异常的捕获
异常的捕获有以下几种方法:
1:使用try和except语句
该种异常处理语法的规则是:
• 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
• 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
• 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
• 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
• 如果没有发生异常,则执行else块代码。
示例代码:
捕获到的IOError错误的详细原因会被放置在对象e中,然后运行该异常的except代码块,也可以使用以下方法来捕获所有的异常:
使用except子句需要注意的事情,就是多个except子句截获异常时,如果各个异常类之间具有继承关系,则子类应该写在前面,否则父类将会直接截获子类异常,放在后面的子类异常也就不会执行到了。
2:使用try跟finally
该语句的执行规则是:
• 执行try下的代码。
• 如果发生异常,在该异常传递到下一级try时,执行finally中的代码。
• 如果没有发生异常,则执行finally中的代码。
第二种try语法在无论有没有发生异常都要执行代码的情况下是很有用的,例如我们在python中打开一个文件进行读写操作,我在操作过程中不管是否出现异常,最终都是要把该文件关闭的。
这两种形式相互冲突,使用了一种就不允许使用另一种,而功能又各异。
二、手工引发引发一个异常
在Python中,要想引发异常,最简单的形式就是输入关键字raise,后跟要引发的异常的名称。异常名称标识出具体的类:Python异常是那些类的对象,执行raise语句时,Python会创建指定的异常类的一个对象,raise语句还可指定对异常对象进行初始化的参数,为此,请在异常类的名称后添加一个逗号以及指定的参数(或者由参数构成的一个元组)。
示例代码:
三、跟踪查看异常
发生异常时,Python能“记住”引发的异常以及程序的当前状态,Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息,异常可能在一系列嵌套较深的函数调用中引发,程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名,一旦异常被引发,Python会搜索一个相应的异常处理程序。
如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止,这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(Stack Unwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。
四、采用sys模块回溯最后的异常
或者以如下的形式:
这里的type是异常的类型,value/message是异常的信息或者参数,traceback包含调用栈信息的对象,从这点上可以看出此方法涵盖了traceback。
以上都是错误处理的理论知识,接下来我们要动手设计一个自己的异常处理类,用来记录异常日志,将错误的日志按照每小时一个文件的频率,保存到我们指定的位置。代码如下:
运行一下,我们会在该文件目录下的log/fight下看到一个日志文件,记录的描述内容如下:
一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。
一、异常的捕获
异常的捕获有以下几种方法:
1:使用try和except语句
try:
block
except [exception,[data…]]:
block
try:
block
except [exception,[data...]]:
block
else:
block该种异常处理语法的规则是:
• 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
• 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
• 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
• 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
• 如果没有发生异常,则执行else块代码。
示例代码:
try:
f = open(“file.txt”,”r”)
except IOError, e:
print e捕获到的IOError错误的详细原因会被放置在对象e中,然后运行该异常的except代码块,也可以使用以下方法来捕获所有的异常:
try:
a=b
b=c
except Exception,ex:
print Exception,":",ex使用except子句需要注意的事情,就是多个except子句截获异常时,如果各个异常类之间具有继承关系,则子类应该写在前面,否则父类将会直接截获子类异常,放在后面的子类异常也就不会执行到了。
2:使用try跟finally
try:
block
finally:
block该语句的执行规则是:
• 执行try下的代码。
• 如果发生异常,在该异常传递到下一级try时,执行finally中的代码。
• 如果没有发生异常,则执行finally中的代码。
第二种try语法在无论有没有发生异常都要执行代码的情况下是很有用的,例如我们在python中打开一个文件进行读写操作,我在操作过程中不管是否出现异常,最终都是要把该文件关闭的。
这两种形式相互冲突,使用了一种就不允许使用另一种,而功能又各异。
二、手工引发引发一个异常
在Python中,要想引发异常,最简单的形式就是输入关键字raise,后跟要引发的异常的名称。异常名称标识出具体的类:Python异常是那些类的对象,执行raise语句时,Python会创建指定的异常类的一个对象,raise语句还可指定对异常对象进行初始化的参数,为此,请在异常类的名称后添加一个逗号以及指定的参数(或者由参数构成的一个元组)。
示例代码:
try:
raise MyError #自己抛出一个异常
except MyError:
print 'a error'
raise ValueError,'invalid argument'捕捉到的内容为:type = VauleError
message = invalid argument三、跟踪查看异常
发生异常时,Python能“记住”引发的异常以及程序的当前状态,Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息,异常可能在一系列嵌套较深的函数调用中引发,程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名,一旦异常被引发,Python会搜索一个相应的异常处理程序。
如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止,这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(Stack Unwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。
try:
block
except:
traceback.print_exc()四、采用sys模块回溯最后的异常
import sys
try:
block
except:
info=sys.exc_info()
print info[0],":",info[1]或者以如下的形式:
import sys
tp,val,td = sys.exc_info() sys.exc_info()的返回值是一个tuple, (type, value/message, traceback)这里的type是异常的类型,value/message是异常的信息或者参数,traceback包含调用栈信息的对象,从这点上可以看出此方法涵盖了traceback。
以上都是错误处理的理论知识,接下来我们要动手设计一个自己的异常处理类,用来记录异常日志,将错误的日志按照每小时一个文件的频率,保存到我们指定的位置。代码如下:
#coding:utf-8
#基于python2.6
import logging,os,time,traceback
class LOG:
def __init__(self,logger):
self.fileHandlerName = ''
self.fileHandler = None
self.loggerName = logger
self.logger = logging.getLogger(logger)
self.logger.setLevel(logging.DEBUG)
self.formatter = logging.Formatter("=========================\ntime:%(asctime)s \nlogger:%(name)s \nlevel:%(levelname)s \nfile:%(filename)s \nfun:%(funcName)s \nlineno:%(lineno)d \nmessage:%(message)s")
# 控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(self.formatter)
self.logger.addHandler(ch)
path = os.path.abspath(os.path.dirname(__file__)) + '/log/'+self.loggerName+'/'
print 'log path=',path
def setfh(self):
fname = time.strftime("%Y%m%d%H")
if fname!=self.fileHandlerName:
#移除原来的句柄
if self.fileHandler!=None :
self.logger.removeHandler(self.fileHandler)
#设置日志文件保存位置
path = os.path.abspath(os.path.dirname(__file__)) + '/log/'+self.loggerName+'/'
print path
if os.path.isdir(path) == False:
os.makedirs(path)
fh = logging.FileHandler(path+fname+'.log')
fh.setLevel(logging.DEBUG)
fh.setFormatter(self.formatter)
self.logger.addHandler(fh)
self.fileHandlerName = fname
self.fileHandler = fh
#格式化日志内容
def _fmtInfo(self,msg):
if len(msg)==0:
msg = traceback.format_exc()
return msg
else:
_tmp = [msg[0]]
_tmp.append(traceback.format_exc())
return '\n**********\n'.join(_tmp)
#封装方法
def debug(self,*msg):
_info = self._fmtInfo(msg)
try:
self.setfh()
self.logger.debug(_info)
except:
print 'mylog debug:' + _info
def error(self,*msg):
_info = self._fmtInfo(msg)
try:
self.setfh()
self.logger.error(_info)
except:
print 'mylog error:' + _info
def info(self,*msg):
_info = self._fmtInfo(msg)
try:
self.setfh()
self.logger.error(_info)
except:
print 'mylog info:' + _info
def warning(self,*msg):
_info = self._fmtInfo(msg)
try:
self.setfh()
self.logger.error(_info)
except:
print 'mylog warning:' + _info
if __name__=='__main__':
log = LOG('fight')
try:
print 1/0
except:
log.error() #使用系统自己的错误描述
try:
print 2/0
except:
log.error('搞错了,分母不能为0') #使用自己的错误描述运行一下,我们会在该文件目录下的log/fight下看到一个日志文件,记录的描述内容如下:
#文章部分内容来源于网络,作者不详 无法署名# python中用ctypes模块调用C语言库
作者:ciniao 时间:2011-09-13 分类:python 2 Comments
最近用到中文分词库 Bamboo ,开始时有点头疼居然没有 Python 封装,后来发现用 ctypes 模块来封装实在是太简单、太方便了~几乎被感动到内流满面~有了庞大 C 库和 ctypes 模块的 Python ,真是可比当年的数理化——走遍天下都不怕~下面给出通过 ctypes 模块调用 Bamboo 分词的示例代码:
相关文章:沈崴大侠的《用 Python 写自己的 C Module》
本文作者:Elias的邪异门
文章转自:http://blog.elias.cn/archives/399
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from ctypes import *
# 通过 C 接口载入 libbamboo ,.dylib是 Mac OSX 下的动态库后缀, Linux 下应该是libbamboo.so
libbamboo = CDLL('libbamboo.dylib')
# 调用 bamboo_init() 函数得到一个分词器实例
bamboo_init = libbamboo.bamboo_init
bamboo_init.restype = c_void_p
bamboo_handler = bamboo_init(c_char_p('crf_seg'), None)
# 如果返回的实例是 None (也即 C 中的 Null ),表示实例生成失败,那我们打印出错原因
if bamboo_handler is None:
bamboo_strerror = libbamboo.bamboo_strerror
bamboo_strerror.restype = c_char_p
print bamboo_strerror()
else:
# 把文本传给分词器准备分词
# 待分词的文本必须是 utf-8 编码的 bytes string ,所以我们要把 unicode string encode 一下
libbamboo.bamboo_setopt(bamboo_handler, c_long(0), c_char_p(u'我爱北京天安门'.encode('utf-8')))
# 真正开始分词
bamboo_parse = libbamboo.bamboo_parse
bamboo_parse.restype = c_char_p
# 下一行得到分词结果(空格分隔),格式还是 utf-8 编码的 bytes string ,我们把它 decode 成 unicode
segged = bamboo_parse(bamboo_handler).decode('utf-8')
print type(segged), len(segged), segged
# 调用 bamboo_clean() 函数释放分词器实例
libbamboo.bamboo_clean(bamboo_handler)
相关文章:沈崴大侠的《用 Python 写自己的 C Module》
本文作者:Elias的邪异门
文章转自:http://blog.elias.cn/archives/399