首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > perl python >

您需要知道的、有用的 Python 功能和特点

2013-12-28 
你需要知道的、有用的 Python 功能和特点在使用Python多年以后,我偶然发现了一些我们过去不知道的功能和特

你需要知道的、有用的 Python 功能和特点

在使用Python多年以后,我偶然发现了一些我们过去不知道的功能和特性。一些可以说是非常有用,但却没有充分利用。考虑到这一点,我编辑了一些你应该了解的Python功能特色。

带任意数量参数的函数

你可能已经知道了Python允许你定义可选参数。但还有一个方法,可以定义函数任意数量的参数。

首先,看下面是一个只定义可选参数的例子

01def?function(arg1="",arg2=""):02????print?"arg1:?{0}".format(arg1)03????print?"arg2:?{0}".format(arg2)04??05function("Hello",?"World")06#?prints?args1:?Hello07#?prints?args2:?World08??09function()10#?prints?args1:11#?prints?args2:

现在,让我们看看怎么定义一个可以接受任意参数的函数。我们利用元组来实现。

01def?foo(*args):?#?just?use?"*"?to?collect?all?remaining?arguments?into?a?tuple02????numargs?=?len(args)03????print?"Number?of?arguments:?{0}".format(numargs)04????for?i,?x?in?enumerate(args):05????????print?"Argument?{0}?is:?{1}".format(i,x)06??07foo()08#?Number?of?arguments:?009??10foo("hello")11#?Number?of?arguments:?112#?Argument?0?is:?hello13??14foo("hello","World","Again")15#?Number?of?arguments:?316#?Argument?0?is:?hello17#?Argument?1?is:?World18#?Argument?2?is:?Again使用Glob()查找文件

大多Python函数有着长且具有描述性的名字。但是命名为glob()的函数你可能不知道它是干什么的除非你从别处已经熟悉它了。
它像是一个更强大版本的listdir()函数。它可以让你通过使用模式匹配来搜索文件。

1import?glob2??3#?get?all?py?files4files?=?glob.glob('*.py')5print?files6??7#?Output8#?['arg.py',?'g.py',?'shut.py',?'test.py']

?

你可以像下面这样查找多个文件类型:

01import?itertools?as?it,?glob02??03def?multiple_file_types(*patterns):04????return?it.chain.from_iterable(glob.glob(pattern)?for?pattern?in?patterns)05??06for?filename?in?multiple_file_types("*.txt",?"*.py"):?#?add?as?many?filetype?arguements07????print?filename08??09#?output10#=========#11#?test.txt12#?arg.py13#?g.py14#?shut.py15#?test.py

?

如果你想得到每个文件的绝对路径,你可以在返回值上调用realpath()函数:

01import?itertools?as?it,?glob,?os02??03def?multiple_file_types(*patterns):04????return?it.chain.from_iterable(glob.glob(pattern)?for?pattern?in?patterns)05??06for?filename?in?multiple_file_types("*.txt",?"*.py"):?#?add?as?many?filetype?arguements07????realpath?=?os.path.realpath(filename)08????print?realpath09??10#?output11#=========#12#?C:\xxx\pyfunc\test.txt13#?C:\xxx\pyfunc\arg.py14#?C:\xxx\pyfunc\g.py15#?C:\xxx\pyfunc\shut.py16#?C:\xxx\pyfunc\test.py?调试

下面的例子使用inspect模块。该模块用于调试目的时是非常有用的,它的功能远比这里描述的要多。

这篇文章不会覆盖这个模块的每个细节,但会展示给你一些用例。

01import?logging,?inspect02??03logging.basicConfig(level=logging.INFO,04????format='%(asctime)s?%(levelname)-8s?%(filename)s:%(lineno)-4d:?%(message)s',05????datefmt='%m-%d?%H:%M',06????)07logging.debug('A?debug?message')08logging.info('Some?information')09logging.warning('A?shot?across?the?bow')10??11def?test():12????frame,filename,line_number,function_name,lines,index=\13????????inspect.getouterframes(inspect.currentframe())[1]14????print(frame,filename,line_number,function_name,lines,index)15??16test()17??18#?Should?print?the?following?(with?current?date/time?of?course)19#10-19?19:57?INFO?????test.py:9???:?Some?information20#10-19?19:57?WARNING??test.py:10??:?A?shot?across?the?bow21#(,?'C:/xxx/pyfunc/magic.py',?16,?'',?['test()\n'],?0)

?

生成唯一ID

在有些情况下你需要生成一个唯一的字符串。我看到很多人使用md5()函数来达到此目的,但它确实不是以此为目的。
其实有一个名为uuid()的Python函数是用于这个目的的。

1import?uuid2result?=?uuid.uuid1()3print?result4??5#?output?=>?various?attempts6#?9e177ec0-65b6-11e3-b2d0-e4d53dfcf61b7#?be57b880-65b6-11e3-a04d-e4d53dfcf61b8#?c3b2b90f-65b6-11e3-8c86-e4d53dfcf61b

?

你可能会注意到,即使字符串是唯一的,但它们后边的几个字符看起来很相似。这是因为生成的字符串与电脑的MAC地址是相联系的。

为了减少重复的情况,你可以使用这两个函数。

01import?hmac,hashlib02key='1'03data='a'04print?hmac.new(key,?data,?hashlib.sha256).hexdigest()05??06m?=?hashlib.sha1()07m.update("The?quick?brown?fox?jumps?over?the?lazy?dog")08print?m.hexdigest()09??10#?c6e693d0b35805080632bc2469e1154a8d1072a86557778c27a01329630f891711#?2fd4e1c67a2d28fced849ee1bb76e7391b93eb12序列化

