闭包

在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么我们将这个函数以及用到的一些变量,里面的整体为闭包

def test(a,b):
    def test_in(x):
        print(a*x+b)
    return test_in

line1 = test(1,1)
line1(2)

装饰器

装饰器的作用:增强函数的功能,确切的说,可以装饰函数,也可以装饰类

1.内置装饰器@property

作用:由于python进行属性的定义时,没办法设置私有属性,因此要通过@property的方法来进行设置。

这样可以隐藏属性名,让用户进行使用的时候无法随意修改

注意点:加了@property后,可以用调用属性的形式来调用方法,后面不需要加()

# @property只读属性
class DataSet(object):
    def __init__(self):
        self._images = 1
        self._labels = 2 #定义属性的名称
    @property
    def images(self): 
        return self._images 
    @property
    def labels(self):
        return self._labels
l = DataSet()
print(l.images)    # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。

#  @age.setter属性修改,并限制属性
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.__age = 18

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        if age < 18:
            print('年龄必须大于18岁')
            return
        self.__age = age
        return self.__age

xm = Person('xiaoming', 20)
print(xm.age)
print('----------')
xm.age = 10
print(xm.age)
print('----------')
xm.age = 20
print(xm.age)

2.内置装饰器@staticmethod和@classmethod

@classmethod类方法:可以在class内实例化class,作用就是比如输入的数据需要清洗一遍再实例化,可以把清洗函数定义在class内部并加上@classmethod

@staticmethod静态方法:就是一普通函数,只不过封装在class内部,使用class.func()访问,很少使用

class Data_test2(object):
    day=0
    month=0
    year=0
    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):
        #这里第一个参数是cls, 表示调用当前的类名
        year,month,day=map(int,string_date.split('-'))
        date1=cls(year,month,day)
        #返回的是一个初始化后的类
        return date1

    def out_date(self):
        print("year:{0}".format(self.year))
        print("month:{0}".format(self.month))
        print("day:{0}".format(self.day))

r=Data_test2.get_date("2016-8-6")
r.out_date()

重构类的时候不必要修改构造函数,只需要额外添加你要处理的函数,然后使用装饰符 @classmethod 就可以

3.日志打印

def logger(fuc):
    def wrapper(*args, **kargs):
        print("开始记录{0}的日志".format(fuc.__name__))
        fuc(*args, **kargs)
        print("打印结束")
    return wrapper

@logger
def add(x, y):
    print("x:{0} + y:{1} = z:{2}".format(x, y, x + y))

add(200, 50)

4.时间计时

import time

def timer(fuc):
    def wrapper(*args, **krags):
        t1 = time.time()
        fuc(*args, **krags)
        t2 = time.time()
        print("消耗时间:{0}".format(t2 - t1))
    return wrapper

@timer
def time_sleep(time_sleep):
    time.sleep(time_sleep)

time_sleep(5)

5.带参数的函数装饰器

def say_hello(country):
    def wrapper(fuc):
        def deco(*args, **krags)
            if country == "china":
                print("你好!")
            elif country == "america"
                print("hello.")
            else:
                return ''
            fuc(*args, **krags)
        return deco
    return wrapper

@say_hello("china")
def chinese():
    print("我是中国人")

chinese()

6.不带参数的类装饰器

基于类装饰器的实现,必须实现__call__ 和 init__两个内置函数。__init :接收被装饰函数,call :实现装饰逻辑。

class logger(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
         print("[INFO]: the function {func}()is running..."\
            .format(func=self.func.__name__))
         return self.func(*args, **kwargs)

@logger      
def say(something):
    print("say {}!".format(something))

say("hello")

7.带参数的类装饰器

class logger(object):
    def __init__(self, level='INFO'):
        self.level = level

    def __call__(self, fuc):
        def wapper(*args, **kwargs):
             print("[{0}]: the function {1}()is running...".format(self.level, fuc.__name__))
             fuc(*args, **kwargs)
        return wapper

@logger('WRANING')   
def say(something):
    print("say {0}!".format(something))

say("hello")

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:http://example.com/article/python_base2/