Linux---python中的装饰器 模块 面向对象

file: 装饰器02.py
date: 2018-09-08 8:54 AM
author: westos-dd
desc:
装饰器需求:获取每个函数的执行时间
    1.函数执行之前计算时间
    2.函数执行之后计算时间

问题1:被装饰的函数有返回值的时候怎么办?
问题2:如何保留被装饰函数的函数名和帮助文档信息
"""

import time
import random
import string
import functools
li = [random.choice(string.ascii_letters) for i in range(100)]
def timeit(fun):
    """这是一个装饰器"""
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):  # 接收可变参数和关键字参数
        """这是一个wrapper函数"""
        # args:元组 kwargs:字典
        # 函数执行之前
        start_time = time.time()
        # 执行函数
        # 接收被装饰函数的返回值
        res = fun(*args, **kwargs)
        # 函数执行之后
        end_time = time.time()
        print '运行的时间为:%.6f' % (end_time - start_time)
        return res
    return wrapper
@timeit
def con_add():
    s = ''
    for i in li:
        s += (i + ',')
    print s
@timeit
def join_add():
    print ','.join(li)
@timeit
def fun_list(n):
    """这是fun_list函数,被timeit装饰"""
    return [2 * i for i in range(n)]
@timeit
def fun_map(n):
    """这是fun_map函数"""
    return list(map(lambda x: x * 2, range(n)))
con_add()
join_add()
print fun_list(50000)
print fun_map(50000)
print fun_list.__name__
print fun_list.__doc__

 

file: map_和匿名函数.py
date: 2018-09-08 9:25 AM
author: westos-dd
desc:
    

"""
def f(x):
    return x*x
# map()传入的第一个参数是一个函数,第二个参数是一个序列
print map(f,[1,2,3,4])

print map(lambda x:x*x,[1,2,3,4])

file: 装饰器0.py
date: 2018-09-08 10:23 AM
author: westos-dd
desc:
需求:用户登陆验证的装饰器 is_login
        1.如果用户登陆成功,则执行被装饰的函数
        1.如果用户登陆不成功,则执行登陆函数

