装饰器

原始的装饰器模式

def decorator(func):
 def wrapper():
   print(time.time())
   func()
 return wrapper

def f1():
 print('hello world')

decorator(f1)()

Python 中对于装饰器的语法糖

def decorator(func):
 def wrapper():
   print(time.time())
   func()
 return wrapper

@decorator
def f1():
 print('hello world')

f1()

带参数的装饰器

def decorator(func):
 def wrapper(func_name):
   print(time.time())
   func(func_name)
 return wrapper

@decorator
def f1(func_name):
 print('hello world' + func_name)

f1("ljl")

# 支持不同参数个数
import time

def decorator(func):
 def wrapper(*args):
   print(time.time())
   func(*args)
 return wrapper

@decorator
def f1(func_name):
 print('hello world' + func_name)

@decorator
def f2():
 print('hello world')

f1("ljl")
f2()

# 带关键字参数
def decorator(func):
 def wrapper(*args, **kw):
   print(time.time())
   func(*args, **kw)
 return wrapper

 @decorator
def f3(func_name, **kw):
 print('hello world' + func_name)
 print(kw)

f1("ljl")
f2()
f3("ljl", a = 1, b = 2, c = 'ljl')

装饰器带有参数

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

@log('execute')
def now():
    print('2015-3-25')

Python 的其他知识

列表推导式

a = [1, 2, 3, 4, 5, 6, 7, 8]
ret1 = [i * i for i in a]
print(ret1) # [1, 4, 9, 16, 25, 36, 49, 64]
ret2 = [i * i for i in a if i >= 5]
print(ret2) # [25, 36, 49, 64]
a1 = {1, 2, 3, 4}
ret3 = {i * i for i in a1}
print(ret3) # {16, 1, 4, 9}

students = {
 'ljl': 12,
 'lyb': 20,
 'aaa': 11
}
ret4 = [key for key, value in students.items()]
print(ret4) # ['ljl', 'lyb', 'aaa']
ret5 = {value: key for key, value in students.items()}
print(ret5) # {12: 'ljl', 20: 'lyb', 11: 'aaa'
ret6 = (key for key, value in students.items()) # 得到的是一个generator

迭代器与生成器

迭代器

# BookCollection就是一个自定义的可迭代对象
class BookCollection:
 def __init__(self):
   self.data = ["aaa", "bbb", "ccc"]
   self.cur = 0

 def __iter__(self):
   return self

 def __next__(self):
   if self.cur >= len(self.data):
     raise StopIteration()
   r = self.data[self.cur]
   self.cur += 1
   return r

books = BookCollection()
for b in books:
 print(b)

for b in books:
 print(b)

# 只会打印一次,第二次遍历无效,解决方法:
# 1. 重新创建一个BookCollection对象
# 2. copy

解决只能遍历一次的问题

import copy
books_copy = copy.copy(books) # 浅复制
books_copy2 = copy.deepcopy(books) # 深复制

for b in books:
 print(b)

for b in books_copy:
 print(b)

for b in books_copy2:
 print(b)

生成器

def gen(max):
  n = 0
  while n <= max:
    n += 1
    yield n # 返回n,每次调用next接着这里执行

g = gen(10000)
print(next(g)) # 1
print(next(g)) # 2
print(next(g)) # 3
print(next(g)) # 4

None

a = []
b = False
c = 0
print(None == a) # False
print(None == b) # False
print(None == c) # False
print(a is None) # False
print(b is None) # False
print(c is None) # False

# 判断值为空
if a:
  pass

if not a:
  pass

装饰器的副作用

import time

def decorator(func):
  def wrapper():
    print(time.time())
    func()
  return wrapper

@decorator
def f1():
  print(f1.__name__)  # wrapper

f1()

解决办法: 使用 wraps

import time
from functools import wraps

def decorator(func):
  @wraps(func)
  def wrapper():
    print(time.time())
    func()
  return wrapper

@decorator
def f1():
  print(f1.__name__)  # f1

f1()

错误处理

Python 中的异常

错误处理

try:
  a = 3 / 0
  fn()
except ZeroDivisionError:
  print('Division by zero')
except NameError:
  print('Invalid Name')
except:
  printn('Defalut handler')
else:
  # 没有错误时会调用
  print('No errors')
finally:
  print('Clean up actions')