Python 3 知识点查漏补缺2

补充

最近读了一本名叫Intermediate Python的书,对应的中文版是Python进阶,本文是读完之后的笔记。

列表

调试器

Python也有调试器,和gdb的指令基本一致。进入debug有两种方法,一种是运行程序的时候执行python -m pdb xxxx.py;另一种是使用pdb模块的set_trace()方法在函数中间设置断点。

有没有用?求同存异吧。

可迭代对象、迭代器、迭代

Python中任意对象,只要实现了可以返回一个迭代器的__iter__方法,或定义了可以支持下标索引的__getitem__方法,那么它就是一个可迭代对象

任何对象,只要定义了__next__方法,它就是一个迭代器

当我们是使用一个循环来遍历某个东西时,这个过程就是迭代

Map, Filter, Reduce

通常和lambda表达式结合一起使用,但也可以是一个函数地址。格式均为:

Map/Filter/Reduce((lambda expression)|fn, items)

其中items必须是个可迭代的对象。

Map是将expression作用于items每个成员上,并返回一个新的可迭代对象。其lambda式或fn一般是一个参数。Map还可以这样写:

def multiply(x):
    return (x*x)
def add(x):
    return (x+x)

funcs = [multiply, add]
for i in range(5):
    value = map(lambda x: x(i), funcs)
    print (list(value))

Filter是过滤器,将符合lambda式或函数的值过滤出来形成新的返回对象。

Reduce是迭代处理一个迭代对象,因此其lambda式或函数一般带有两个参数,它首先作用于迭代对象的第一第二个元素,生成一个中间值,然后处理中间值和第三个元素,之后生成新的中间值,并和下一值结对处理,最后一般返回一个值。Python里Reduce被收到了functools模块里,需要像from functools import reduce这样调用。

三元运算符

除了一般的:

is_fat = True
state = "fat" if is_fat else "not fat"

还可以这样写:

fat = True
fitness = ("skinny", "fat")[fat]
print("Ali is ", fitness)

但不推荐,有隐患:

condition = True
print(2 if condition else 1/0)
# 输出2
print((1/0, 2)[condition])
# 输出ZeroDivisionError异常

装饰器

补充两个关于装饰器的代码。

使用functools.wraps保存原函数的名字和注释文档

from functools import wraps

def a_new_decorator(a_func):
    @wraps(a_func)
    def wrapTheFunction():
        print ("I am doing some boring work before executing a_func()")
        a_func()
        print ("I am doing some boring work after executing a_func()")
    return wrapTheFunction

@a_new_decorator
def a_function_requiring_decoration():
    """Hey yo! Decorate me!"""
    print("I am the function which needs some decoration to remove my foul smell")


print(a_function_requiring_decoration.__name__)
print(a_function_requiring_decoration.__doc__)

装饰器模板

from functools import wraps

