`
nanfang
  • 浏览: 8654 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

Python隐藏功能

 
阅读更多

本文主要内容来自StackOverflow上的一个热贴:http://stackoverflow.com/questions/101268/hidden-features-of-python,我进行了些翻译和整理工作。希望对大家有帮助,同时此文遵循GPL,可以随意转载,只要能帮到每个喜爱Python的程序员就好。

 

---------------正文开始---------------

 

1. 函数参数解箱(Function argument unpacking)

def draw_point(x, y):
    # do some magic

point_foo = (3, 4)
point_bar = {'y': 3, 'x': 2}

draw_point(*point_foo)
draw_point(**point_bar)

 这个其实不算太隐藏的功能了,每个python程序员都应该知道

 

2. 大括号

如果你不想使用缩进,而是使用C语言风格的大括号来定义函数块,那么这样:

from __future__ import braces

这个也许是最没用的隐藏特性

 

3. 链式的比较操作

看代码就明白了:

>>> x = 5
>>> 1 < x < 10
True
>>> 10 < x < 20 
False
>>> x < 10 < x*10 < 100
True
>>> 10 > x <= 9
True
>>> 5 == x > 4
True

 比方说,你想写 if x > 1 and x <10,那么写成 if 1<x <10,这样更简单并且表达力更强

 

4. 装饰器(Decorator)

Decorator可以用一个函数给另外一个函数上个套,看代码

>>> def print_args(function):
>>>     def wrapper(*args, **kwargs):
>>>         print 'Arguments:', args, kwargs
>>>         return function(*args, **kwargs)
>>>     return wrapper

>>> @print_args
>>> def write(text):
>>>     print text

>>> write('foo')
Arguments: ('foo',) {}
foo

这里的write('foo'),其实等于 print_args(write('foo')),装饰器有点像Java的annotation,但是简单,优雅,直接了当的多了。装饰器还有很多更深入的用法,建议大家google深入学习一下

 

5. 字典的get方法

对于一个字典(dict) d,除了可以用d['key']访问元素,也可以用d.get('key')。当字典不包含某键值时,前一种方法会报异常,而后一种则会返回一个默认值,缺省的默认值是None。下面代码展示这种用法:

sum[value] = sum.get(value, 0) + 1 

 

6. Doctest: 文档注释和单元测试写到一起

这个需要用到doctest这个内置module,下面的例子来自Python文档:

def factorial(n):
    """Return the factorial of n, an exact integer >= 0.

    If the result is small enough to fit in an int, return an int.
    Else return a long.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    """

    import math
    if not n >= 0:
        raise ValueError("n must be >= 0")
    if math.floor(n) != n:
        raise ValueError("n must be exact integer")
    if n+1 == n:  # catch a value like 1e300
        raise OverflowError("n too large")
    result = 1
    factor = 2
    while factor <= n:
        result *= factor
        factor += 1
    return result

def _test():
    import doctest
    doctest.testmod()    

if __name__ == "__main__":
    _test()

 

7. 切片省略语法 (Ellipsis Slicing Syntax)

Python的Slicing语法所有语言中几乎最好的,但它还支持省略号哟,见如下代码:

>>> class TestEllipsis(object):
...     def __getitem__(self, item):
...         if item is Ellipsis:
...             return "Returning all items"
...         else:
...             return "return %r items" % item
... 
>>> x = TestEllipsis()
>>> print x[2]
return 2 items
>>> print x[...]
Returning all items

也就是说要使用这种语法,需要自定义类

 

8. 列举(enumerate)

注意这不是指很多语言中支持的枚举,当遍历一个列表时,我们常需要知道元素的坐标,那么可以这样:

>>> a = ['a', 'b', 'c', 'd', 'e']
>>> for index, item in enumerate(a): print index, item
...
0 a
1 b
2 c
3 d
4 e
>>>
 

9. for...else语法

for循环后面还可以跟个else,看下面的代码

for i in foo:
    if i == 0:
        break
else:
    print("i was never 0")
 

 else的部分总是会在循环结束后执行,除非for循环遇到break,这个语法有点绕,else这个关键字也不太好

 

10. 函数也可以作为iter()的参数

不熟悉iter的同学请先自行google之,下面的代码我直接摘抄了python文档

 

with open('mydata.txt') as fp:
    for line in iter(fp.readline, ''):
        process_line(line)

看来函数作为iter参数应该是主流才是

 

11. 创建Generator对象

如果你这么写

x=(n for n in foo if bar(n))

那你可以这么用

 

for n in x:

其实你也可以这么做达到同样的效果

 

[x = [n for n in foo if bar(n)]

但是区别就是前者产生的x是个gerenrator对象,后者的x是个list。为什么这点微妙的区别我们需要注意:性能。前者有时候比后者想能好很多。

 

12. import this

建议大家试着执行一下这行,然后你会看到

 

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

 好了,可以开始享受编程的乐趣了!

 

13. 交换变量(swapping)

如何优雅的交换两个变量值,需要中间变量或者用匪夷所思的位操作吗?看代码吧

 

>>> a = 10
>>> b = 5
>>> a, b
(10, 5)

>>> a, b = b, a
>>> a, b
(5, 10)
 

14. 列表跳格 (list stepping)

直接看段代码

 

a = [1,2,3,4,5]
>>> a[::2]  # iterate over the whole list in 2-increments
[1,3,5]

 每隔两格去一个元素,那么能倒着取吗,可以:

 

>>> a[::-1]
[5,4,3,2,1]
 

15. __missing__

通过覆盖这个函数对dict扩展,给不存在的key一个默认的值

>>> class MyDict(dict):
...  def __missing__(self, key):
...   self[key] = rv = []
...   return rv
... 
>>> m = MyDict()
>>> m["foo"].append(1)
>>> m["foo"].append(2)
>>> dict(m)
{'foo': [1, 2]}

 实际上,python的collections模块里提供了一个defaultdict类,提供了类似的功能

>>> from collections import defaultdict
>>> m = defaultdict(list)
>>> m["foo"].append(1)
>>> m["foo"].append(2)
>>> dict(m)
{'foo': [1, 2]}
 

16. 多行正则表达式

为了使正则式更好读,我们可以把它拆成多行

>>> pattern = """
... ^                   # beginning of string
... M{0,4}              # thousands - 0 to 4 M's
... (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
...                     #            or 500-800 (D, followed by 0 to 3 C's)
... (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
...                     #        or 50-80 (L, followed by 0 to 3 X's)
... (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
...                     #        or 5-8 (V, followed by 0 to 3 I's)
... $                   # end of string
... """
>>> re.search(pattern, 'M', re.VERBOSE)
 其实重点就是这个re.VERBOSE了

 

17. 带名字的字符串格式化(format)

大家对字符串格式化应该已经很熟悉了,除了使用%s作为占位符,我们还可以给占位符一个名字

>>> print "The %(foo)s is %(bar)i." % {'foo': 'answer', 'bar':42}
The answer is 42.

>>> foo, bar = 'question', 123

>>> print "The %(foo)s is %(bar)i." % locals()
The question is 123.

 还有一种新的方式

>>> print("The {foo} is {bar}".format(foo='answer', bar=42))

 

18. 嵌套的list conprehensions

如果想写一个双重循环的话,考虑用用下面两种方式

[(i,j) for i in range(3) for j in range(i) ]    
((i,j) for i in range(4) for j in range(i) )

 提醒,第一种产生一个list,第二种产生一个generator

 

19. 动态创建一个新类型

>>> NewType = type("NewType", (object,), {"x": "hello"})
>>> n = NewType()
>>> n.x
"hello"

 上面代码等价于

>>> class NewType(object):
>>>     x = "hello"
>>> n = NewType()
>>> n.x
"hello"

可能不常用,但是还是知道为好

 

20. *.pth文件

Python比较搓的地方是它混乱的包管理,除了在环境变量PYTHONPATH里加依赖,可以考虑使用*.pth文件。做法是找到你的site-packages目录,在里面放一个*.pth文件,里面写上你需要加载的路径。那么这些路径就会自动加载到sys.path

 

21. ROT13 encoding

ROT13是啥?我google了一下后,它的全称叫回转13位,是一种在源代码里隐藏八卦信息的编码

如果在你的代码头加上

# -*- coding: rot13 -*-

 那么大家可以用ROT13来写代码了,代码这可能长成这样

cevag "Uryyb fgnpxbiresybj!".rapbqr("rot13")

 

22. Debug正则表达式

其实就是利用re.DEBUG这个flag了

>>> re.compile("^\[font(?:=(?P<size>[-+][0-9]{1,2}))?\](.*?)[/font]",
    re.DEBUG)
at at_beginning
literal 91
literal 102
literal 111
literal 110
literal 116
max_repeat 0 1
  subpattern None
    literal 61
    subpattern 1
      in
        literal 45
        literal 43
      max_repeat 1 2
        in
          range (48, 57)
literal 93
subpattern 2
  min_repeat 0 65535
    any None
in
  literal 47
  literal 102
  literal 111
  literal 110
  literal 116

 如果还想同时用其他的flag咋搞

>>> re.compile("""
 ^              # start of a line
 \[font         # the font tag
 (?:=(?P<size>  # optional [font=+size]
 [-+][0-9]{1,2} # size specification
 ))?
 \]             # end of tag
 (.*?)          # text between the tags
 \[/font\]      # end of the tag
 """, re.DEBUG|re.VERBOSE|re.DOTALL)

 

23. 给生成器(generator)传值

比如你有以下函数

def mygen():
    """Yield 5 until something else is passed back via send()"""
    a = 5
    while True:
        f = (yield a) #yield a and possibly get f in return
        if f is not None: 
            a = f  #store the new value

 可以这样给它传值

>>> g = mygen()
>>> g.next()
5
>>> g.next()
5
>>> g.send(7)  #we send this back to the generator
7
>>> g.next() #now it will yield 7 until we send something else
7
 

24. 交互模式下用tab做自动补齐

如何做到:

try:
    import readline
except ImportError:
    print "Unable to load readline module."
else:
    import rlcompleter
    readline.parse_and_bind("tab: complete")


>>> class myclass:
...    def function(self):
...       print "my function"
... 
>>> class_instance = myclass()
>>> class_instance.<TAB>
class_instance.__class__   class_instance.__module__
class_instance.__doc__     class_instance.function
>>> class_instance.f<TAB>unction()

使用这个特性必须设置PYTHONSTARTUP变量

如果使用iPython,已经自动有个这个特性了,所以说这个特性用处不大了

 

25. 三元表达式(ternary expression)

最基本的形式

x = 3 if (y == 1) else 2

在这个基础上我们可以做个if else链了

x = 3 if (y == 1) else 2 if (y == -1) else 1

然后,咱还可以这样执行函数

(func1 if y == 1 else func2)(arg1, arg2) 

初始话对象也可以

x = (class1 if y == 1 else class2)(arg1, arg2)

 

26. try/except/else

出了for, 连try也可以加个elsetry:

try:
  put_4000000000_volts_through_it(parrot)
except Voom:
  print "'E's pining!"
else:
  print "This parrot is no more!"
finally:
  end_sketch()

 else里的语句在不发生异常时执行,这样做的好处是避免捕捉else里的异常

 

26. with语句

这个我觉的是最有用的功能了,只有2.6以后的版本才支持

常用的一个场景是,打开一个文件,读写,然后关闭,那么代码看起来是

fp = open('test.txt', 'w')
f.write('hello!')
fp.close()

用了with就漂亮多了

with open('foo.txt', 'w') as f:
    f.write('hello!')

看,不用自己写close()了,至于with原理,建议大家深入研究下

 

---------------正文结束---------------

翻译完这篇帖子,我感觉还不够过瘾啊,还有很多好的特性和类库值得挖掘,希望大家能够补充
下篇文章我将总结下我使用Python一年半以来所用过的最有用的类库和模块,敬请期待...

分享到:
评论

相关推荐

    基于Python的图像信息隐藏技术的实现.zip

    本次就是利用python技术,结合LSB等算法内容,来搭建一款图像隐藏的软件,通过该软件实现信息的隐藏传输功能。 此次设计的图像隐藏需要具备以下的性能要求,只有做到了以下的一些指标要求才能够保证信息隐藏过程是...

    HMM, python 隐藏 马尔可夫 模型框架.zip

    HMM, python 隐藏 马尔可夫 模型框架 HMMnumpy/python只隐藏 马尔可夫 模型框架。 不需要其他依赖项。这里实现( 其他很多) 基于以下文件: "隐藏 马尔可夫 模型和语音识别中选择的应用的教程,RABINER 1989"主要支持...

    基于python的图像信息隐藏算法的实现.zip

    由于此次的网站搭建内容比较简单,主要突出的功能就是图像隐藏,除此之外只有一些简单的菜单模块,因此整体开发的难度比较低,使用python语言开发是基于该语言的易懂、易开发的特性,能够提供很好的开发结果。...

    python项目图像信息隐藏技术设计.zip

    该项目是一个专注于图像信息隐藏技术的设计系统,使用Python语言进行开发。 1. **系统设计**:项目主要目的是实现将信息隐藏在图像中,以实现隐秘传输或保护知识产权。 2. **技术实现**: - 使用了Python的PIL库来...

    Python Graphics

    从基本的Python函数开始,设置绘图空间并生成2维和3维对象,您将学习如何构建更复杂的对象,翻译和旋转它们,删除隐藏的线条,引入阴影以添加真实感,以及投影图像可视化任何数据集。最后一章包括科学和工程领域的几...

    分享6个隐藏的python功能

    小编在以前给大家介绍过python一些很少用到的功能,这次我们给大家分享了6个隐藏的python功能,学习下。 在python的设计哲学中,有这么一条内容:“Simple is better than complex”,简单的代码比复杂的要好,这也...

    python091图像信息隐藏技术设计.zip

    无论是学业预警、自主评测,还是电影推荐、二维码识别,或者是数据加密、信息隐藏,这些项目充分利用了Python语言的优势,为用户提供了高效、灵活的解决方案。 Python语言作为一种高级编程语言,具有简洁、可读性强...

    Python毕业设计-python的图像信息隐藏技术设计.zip

    该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载, 1. 技术组成 前端: html 后台框架:Python,建议使用 3.7 开发环境:...

    Python毕业设计-python的基于图像的信息隐藏技术研究.zip

    该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载, 1. 技术组成 前端: html 后台框架:Python,建议使用 3.7 开发环境:...

    python081基于图像的信息隐藏技术研究.zip

    无论是学业预警、自主评测,还是电影推荐、二维码识别,或者是数据加密、信息隐藏,这些项目充分利用了Python语言的优势,为用户提供了高效、灵活的解决方案。 Python语言作为一种高级编程语言,具有简洁、可读性强...

    Python毕业设计--python的基于lsb算法与rsa算法的信息隐藏算法实现(django).zip

    该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载, 1. 技术组成 前端: html 后台框架:Python 开发环境:pycharm 数据库可视...

    python项目基于图像的信息隐藏技术研究.zip

    该项目是一个使用Python语言开发的基于图像的信息隐藏技术研究。 1. **系统设计**:项目主要目的是通过将信息嵌入到图像中,实现信息的隐藏和保护。这通常用于保密通信、版权保护等场景。 2. **技术实现**: - ...

    Python数据分析实践:Python数据分析概述-new.ppt

    教学单元一.Python数据分析概述 Python高级编程 -Python数据分析与应用 课程内容 认识数据分析 1 2 3 4 熟悉Python数据分析的工具 Jupyter Notebook 常用功能 安装 配置数据分析环境 认识数据分析 数据分析是指用...

    python128web漏洞挖掘技术的研究_django.zip

    无论是学业预警、自主评测,还是电影推荐、二维码识别,或者是数据加密、信息隐藏,这些项目充分利用了Python语言的优势,为用户提供了高效、灵活的解决方案。 Python语言作为一种高级编程语言,具有简洁、可读性强...

    (基于python的毕业设计)图像信息隐藏技术设计(源码+说明+演示视频).zip

    (基于python的毕业设计)图像信息隐藏技术设计(源码+说明+演示视频),本科毕业设计高分项目。 【项目技术】 python+Django+mysql 【实现功能】 主要是围绕着数据隐藏的功能,整体的页面设计保持简洁大方的内容显示,...

Global site tag (gtag.js) - Google Analytics