python函数有哪些特性_你需要知道的实用Python函数和特性

虽然已经使用了Python很多年,但我们仍然经常被我们所不熟悉的python函数或者特性所难住。有一些甚至是非常有用,但我们并未好好利用。对此,我特意编写了一份关于实用Python函数或者特性的清单,关于清单上的内容,我们每一个Python开发者都应该熟悉掌握。

Functionswith Arbitrary Number of Arguments  带任意数量参数的函数

你可能已经知道,Python允许开发者自定义可选参数的函数。但是这里有一个方法,允许开发者完全自定义任意数量参数的函数。

首先,下面是一个关于可选参数的举例:

def function(arg1="",arg2=""):

print "arg1: {0}".format(arg1)

print "arg2: {0}".format(arg2)

function("Hello", "World")

# prints args1: Hello

# prints args2: World

function()

# prints args1:

# prints args2:        现在,让我们看看如何定义一个可接受任意数量参数的函数。这次我们会采用

def foo(*args): # just use "*" to collect all remaining arguments into a tuple

numargs = len(args)

print "Number of arguments: {0}".format(numargs)

for i, x in enumerate(args):

print "Argument {0} is: {1}".format(i,x)

foo()

# Number of arguments: 0

foo("hello")

# Number of arguments: 1

# Argument 0 is: hello

foo("hello","World","Again")

# Number of arguments: 3

# Argument 0 is: hello

# Argument 1 is: World

# Argument 2 is: Again

Using Glob() to Find Files  使用Glob()函数寻找文档

许多Python函数拥有很长的描述性名称。然而,一个拥有像Glob()这样名称的函数,除非你在其它地方深入了解过,否则你很难准确理解这个函数的真正用途。实际上,你可以把Glob()函数当作listdir()函数的更强大版本来使用。

import glob

# get all py files

files = glob.glob('*.py')

print files

# Output

# ['arg.py', 'g.py', 'shut.py', 'test.py']       你也可以如下面例子一样获取多种类型的文件:

import itertools as it, glob

def multiple_file_types(*patterns):

return it.chain.from_iterable(glob.glob(pattern) for pattern in patterns)

for filename in multiple_file_types("*.txt", "*.py"): # add as many filetype arguements

print filename

# output

#=========#

# test.txt

# arg.py

# g.py

# shut.py

# test.py

如果你想要获得每一个文件的完整路径,可以在函数返回时调用realpath()函数:

import itertools as it, glob, os

def multiple_file_types(*patterns):

return it.chain.from_iterable(glob.glob(pattern) for pattern in patterns)

for filename in multiple_file_types("*.txt", "*.py"): # add as many filetype arguements

realpath = os.path.realpath(filename)

print realpath

# output

#=========#

# C:\xxx\pyfunc\test.txt

# C:\xxx\pyfunc\arg.py

# C:\xxx\pyfunc\g.py

# C:\xxx\pyfunc\shut.py

# C:\xxx\pyfunc\test.py

Debugging  调试

下面的许多例子使用了inspect模块。这一模块在程序调试的时候是非常有用的,而且在使用之后,相信你能够有更多收获。在这篇文章中,我们并不会列举关于inspect模块的每一项用处,但我会展示一些非常实用的小例子:

import logging, inspect

logging.basicConfig(level=logging.INFO,

format='%(asctime)s %(levelname)-8s %(filename)s:%(lineno)-4d: %(message)s',

datefmt='%m-%d %H:%M',

)

logging.debug('A debug message')

logging.info('Some information')

logging.warning('A shot across the bow')

def test():

frame,filename,line_number,function_name,lines,index=\

inspect.getouterframes(inspect.currentframe())[1]

print(frame,filename,line_number,function_name,lines,index)

test()

# Should print the following (with current date/time of course)

#10-19 19:57 INFO test.py:9 : Some information

#10-19 19:57 WARNING test.py:10 : A shot across the bow

#(, 'C:/xxx/pyfunc/magic.py', 16, '', ['test()\n'], 0)

GeneratingUnique ID’s  生成唯一ID

在许多情况下,你需要生成一个唯一字符串。许多人会选择使用md5()函数,但是,这并不是实现这一目的的最佳函数。

实际上,有一个专用于此目的的Python函数——uuid()函数。

import uuid

result = uuid.uuid1()

print result

# output => various attempts

# 9e177ec0-65b6-11e3-b2d0-e4d53dfcf61b

# be57b880-65b6-11e3-a04d-e4d53dfcf61b

# c3b2b90f-65b6-11e3-8c86-e4d53dfcf61b       你可能已经注意到了,尽管生成的字符串是唯一的,但是除了前面的几个字符不同之外,后面的很多字符是相同的。这主要是因为生成的字符串和计算机的网络地址有关。

为了降低生成相同字符串的可能性,你可以选择使用下面的两个函数。

import hmac,hashlib

key='1'

data='a'

print hmac.new(key, data, hashlib.sha256).hexdigest()

m = hashlib.sha1()

