初步学习Python高级语法

作者: | 更新日期:

最近由于工作需要,需要快速学习python的高级语法.现在把学习的东西记录下来。

本文首发于公众号:天空的代码世界,微信号:tiankonguse

python 高级特性

切片

切片取一个list或tuple的部分元素是非常常见的操作。

假设有下面的list,要取前三个数据。

L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']

最笨的方法

[L[0], L[1], L[2]]

循环方法

r = []
n = 3
for i in range(n):
    r.append(L[i])

切片方法

L[0:3]

省略0索引的方法

L[:3]

取倒数的两个

L[-2:]
# ['Bob', 'Jack']

指定等差 取偶数个

L[:10:2]

迭代

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们成为迭代(Iteration)。

在Python中,迭代是通过for … in来完成的.

dict 也可以使用 for in 来迭代。但是由于 dict 有 key 和 value ,且dict是依靠 key 来储存的,所以迭代出的是 key.

如果想得到key 和 val,可以使用下面的方法。

d = {'a': 1, 'b': 2, 'c': 3}
for value in d.itervalues():
    print value
    
for k, v in d.iteritems():
    print "key:",key,",value:",value

字符串也是可迭代.

for ch in 'ABC':
    print ch

当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行

那么,如何判断一个对象是可迭代对象呢?

方法是通过collections模块的Iterable类型判断:

from collections import Iterable
isinstance('abc', Iterable) # True
isinstance(123, Iterable) # False

对 list 迭代,得到下标和值。

for i, value in enumerate(['A', 'B', 'C']):
    print i, value

列表生成式

[x * x for x in range(1, 11)] # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

例如列出当前目录下的所有文件和目录名

import os # 导入os模块,模块的概念后面讲到
[d for d in os.listdir('.')] # os.listdir可以列出文件和目录

函数式编程

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。

而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

map 函数

比如我们有一个函数f(x)=x^2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上

def f(x):
    return x * x
map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) # [1, 4, 9, 16, 25, 36, 49, 64, 81]

reduce 函数

reduce把结果继续和序列的下一个元素做累积计算

比方说对一个序列求和

def add(x, y):
    return x + y
reduce(add, [1, 3, 5, 7, 9]) # 25

字符串转化为整数的函数

def fn(x, y):
    return x * 10 + y
    
def char2num(s):
    return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    
def str2int(s):
    return reduce(fn, map(char2num, s))

排序算法

# 内置类型默认排序
sorted([36, 5, 12, 9, 21]) # [5, 9, 12, 21, 36]

# 自定义排序函数
def reversed_cmp(x, y):
    if x > y:
        return -1
    if x < y:
        return 1
    return 0

sorted([36, 5, 12, 9, 21], reversed_cmp) #[36, 21, 12, 9, 5]

函数作为返回值

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。

匿名函数

关键字lambda表示匿名函数

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。

此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数

def char2num(s):
    return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]

def str2int(s):
    return reduce(lambda x,y: x*10+y, map(char2num, s))

装饰器

由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。

函数对象有一个__name__属性,可以拿到函数的名字.

假设我们要增强函数的功能,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

本质上,decorator就是一个返回函数的高阶函数。

借助Python的@语法,把decorator置于函数的定义处.

Python内置的functools.wraps把原始函数的__name__等属性复制到wrapper()函数中.

import functools

def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print 'call %s():' % func.__name__
        return func(*args, **kw)
    return wrapper
    
    
@log
def now():
    print '2013-12-25'

偏函数

import functools
int2 = functools.partial(int, base=2);

等价于

def partial(func, base):
    def wrapper(args):
        return func(args, base);
    return wrapper

int2 = partial(int, 2);

print int('10',2);

print int2('10');

只不过,偏函数是依赖参数的名字来自动填充的,而高级函数必须知道具体的函数参数列表。

模块

在Python中,一个.py文件就称之为一个模块(Module)

为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。

引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。

每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。

init.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块

导入模块

import sys

导入模块时,还可以使用别名

try:
    import cStringIO as StringIO
except ImportError: # 导入失败会捕获到ImportError
    import StringIO

作用域

正常的函数和变量名是公开的(public),可以被直接引用

Python并没有一种方法可以完全限制访问private函数或变量,但是,从编程习惯上不应该引用private函数或变量。

模块搜索路径

一是直接修改sys.path,添加要搜索的目录 第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。

本文首发于公众号:天空的代码世界,微信号:tiankonguse
如果你想留言,可以在微信里面关注公众号进行留言。

关注公众号,接收最新消息

tiankonguse +
穿越