装饰器

@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()
posted @ 2018-02-02 20:04  blog_hfg  阅读(127)  评论(0)    收藏  举报