m.update("The quick brown fox jumps over the lazy dog")

print m.hexdigest()

# c6e693d0b35805080632bc2469e1154a8d1072a86557778c27a01329630f8917

# 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12

Serialization  序列化

你是否曾经需要存储一个复杂变量到一个数据库或者文本文档中?你可能会想到构造一个巧妙的方法将数组或者对象转换为格式化的字符串。实际上,并没有这个必要,因为,Python已经为你准备好了实现这一目的的函数。

import pickle

variable = ['hello', 42, [1,'two'],'apple']

# serialize content

file = open('serial.txt','w')

serialized_obj = pickle.dumps(variable)

file.write(serialized_obj)

file.close()

# unserialize to produce original content

target = open('serial.txt','r')

myObj = pickle.load(target)

print serialized_obj

print myObj

#output

# (lp0

# S'hello'

# p1

# aI42

# a(lp2

# I1

# aS'two'

# p3

# aaS'apple'

# p4

# a.

# ['hello', 42, [1, 'two'], 'apple']       这是比较朴素的Python序列化方法。然而,随着

JSON近几年的流行,Python语言的研究者们决定支持

JSON的使用。现在你也可以使用

JSON来加密和解密:

import json

variable = ['hello', 42, [1,'two'],'apple']

print "Original {0} - {1}".format(variable,type(variable))

# encoding

encode = json.dumps(variable)

print "Encoded {0} - {1}".format(encode,type(encode))

#deccoding

decoded = json.loads(encode)

print "Decoded {0} - {1}".format(decoded,type(decoded))

# output

# Original ['hello', 42, [1, 'two'], 'apple'] -

# Encoded ["hello", 42, [1, "two"], "apple"] -

# Decoded [u'hello', 42, [1, u'two'], u'apple'] -         这是一种更健壮、更优秀的实现方法,而且还和javascript等其它语言兼容。然而,对于复杂对象,可能会存在信息丢失。

CompressingStrings  压缩字符串

当我们讨论压缩的时候,通常会想到归档,比如ZIP文件。在Python中,可以不使用任何归档文件来压缩长字符串。

import zlib

string = """ Lorem ipsum dolor sit amet, consectetur

adipiscing elit. Nunc ut elit id mi ultricies

adipiscing. Nulla facilisi. Praesent pulvinar,

sapien vel feugiat vestibulum, nulla dui pretium orci,

non ultricies elit lacus quis ante. Lorem ipsum dolor

sit amet, consectetur adipiscing elit. Aliquam

pretium ullamcorper urna quis iaculis. Etiam ac massa

sed turpis tempor luctus. Curabitur sed nibh eu elit

mollis congue. Praesent ipsum diam, consectetur vitae

ornare a, aliquam a nunc. In id magna pellentesque

tellus posuere adipiscing. Sed non mi metus, at lacinia

augue. Sed magna nisi, ornare in mollis in, mollis

sed nunc. Etiam at justo in leo congue mollis.

Nullam in neque eget metus hendrerit scelerisque

eu non enim. Ut malesuada lacus eu nulla bibendum

id euismod urna sodales. """

print "Original Size: {0}".format(len(string))

compressed = zlib.compress(string)

print "Compressed Size: {0}".format(len(compressed))

decompressed = zlib.decompress(compressed)

print "Decompressed Size: {0}".format(len(decompressed))

# output

# Original Size: 1022

# Compressed Size: 423

# Decompressed Size: 1022

RegisterShutdown Function  注册关闭函数

假如你想要在自己的脚本运行结束前抓取一些标志性统计数据(benchmark statistic),比如,脚本运行花费了多长时间:

import atexit

import time

import math

def microtime(get_as_float = False) :

if get_as_float:

return time.time()

else:

return '%f %d' % math.modf(time.time())

start_time = microtime(False)

atexit.register(start_time)

def shutdown():

global start_time

print "Execution took: {0} seconds".format(start_time)

atexit.register(shutdown)

# Execution took: 0.297000 1387135607 seconds

# Error in atexit._run_exitfuncs:

# Traceback (most recent call last):

# File "C:\Python27\lib\atexit.py", line 24, in _run_exitfuncs

# func(*targs, **kargs)

# TypeError: 'str' object is not callable

# Error in sys.exitfunc:

# Traceback (most recent call last):

# File "C:\Python27\lib\atexit.py", line 24, in _run_exitfuncs

# func(*targs, **kargs)

# TypeError: 'str' object is not callable        开始的时候你可能不明所以,只是简单的将这段代码添加到了你的脚本的底部,而且,在脚本运行结束前,这段代码成功运行。但是,如果发生灾难性的错误,或者脚本运行被人为的中止,这段代码都将再一次停止运行。

当使用了

atexit.register()之后,你会发现,不管脚本为何停止运行,这段代码都将运行。

Conclusion  结论

你是否还知道其他一些不流行但非常实用的Python特性呢?请在评论中和我们分享吧!最后,谢谢您的阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值