"""
import functools

login_users = ['admin', 'root']
def is_login(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        # 判断写博客这个用户是否登陆成功
        if kwargs.get('name') in login_users:
            res = fun(*args, **kwargs)
            return res
        else:
            res = login()
            return res

    return wrapper

def login():
    return '登陆。。。'
@is_login
def writeBlog(name):
    return '编写博客。。'

print writeBlog(name='adminss')

 

 

 

file: 多个装饰器的应用.py
date: 2018-09-08 11:12 AM
author: westos-dd
desc:
 在我们实际的应用场景中,会采用多个装饰器先验证是否登陆成功再验证权限

"""
import functools
import inspect
def is_root(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        # inspect.getcallargs返回值是字典,key值为:形参 value值:形参对应的实参
        inspect_res = inspect.getcallargs(fun, *args, **kwargs)
        print 'inspect_res的返回值:%s' % inspect_res
        if inspect_res.get('name') == 'root':
            res = fun(*args, **kwargs)
            return res
        else:
            print 'Error:no permisson add studnet'
    return wrapper
login_session = ['root', 'admin', 'redhat']
def is_login(fun):
    @functools.wraps(fun)
    def warrper(*args, **kwargs):
        if args[0] in login_session:
            res = fun(*args, **kwargs)
            return res
        else:
            print 'Error:%s未登陆!' % args[0]
    return warrper
@is_login
@is_root
def add_student(name):
    print '添加学生信息。。'
add_student('root')

 

file: 多个装饰器的顺序.py
date: 2018-09-08 11:07 AM
author: westos-dd
desc:
探究多个装饰器的执行顺序

"""


def decorator_a(func):
    print 'Get in decorator_a'

    def inner_a(*args, **kwargs):
        print 'Get in inner_a'
        res = func(*args, **kwargs)
        return res

    return inner_a


def decorator_b(func):
    print 'Get in decorator_b'

    def inner_b(*args, **kwargs):
        print 'Get in inner_b'
        res = func(*args, **kwargs)
        return res

    return inner_b

# 当有多个装饰器时,从下到上调用装饰器
@decorator_b
@decorator_a
def f(x):
    print 'Get in f'
    return x * 2

f(1)

file: 带有参数的装饰器.py
date: 2018-09-08 11:55 AM
author: westos-dd
desc:
    

"""
import time
import functools
#print time.ctime()

def log(kind):
    def add_log(fun):
        @functools.wraps(fun)
        def wrapper(*args,**kwargs):
            start_time = time.time()
            res = fun(*args,**kwargs)
            end_time = time.time()
            print '<%s> [%s] 函数名:%s,运行时间:%.5f,运行返回值结果:%d' %(kind,time.ctime(),fun.__name__,end_time-start_time,res)
            return res
        return wrapper
    return add_log
@log('westos')
# log('dubug) --> 返回值是add_log
# add = add_log(add)
def add(x,y):
    time.sleep(1)
    return x+y

# wrapper(1,2)
print add(1,2)

file: 装饰器练习.py
date: 2018-09-08 9:54 AM
author: westos-dd
desc:
# 创建装饰器, 要求如下:
# 1. 创建add_log装饰器, 被装饰的函数打印日志信息;
# 2. 日志格式为: [字符串时间] 函数名: xxx, 运行时间:xxx, 运行返回值结果:xxx

"""
import time
import functools
#print time.ctime()

def add_log(fun):
    @functools.wraps(fun)
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = fun(*args,**kwargs)
        end_time = time.time()
        print '[%s] 函数名:%s,运行时间:%.5f,运行返回值结果:%d' %(time.ctime(),fun.__name__,end_time-start_time,res)
        return res
    return wrapper
@add_log
def add(x,y):
    time.sleep(1)
    return x+y

print add(1,2)

file: 装饰器练习02.py
date: 2018-09-08 10:33 AM
author: westos-dd
desc:
编写装饰器required_ints, 条件如下:
#     1). 确保函数接收到的每一个参数都是整数;
#     2). 如果参数不是整形数, 打印 TypeError:参数必须为整形

"""
import functools
def required_ints(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        for i in args:
            if not isinstance(i, int):
                print 'TypeError:参数必须为整形'
                break
        else:
            res = fun(*args, **kwargs)
            return res

    return wrapper

@required_ints
def add(a, b):
    return a + b

@required_ints
def myMax(a,b,c,d):
    return max(a,b,c,d)

print add(1.0,2)
print myMax(1,2,3,4)

#######

注意:由于1.0为浮点型  不是整形 所以会出现以下字样:

#######

file: 装饰器练习03.py
date: 2018-09-08 1:41 PM
author: westos-dd
desc:
  编写装饰器required_types, 条件如下:
#     1). 当装饰器为@required_types(int,float)确保函数接收到的每一个参数都是int或者float类型;
#     2). 当装饰器为@required_types(list)确保函数接收到的每一个参数都是list类型;
#     3). 当装饰器为@required_types(str,int)确保函数接收到的每一个参数都是str或者int类型;
#     4). 如果参数不满足条件, 打印 TypeError:参数必须为xxxx类型

"""
"""
# 装饰器的概念
- 装饰器的实现是函数里面嵌套函数;
- 装饰器的本质是一个函数, 它可以让其他函数在不需要做任何代码改动的前提下增加额外的功能;
- 装饰器需要传递一个函数, 返回值也是一个函数对象.
"""
import functools

def required_types(*kinds):
    def required_ints(fun):
        @functools.wraps(fun)
        def wrapper(*args, **kwargs):
            for i in args:
                if not isinstance(i, kinds):
                    print 'TypeError:参数必须为',kinds
                    break
            else:
                res = fun(*args, **kwargs)
                return res
        return wrapper
    return required_ints

@required_types(float,float)
def add(a, b):
    return a + b

print add(1.1,3)

注意:因为定义的为浮点型  所以要满足条件才会显示计算出来的值

file: 面向对象.py
date: 2018-09-08 4:29 PM
author: westos-dd
desc:

面向对象 oop:object oriented programming
面向对象的基本概念
我们之前学习的编程方式就是面向过程的
面向过程和面向对象,是两种不同的编程方式
对比面向过程的特点,可以更好的了解什么是面向对象

过程和函数(都是对一段功能的代码进行封装)
过程:是早期的一个编程概念
    过程类似于函数,只能执行,但是没有返回值
函数:不仅能执行,还可以返回结果(return)
===================================================================
面向过程 和 面向对象 的基本概念

面向过程:---侧重于怎么做?
1.把完成某一个需求的 所有步骤 从头到尾 逐步实现
2.根据开发要求,将某些功能独立的代码封装成一个又一个函数
3.最后完成的代码,就是顺序的调用不同的函数
特点:
1.注重步骤与过程,不注重职责分工
2.如果需求复杂,代码会变得很复杂
3.开发复杂项目,没有固定的套路,开发难度很大

面向对象:--谁来做?
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
1.在完成某一个需求前,首先确定职责--要做的事(方法)
2.根据职责确定不同的对象,在对象内部封装不同的方法(多个)
3.最后完成代码,就是顺序的让不同的对象调用不同的方法
特点:
1.注重对象和职责,不同的对象承担不同的职责
2.更加适合对复杂的需求变化,是专门应对复杂项目的开发,提供的固定套路
3.需要在面向过程的基础上,再学习一些面向对象的语法


熟悉面向对象编程
python java c++

类:是对一群具有相同特征或行为的事物的一个统称,不能直接使用(比如:飞机制造图纸不能飞上天)
    特征:属性
    行为:方法
对象:由类创建出来的一个具体的存在,可以直接使用(用图纸制造出来的飞机可以飞上天)

在程序开发中:应该先有类 再有对象

类的设计
1.类名 这类事物的名字,满足大驼峰命名法
    大驼峰命名法
        每一个单词的首字母大写
        单词与单词只见没有下划线
2.属性 这个类创建出的对象有什么样的特征
3.方法 这个类创建出的对象有什么样的行为
"""
"""
小明今年18岁,身高1.75,每天早上要跑步,会去吃东西
小美今年17岁,身高1.65 小美不跑步,小美喜欢吃东西
Person
name
age
height
eat()
run()
"""

 

"""
一只黄颜色的狗狗叫大黄
看见生人旺旺叫
看见家人摇尾巴
Dog
name
color
shout()
shake()
"""

##################

以下代码为:与机器人进行自动对话,用网页微信可以测试  (在此注意的是这个之可以在python3中进行操作)

##################

import itchat
import random
import time
import requests


def get_tuling_response(_info):
    print(_info)
    # 图灵机器人的api网址
    api_url = 'http://www.tuling123.com/openapi/api'
    data = {
        'key':'55f5db4f976d4de38302c333e8848a1d',
        'info':_info,
        'userid':'lily'
    }

    # 发送数据到指定的网址,获取网址返回的数据
    res = requests.post(api_url,data).json()
    #print(res,type(res))
    print(res['text'])
    return res['text']

# get_tuling_response('给我讲个笑话')
# get_tuling_response('给我讲个故事')

# 时刻监控好友发送的文本信息,别给予一个回复
# 注册消息响应事件。消息的类型为itchat.content.TEXT,即文本消息
@itchat.msg_register(itchat.content.TEXT,isFriendChat=True)
def text_reply(msg):
    # 获取好友发送的消息内容
    # 返回同样的文本消息
    content = msg['Content']
    # 将好友的消息发送给机器人去处理,处理的结果就是返回给好友的消息
    returnContent = get_tuling_response(content)
    #time.sleep(random.randint(1,10))
    return returnContent

itchat.auto_login(hotReload=True)
# 绑定消息响应事件后,让itchat运行起来
itchat.run()

 

###############

此为用手机来控制命令生成,所用python版本与以上的相同

###############

import os
import itchat

# # 在python里面执行shell命令
# # 1.第一种方式:可以判断命令是否执行成功;返回值为0
# # 执行成功,返回值不为0,则不成功
# res = os.system('hostnames')
# print(res)

# 2.第二种方式:用来保存命令的执行结果
res = os.popen('hostname').read()
print(res)

@itchat.msg_register(itchat.content.TEXT)
def text_reply(msg):
    """
    需求:当文件助手发送消息,执行发送的内容
        1.如果执行成功:【显示执行成功】:执行结果
        2.反之,显示执行失败
    """
    print(msg)
    if msg['ToUserName'] == 'filehelper':
        # 获取要执行命令的内容
        command = msg['Content']
        print(command)
        # 让电脑执行命令代码
        # 如果执行成功,返回值是0
        if os.system(command) == 0:
            res = os.popen(command).read()
            result = '[返回值] - 命令执行成功,执行结果:\n' + res
            itchat.send(result, 'filehelper')
        # 命令执行失败
        else:
            result = '返回值] - 命令%s执行失败,请重试' % command
            itchat.send(result,'filehelper')

itchat.auto_login(hotReload=True)
itchat.run()

 

面向对象的基本语法:
定义一个只包含方法的类
class 类名:
    def 方法1(self,参数列表):
        pass
    def 方法2(self,参数列表):
        pass
方法的定义格式和之前学的函数几乎一样
区别在于第一个参数必须是self
"""
"""
小猫爱吃鱼,小猫要喝水
"""

class Cat:
    def eat(self):
        print '小猫爱吃鱼'
    def drink(self):
        print '小猫爱喝水'

"""
创建对象
当一个类定义完成之后,要使用这个类来创建对象
对象变量 = 类名()
"""

# 创建猫对象
tom = Cat()
tom.drink()
tom.eat()

 在面向对象开发中,引用的概念是同样适用的
tom = Cat():在等号右侧我们使用cat类创建了一个猫对象,在等号左侧使用tom这个变量接收了这个猫对象
python解释器在执行到此句代码的时候,在内存中为这个猫对象分配了一个内存空间,然后再让tom这个变量记录了猫对象在内存中的地址
在python中使用类创建对象之后,tom变量中仍然记录的是对象在内存中的地址
也就是tom变量引用了新建的猫对象
使用print输出对象变量,默认情况下,是能够输出这个变量引用的对象是由哪一个类创建的象,以及在内存中的地址(十六进制表示)
提示:在计算机中,通常使用十六进制表示内存地址

"""
class Cat:
    def eat(self):
        print '小猫爱吃鱼'
    def drink(self):
        print '小猫爱喝水'

tom = Cat()
tom.eat()
tom.drink()
print tom
addr = id(tom)
print addr
# %x:打印格式为十六进制
print '%x' %addr
# %d:打印格式为十进制
print '%d' %addr

lazy_cat = Cat()
lazy_cat.drink()
lazy_cat.eat()
print lazy_cat
# 两个对象的内存地址不一样,
# 我们就断定这两只猫是不同的猫

lazy_cat2 = lazy_cat
print lazy_cat2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值