装饰器
@f1(arg)
@f2
def func():
pass
is roughly equivalent to
def func():
pass
func = f1(arg)(f2(func))
Pythoon允许创建内嵌函数
Python的变量搜索是从里到外的
def outer():
x=1
def inner():
print x
inner()
outer()
Python中的函数和其他任何东西一样,都是对象,这意味着可以将函数当做实参传递给函数,甚至返回函数。
def add(x, y):
return x + y
def sub(x, y):
return x - y
def apply(func, x, y): # 1
return func(x, y) # 2
apply(add, 2, 1) # 3
apply(sub, 2, 1)
def outer():
def inner():
print("Inside inner")
return inner#返回函数对象
foo = outer()
foo()
闭包
def outer():
x=1
def inner():
print(x)
return inner
foo= outer()#outer运行完,局部变量x就消失了
foo.inner()
#这代码也是能正常运行的
变量x对函数outer是局部变量,即只有当outer运行时它才存在,只有当outer返回后才能调用inner,所以依据Python运行机制,在调用Inner时x就应该不存在了;但结果并不是,返回的Inner正常运行。
Python支持一种名为函数闭包的特性:函数记住其外层作用域,__里层函数可以调用外层函数的变量
装饰器
装饰器其实就是一个以函数作为参数,并返回一个替换函数的可执行函数
#简单装饰器格式
def outer(some_func):
def inner():
print ("before some_func")
ret = some_func()
return ret+1 #返回一个对象
return inner#返回一个函数
def foo():
return 1
decorated = outer(foo) # decorated是foo的装饰板---即foo加上了一些东西。
decorated()
foo =outer(foo)#变成附带其他东西的foo版本
foo()
class Coordinate(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Coord: " + str(self.__dict__)
def wrapper(func):#该装饰器限定输出x,y必须大于0
def checker(a,b):
ret=func(a,b)
ret=Coordinate(ret.x if ret.x>0 else 0,ret.y if ret.y>0 else 0)
return ret
return checker
def sub(a, b):
return Coordinate(a.x - b.x, a.y - b.y)
one = Coordinate(100, 200)
two = Coordinate(300, 100)
sub=wrapper(sub)
print(sub(one,two))
函数装饰器@符号的应用
add=wrapper(add)等价于
@ wrapper#该装饰器是硬编码的,必须接收两个参数的函数才能使用,这时需借助args和*kwargs
def add(a,b):
args,*kwargs
def one(*args):#可以接收任意多个参数
print args
在调用函数时,以*开头的变量表示该变量内容需被取出用做位置参数。
def add(x,y):
return x+y
add(*[1,2])
def foo(**kwargs):#表示字典和键值对
print kwargs
foo()
foo(x=1,y=2)
和 * 的使用一样,可以在函数调用和定义时使用 **。
利用args,kwargs编写装饰器
def logger(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
@logger
def fool(x,y=1):
return x*y
@logger
def foo2():
return 2
常见装饰器
@classmethod#类对象能使用的方法(类实例对象也可以)
@staticmethod#静态方法
class test(object):
@classmethod#类与实例都可以
def hello(cls):#cls表示当前类
print('1')
@staticmethod#类与实例都可以
def world():
print('hello world')
def helloWorld(self):#成员方法,只有实例对象可以调用
print('hello')
class Data_test(object):
def __init__(self,year = 0,month=0,day=0):
self.day=day
self.month =month
self.year = year
@classmethod #它的作用有点像静态类,比静态类不一样的是它可以传进来一个当前类作为第一个参数
def get_date(cls,string_date):
year, month, day = map(int, string_date.split('-'))
date1= cls(year, month, day)
return date1
def out_data(self):
print(self.year)
print(self.month)
print(self.day)
r = Data_test.get_date("2016-8-6")#先调用get_date()对字符串进行出来,然后才使用Data_test的构造函数初始化。这样的好处是以后重构类的时候不要修改构造函数
r.out_data()

浙公网安备 33010602011771号