def decorator_name(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not can_run:
            return "Function will not run"
        return f(*args, **kwargs)
    return decorated

@decorator_name
def func():
    return("Function is running")

can_run = True
print(func())

装饰器的使用场景

授权

from functools import wraps
def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            authenticate()
        return f(*args, **kwargs)
    return decorated

日志

from functools import wraps
def logit(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print(func.__name__ + " was called")
        return func(*args, **kwargs)
    return with_logging

@logit
def addition_func(x):
    """Do some math."""
    return x + x
    
result = addition_func(4)

__slots__魔法

在Python中,每个类都有实例属性。默认情况下Python用⼀个字典来保存⼀个对象的实例属性。这非常有用,因为它允许我们在运⾏时去设置任意的新属性。

class MyClass(object):
    __slots__ = ['name', 'identifier']
    def __init__(self, name, identifier):
        self.name = name
        self.identifier = identifier
        self.set_up()

这样写可以打打减少实例对象的内存使用,另外一款检测内存的模块ipython_memory_usage

虚拟环境

Virtualenv 是⼀个⼯具,它能够帮我们创建⼀个独⽴(隔离)的Python环境。

Collections模块

  • defaultdict,高级字典,可以处理key重复的情况而不是抛出异常。
  • counter,计数器,针对某项数据进行计数。
  • deque,双端队列
  • namedtuple,高级元组,可以生成一个带名字和字段的元组(但只是元组,这意味着值不能改变
from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')  # 元组名称和参数(用空格分隔)
perry = Animal(name="perry", age=31, type="cat")
print(perry)
print(perry[0])
print(perry.name, perry.age, perry.type) # 进行类字典访问
print(perry._asdict()) # 转换为字典
  • enum.Enum (Python 3.4+)
from enum import Enum
class Species(Enum):
    cat = 1
    dog = 2
    horse = 3
    aardvark = 4
    butterfly = 5
    owl = 6
    platypus = 7
    dragon = 8
    unicorn = 9
   
print (Species(1))
print (Species['cat'])
print (Species.cat)

枚举 Enumerate

enumerate可以带参数,注意参数不是表示从第几个元素开始,是指从数字几开始枚举。

my_list = ['apple', 'banana', 'grapes', 'pear']
for c, value in enumerate(my_list, 2):
print(c, value)
# 输出,注意不是从第几个元素开始,是指从数字几开始枚举
# 4 apple
# 5 banana
# 6 grapes
# 7 pear

对象自省 Introspection

dir

返回一个列表,表示一个对象所拥有的全部属性和方法。如果我们运行dir()而传⼊参数,那么它会返回当前作⽤域的所有名字。

type和id

type函数返回一个对象的类型。id返回任意对象的唯一ID。

inspect模块

推导式(即之前所述的生成式)

列表推导式

它的结构是在⼀个中括号⾥包含⼀个表达式,然后是⼀个for语句,然后是0个或多个for或者if语句。

variable = [out_exp for out_exp in input_list if out_exp == 2]

字典推导式

mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {
    k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
    for k in mcase.keys()
}

这个例子是把aA的值合并到a里面了。

集合推导式

{x**2 for x in [1, 1, 2]}

处理多个异常

try:
    file = open('test.txt', 'rb')
except (IOError, EOFError) as e:
    print("An error occurred. {}".format(e.args[-1]))

或者

try:
    file = open('test.txt', 'rb')
except EOFError as e:
    print("An EOF error occurred.")
    raise e
except IOError as e:
    print("An error occurred.")
    raise e

或者用Exception处理所有的异常。

lambda表达式

列表排序

a = [(1, 2), (4, 1), (9, 10), (13, -3)]
a.sort(key=lambda x: x[1])

列表并行排序

data = zip(list1, list2)
data.sort()
list1, list2 = map(lambda t: list(t), zip(*data))

for-else

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print( n, 'equals', x, '*', n/x)
            break
    else:
        # loop fell through without finding a factor
        print(n, 'is a prime number')

Python2+3

Future模块导入

它可以帮你在Python2中导⼊Python3的功能。

模块重命名

try:
    import urllib.request as urllib_request # for Python 3
except ImportError:
    import urllib2 as urllib_request # for Python 2
 
urllib_request.XXXXXXX

失效Python2的内置功能

from future.builtins.disabled import *
apply()

协程

def grep(pattern):
    print("Searching for", pattern)
    while True:
        line = (yield)
        if pattern in line:
            print(line)

search = grep('coroutine')
print (next(search))
print (search.send("Don't you love me?"))
print (search.send("I love coroutine instead!"))
search.close()

函数缓存

函数缓存允许我们将⼀个函数对于给定参数的返回值缓存起来。当⼀个I/O密集的函数被频繁使⽤相同的参数调⽤的时候,函数缓存可以节约时间。在Python 3.2版本以前我们只有写⼀个⾃定义的实现。在Python 3.2以后版本,有个lru_cache的装饰器,允许我们将⼀个函数的返回值快速地缓存或取消缓存。

from functools import lru_cache

@lru_cache(maxsize=32)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

print([fib(n) for n in range(10)])

你可能感兴趣的:(Python 3 知识点查漏补缺2)