python中的装饰器@abc
装饰器可以让代码更加优雅,减少重复,但也不全是优点,也会带来一些问题。
它经常用于有切面需求但场景,比如:插入日志、性能测试、事物处理、缓存等等、权限校验等场景。
装饰器本质上是一个python函数。
在函数前面加@装饰器的名字,然后把这个函数传进装饰器中,装饰器可以获得一些传入这个函数的参数,在函数执行前做一些操作。
比如打印一些log,或者做性能测试等等,常用还是1、日志 2、找bug 3、授权。
def decorator(func):
print("before f")
hi()
def hi():
print("hello")
decorator(hi)
/*** 分隔线 ***/
def debug(func): #传入一个函数,也就是被装饰的函数
def wrapper(*args, **kwargs): # 指定宇宙无敌参数,*表示为可变参数,**表示为关键字参数
print("[DEBUG]: enter {}()".format(func.__name__))
print('Prepare and say...')
if(args[0] == '555'):
print('good')
else:
print('bad')
return func(*args, **kwargs)
return wrapper # 返回
@debug
def say(something):
print("hello {}!".format(something))
say('555')
output:
[DEBUG]: enter say()
Prepare and say...
good
hello 555!
另一个例子:
# -*- coding: UTF-8 -*-
def logging(level):
def wrapper(func):
def inner_wrapper(*args, **kwargs):
print("[{level}]: enter function {func}()".format(
level=level,
func=func.__name__))
return func(*args, **kwargs)
return inner_wrapper
return wrapper
@logging(level='INFO')
def say(something):
print("say {}!".format(something))
say('interesting')
output:
[Debug]: enter function say()
say interesting!
授权的装饰器:
授权的装饰器:
from functools import wraps
#用来判断是否已经有auto,或者此时有账号密码传入。
def requires_auth(f):
@wraps(f) #@wraps本身也是装饰器
def decorated(*args, **kwargs):
auth = request.authorization
if not auth or not check_auth(auth.username, auth.password):
authenticate()
return f(*args, **kwargs)
return decorated3
把log打到文件当中:
#把日志写入文件当中:
from functools import wraps
def logit(logfile='out.log'):
def logging_decorator(func):
@wraps(func)
def wrapped_function(*args, **kwargs):
log_string = func.__name__ + " was called"
print(log_string)
# 打开logfile,并写入内容
with open(logfile, 'a') as opened_file:
# 现在将日志打到指定的logfile
opened_file.write(log_string + '\n')
return func(*args, **kwargs)
return wrapped_function
return logging_decorator
@logit()
def myfunc1():
pass
myfunc1()
# Output: myfunc1 was called
# 现在一个叫做 out.log 的文件出现了,里面的内容就是上面的字符串
@logit(logfile='func2.log')
def myfunc2():
pass
myfunc2()
# Output: myfunc2 was called
# 现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串
常见自带装饰器:
@classmethod #一个object的方法带上它后可以不用实例化直接使用
@property #把object的方法当作属性一样直接用,与上面不同在于其还需要实例化
例子:
# -*- coding: UTF-8 -*-
class UserInfo(object):
def __init__(self, name, age):
self.name = name
self._age = age
@classmethod
def get_name(cls):
print('枯了')
@property
def get_age(self):
return self._age
if __name__ == '__main__':
UserInfo.get_name()
userInfo = UserInfo('yeleng', 22)
print(userInfo.get_age)
推导式:
列表推导式提供简洁的方法创建一个list。
multiples = [i for i in range(30) if i % 3 is 0]
print(multiples) # 创建一个满足条件的list
squared = [x**2 for x in range(10)]
print(squared)
python异常处理:
try: # 把all 异常放到元组当中
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
try:
file = open('test.txt', 'rb')
except Exception:
# 打印一些异常日志,如果你想要的话
raise
#无论是否异常,最后都执行finally
try:
file = open('test.txt', 'rb')
except IOError as e:
print('An IOError occurred. {}'.format(e.args[-1]))
finally:
print("This would be printed whether or not an exception occurred!")
Map、Filter、Reduce
map会将一个函数映射到一个输入列表的所有元素上:
map(function_to_apply,list_of_inputs)
很多时候lambda配合map来进行使用。
lambda配合map、filter使用。
简易版:
map(lambda x:x+1,list1)
~map(lambda a,b)
~filter(lambda x:x<-1,list1)
examples:
list1 = [1,2,3,4,5]
s = []
list2 = list(map(lambda x:x+1,list1)) # 这里map返回的是一个obejct,需要转为list
print(list2)
or:
def k(x):
return x+5
list2 = list(map(k,list1))
##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使用
list1 = [-5,-3,-2,-1,3,4,6,8]
res = list(filter(lambda x:x<-1,list1))
print(res)
output :[-5, -3, -2]
Reduce类似那个reduece,就是把list的结果,经过某些操作返回一个具体的值。
from functools import reduce
def add(x,y):
return x + y
print (reduce(add, range(1, 101))) # 传入2个参数
print (reduce(lambda x,y:x+y,[1,2,3,4,5]))
python3:
__new__
__init__
class Hello(object):
def __init__(self):
print('it is self __init__ method')
def __del__(self):
print('it is del')
def __new__(cls, *args, **kwargs):
print('it is __new__,new a object')
return object.__new__(cls)
res = Hello()
__call__:
class Entity:
def __init__(self, size, x, y):
print(size,x,y)
self.x, self.y = x, y
self.size = size
def __call__(self, x, y):
print('it is call',x,y)
self.x, self.y = x, y
e = Entity(1, 2, 3) # 创建实例
print('stop')
e(4, 5)