你需要知道的、有用的 Python 功能和特点
在使用Python多年以后,我偶然发现了一些我们过去不知道的功能和特性。一些可以说是非常有用,但却没有充分利用。考虑到这一点,我编辑了一些你应该了解的Python功能特色。
带任意数量参数的函数你可能已经知道了Python允许你定义可选参数。但还有一个方法,可以定义函数任意数量的参数。
首先,看下面是一个只定义可选参数的例子
01
def
?function(arg1
=
"
",arg2="
"):
02
????
print
?"arg1:?{0}"
.
format
(arg1)
03
????
print
?"arg2:?{0}"
.
format
(arg2)
04
?
?05
function(
"Hello"
,?
"World"
)
06
#?prints?args1:?Hello
07
#?prints?args2:?World
08
?
?09
function()
10
#?prints?args1:
11
#?prints?args2:
现在,让我们看看怎么定义一个可以接受任意参数的函数。我们利用元组来实现。
01
def
?foo(
*
args):?
#?just?use?"*"?to?collect?all?remaining?arguments?into?a?tuple
02
????
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
?
?07
foo()
08
#?Number?of?arguments:?0
09
?
?10
foo(
"hello"
)
11
#?Number?of?arguments:?1
12
#?Argument?0?is:?hello
13
?
?14
foo(
"hello"
,
"World"
,
"Again"
)
15
#?Number?of?arguments:?3
16
#?Argument?0?is:?hello
17
#?Argument?1?is:?World
18
#?Argument?2?is:?Again
使用Glob()查找文件大多Python函数有着长且具有描述性的名字。但是命名为glob()的函数你可能不知道它是干什么的除非你从别处已经熟悉它了。
它像是一个更强大版本的listdir()函数。它可以让你通过使用模式匹配来搜索文件。
1
import
?glob
2
?
?3
#?get?all?py?files
4
files?
=
?glob.glob(
'*.py'
)
5
print
?files
6
?
?7
#?Output
8
#?['arg.py',?'g.py',?'shut.py',?'test.py']
?
你可以像下面这样查找多个文件类型:
01
import
?itertools?as?it,?glob
02
?
?03
def
?multiple_file_types(
*
patterns):
04
????
return
?it.chain.from_iterable(glob.glob(pattern)?
for
?pattern?
in
?patterns)
05
?
?06
for
?filename?
in
?multiple_file_types(
"*.txt"
,?
"*.py"
):?
#?add?as?many?filetype?arguements
07
????
print
?filename
08
?
?09
#?output
10
#=========#
11
#?test.txt
12
#?arg.py
13
#?g.py
14
#?shut.py
15
#?test.py
?
如果你想得到每个文件的绝对路径,你可以在返回值上调用realpath()函数:
01
import
?itertools?as?it,?glob,?os
02
?
?03
def
?multiple_file_types(
*
patterns):
04
????
return
?it.chain.from_iterable(glob.glob(pattern)?
for
?pattern?
in
?patterns)
05
?
?06
for
?filename?
in
?multiple_file_types(
"*.txt"
,?
"*.py"
):?
#?add?as?many?filetype?arguements
07
????
realpath?
=
?os.path.realpath(filename)
08
????
print
?realpath
09
?
?10
#?output
11
#=========#
12
#?C:\xxx\pyfunc\test.txt
13
#?C:\xxx\pyfunc\arg.py
14
#?C:\xxx\pyfunc\g.py
15
#?C:\xxx\pyfunc\shut.py
16
#?C:\xxx\pyfunc\test.py
?调试下面的例子使用inspect模块。该模块用于调试目的时是非常有用的,它的功能远比这里描述的要多。
这篇文章不会覆盖这个模块的每个细节,但会展示给你一些用例。
01
import
?logging,?inspect
02
?
?03
logging.basicConfig(level
=
logging.INFO,
04
????
format
=
'%(asctime)s?%(levelname)-8s?%(filename)s:%(lineno)-4d:?%(message)s'
,
05
????
datefmt
=
'%m-%d?%H:%M'
,
06
????
)
07
logging.debug(
'A?debug?message'
)
08
logging.info(
'Some?information'
)
09
logging.warning(
'A?shot?across?the?bow'
)
10
?
?11
def
?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
?
?16
test()
17
?
?18
#?Should?print?the?following?(with?current?date/time?of?course)
19
#10-19?19:57?INFO?????test.py:9???:?Some?information
20
#10-19?19:57?WARNING??test.py:10??:?A?shot?across?the?bow
21
#(,?'C:/xxx/pyfunc/magic.py',?16,?'',?['test()\n'],?0)
?
生成唯一ID在有些情况下你需要生成一个唯一的字符串。我看到很多人使用md5()函数来达到此目的,但它确实不是以此为目的。
其实有一个名为uuid()的Python函数是用于这个目的的。
1
import
?uuid
2
result?
=
?uuid.uuid1()
3
print
?result
4
?
?5
#?output?=>?various?attempts
6
#?9e177ec0-65b6-11e3-b2d0-e4d53dfcf61b
7
#?be57b880-65b6-11e3-a04d-e4d53dfcf61b
8
#?c3b2b90f-65b6-11e3-8c86-e4d53dfcf61b
?
你可能会注意到,即使字符串是唯一的,但它们后边的几个字符看起来很相似。这是因为生成的字符串与电脑的MAC地址是相联系的。
为了减少重复的情况,你可以使用这两个函数。
01
import
?hmac,hashlib
02
key
=
'1'
03
data
=
'a'
04
print
?hmac.new(key,?data,?hashlib.sha256).hexdigest()
05
?
?06
m?
=
?hashlib.sha1()
07
m.update(
"The?quick?brown?fox?jumps?over?the?lazy?dog"
)
08
print
?m.hexdigest()
09
?
?10
#?c6e693d0b35805080632bc2469e1154a8d1072a86557778c27a01329630f8917
11
#?2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
序列化你曾经需要将一个复杂的变量存储在数据库或文本文件中吧?你不需要想一个奇特的方法将数组或对象格转化为式化字符串,因为Python已经提供了此功能。
01
import
?pickle
02
?
?03
variable?
=
?[
'hello'
,?
42
,?[
1
,
'two'
],
'apple'
]
04
?
?05
#?serialize?content
06
file
?=
?open
(
'serial.txt'
,
'w'
)
07
serialized_obj?
=
?pickle.dumps(variable)
08
file
.write(serialized_obj)
09
file
.close()
10
?
?11
#?unserialize?to?produce?original?content
12
target?
=
?open
(
'serial.txt'
,
'r'
)
13
myObj?
=
?pickle.load(target)
14
?
?15
print
?serialized_obj
16
print
?myObj
17
?
?18
#output
19
#?(lp0
20
#?S'hello'
21
#?p1
22
#?aI42
23
#?a(lp2
24
#?I1
25
#?aS'two'
26
#?p3
27
#?aaS'apple'
28
#?p4
29
#?a.
30
#?['hello',?42,?[1,?'two'],?'apple']
?
这是一个原生的Python序列化方法。然而近几年来JSON变得流行起来,Python添加了对它的支持。现在你可以使用JSON来编解码。
01
import
?json
02
?
?03
variable?
=
?[
'hello'
,?
42
,?[
1
,
'two'
],
'apple'
]
04
print
?"Original?{0}?-?{1}"
.
format
(variable,
type
(variable))
05
?
?06
#?encoding
07
encode?
=
?json.dumps(variable)
08
print
?"Encoded?{0}?-?{1}"
.
format
(encode,
type
(encode))
09
?
?10
#deccoding
11
decoded?
=
?json.loads(encode)
12
print
?"Decoded?{0}?-?{1}"
.
format
(decoded,
type
(decoded))
13
?
?14
#?output
15
?
?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中可以压缩长字符,不涉及任何档案文件。
01
import
?zlib
02
?
?03
string?
=
??"""???Lorem?ipsum?dolor?sit?amet,?consectetur
04
????????????????
adipiscing?elit.?Nunc?ut?elit?id?mi?ultricies
05
????????????????
adipiscing.?Nulla?facilisi.?Praesent?pulvinar,
06
????????????????
sapien?vel?feugiat?vestibulum,?nulla?dui?pretium?orci,
07
????????????????
non?ultricies?elit?lacus?quis?ante.?Lorem?ipsum?dolor
08
????????????????
sit?amet,?consectetur?adipiscing?elit.?Aliquam
09
????????????????
pretium?ullamcorper?urna?quis?iaculis.?Etiam?ac?massa
10
????????????????
sed?turpis?tempor?luctus.?Curabitur?sed?nibh?eu?elit
11
????????????????
mollis?congue.?Praesent?ipsum?diam,?consectetur?vitae
12
????????????????
ornare?a,?aliquam?a?nunc.?In?id?magna?pellentesque
13
????????????????
tellus?posuere?adipiscing.?Sed?non?mi?metus,?at?lacinia
14
????????????????
augue.?Sed?magna?nisi,?ornare?in?mollis?in,?mollis
15
????????????????
sed?nunc.?Etiam?at?justo?in?leo?congue?mollis.
16
????????????????
Nullam?in?neque?eget?metus?hendrerit?scelerisque
17
????????????????
eu?non?enim.?Ut?malesuada?lacus?eu?nulla?bibendum
18
????????????????
id?euismod?urna?sodales.?"""
19
?
?20
print
?"Original?Size:?{0}"
.
format
(
len
(string))
21
?
?22
compressed?
=
?zlib.compress(string)
23
print
?"Compressed?Size:?{0}"
.
format
(
len
(compressed))
24
?
?25
decompressed?
=
?zlib.decompress(compressed)
26
print
?"Decompressed?Size:?{0}"
.
format
(
len
(decompressed))
27
?
?28
#?output
29
?
?30
#?Original?Size:?1022
31
#?Compressed?Size:?423
32
#?Decompressed?Size:?1022
?
?注册Shutdown函数有可模块叫atexit,它可以让你在脚本运行完后立马执行一些代码。
假如你想在脚本执行结束时测量一些基准数据,比如运行了多长时间:
01
import
?atexit
02
import
?time
03
import
?math
04
?
?05
def
?microtime(get_as_float?
=
?False
)?:
06
????
if
?get_as_float:
07
????????
return
?time.time()
08
????
else
:
09
????????
return
?'%f?%d'
?%
?math.modf(time.time())
10
start_time?
=
?microtime(
False
)
11
atexit.register(start_time)
12
?
?13
def
?shutdown():
14
????
global
?start_time
15
????
print
?"Execution?took:?{0}?seconds"
.
format
(start_time)
16
?
?17
atexit.register(shutdown)
18
?
?19
#?Execution?took:?0.297000?1387135607?seconds
20
#?Error?in?atexit._run_exitfuncs:
21
#?Traceback?(most?recent?call?last):
22
#???File?"C:\Python27\lib\atexit.py",?line?24,?in?_run_exitfuncs
23
#?????func(*targs,?**kargs)
24
#?TypeError:?'str'?object?is?not?callable
25
#?Error?in?sys.exitfunc:
26
#?Traceback?(most?recent?call?last):
27
#???File?"C:\Python27\lib\atexit.py",?line?24,?in?_run_exitfuncs
28
#?????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/