你曾经需要将一个复杂的变量存储在数据库或文本文件中吧?你不需要想一个奇特的方法将数组或对象格转化为式化字符串,因为Python已经提供了此功能。

01import?pickle02??03variable?=?['hello',?42,?[1,'two'],'apple']04??05#?serialize?content06file?=?open('serial.txt','w')07serialized_obj?=?pickle.dumps(variable)08file.write(serialized_obj)09file.close()10??11#?unserialize?to?produce?original?content12target?=?open('serial.txt','r')13myObj?=?pickle.load(target)14??15print?serialized_obj16print?myObj17??18#output19#?(lp020#?S'hello'21#?p122#?aI4223#?a(lp224#?I125#?aS'two'26#?p327#?aaS'apple'28#?p429#?a.30#?['hello',?42,?[1,?'two'],?'apple']

?

这是一个原生的Python序列化方法。然而近几年来JSON变得流行起来,Python添加了对它的支持。现在你可以使用JSON来编解码。

01import?json02??03variable?=?['hello',?42,?[1,'two'],'apple']04print?"Original?{0}?-?{1}".format(variable,type(variable))05??06#?encoding07encode?=?json.dumps(variable)08print?"Encoded?{0}?-?{1}".format(encode,type(encode))09??10#deccoding11decoded?=?json.loads(encode)12print?"Decoded?{0}?-?{1}".format(decoded,type(decoded))13??14#?output15??16#?Original?['hello',?42,?[1,?'two'],?'apple']?-?<type?'list'="">17#?Encoded?["hello",?42,?[1,?"two"],?"apple"]?-?<type?'str'="">18#?Decoded?[u'hello',?42,?[1,?u'two'],?u'apple']?-?<type?'list'="">

?

这样更紧凑,而且最重要的是这样与JavaScript和许多其他语言兼容。然而对于复杂的对象,其中的一些信息可能丢失。

压缩字符

当谈起压缩时我们通常想到文件,比如ZIP结构。在Python中可以压缩长字符,不涉及任何档案文件。

01import?zlib02??03string?=??"""???Lorem?ipsum?dolor?sit?amet,?consectetur04????????????????adipiscing?elit.?Nunc?ut?elit?id?mi?ultricies05????????????????adipiscing.?Nulla?facilisi.?Praesent?pulvinar,06????????????????sapien?vel?feugiat?vestibulum,?nulla?dui?pretium?orci,07????????????????non?ultricies?elit?lacus?quis?ante.?Lorem?ipsum?dolor08????????????????sit?amet,?consectetur?adipiscing?elit.?Aliquam09????????????????pretium?ullamcorper?urna?quis?iaculis.?Etiam?ac?massa10????????????????sed?turpis?tempor?luctus.?Curabitur?sed?nibh?eu?elit11????????????????mollis?congue.?Praesent?ipsum?diam,?consectetur?vitae12????????????????ornare?a,?aliquam?a?nunc.?In?id?magna?pellentesque13????????????????tellus?posuere?adipiscing.?Sed?non?mi?metus,?at?lacinia14????????????????augue.?Sed?magna?nisi,?ornare?in?mollis?in,?mollis15????????????????sed?nunc.?Etiam?at?justo?in?leo?congue?mollis.16????????????????Nullam?in?neque?eget?metus?hendrerit?scelerisque17????????????????eu?non?enim.?Ut?malesuada?lacus?eu?nulla?bibendum18????????????????id?euismod?urna?sodales.?"""19??20print?"Original?Size:?{0}".format(len(string))21??22compressed?=?zlib.compress(string)23print?"Compressed?Size:?{0}".format(len(compressed))24??25decompressed?=?zlib.decompress(compressed)26print?"Decompressed?Size:?{0}".format(len(decompressed))27??28#?output29??30#?Original?Size:?102231#?Compressed?Size:?42332#?Decompressed?Size:?1022

?

?注册Shutdown函数

有可模块叫atexit,它可以让你在脚本运行完后立马执行一些代码。

假如你想在脚本执行结束时测量一些基准数据,比如运行了多长时间:

01import?atexit02import?time03import?math04??05def?microtime(get_as_float?=?False)?:06????if?get_as_float:07????????return?time.time()08????else:09????????return?'%f?%d'?%?math.modf(time.time())10start_time?=?microtime(False)11atexit.register(start_time)12??13def?shutdown():14????global?start_time15????print?"Execution?took:?{0}?seconds".format(start_time)16??17atexit.register(shutdown)18??19#?Execution?took:?0.297000?1387135607?seconds20#?Error?in?atexit._run_exitfuncs:21#?Traceback?(most?recent?call?last):22#???File?"C:\Python27\lib\atexit.py",?line?24,?in?_run_exitfuncs23#?????func(*targs,?**kargs)24#?TypeError:?'str'?object?is?not?callable25#?Error?in?sys.exitfunc:26#?Traceback?(most?recent?call?last):27#???File?"C:\Python27\lib\atexit.py",?line?24,?in?_run_exitfuncs28#?????func(*targs,?**kargs)29#?TypeError:?'str'?object?is?not?callable

?

打眼看来很简单。只需要将代码添加到脚本的最底层,它将在脚本结束前运行。但如果脚本中有一个致命错误或者脚本被用户终止,它可能就不运行了。

当你使用atexit.register()时,你的代码都将执行,不论脚本因为什么原因停止运行。

结论

你是否意识到那些不是广为人知Python特性很有用?请在评论处与我们分享。谢谢你的阅读!

本文地址:http://www.oschina.net/translate/python-functions

原文地址:http://pypix.com/tools-and-tips/python-functions/

热点排行