PYTHON自动化Day9-发邮件、面向对象、类、私有、继承

一.发送邮件

首先我们需要打开邮箱,打开smtp服务,配置客户端授权密码:

 例如:163邮箱

设置授权码,记住这个授权码,我们需要在发送邮件时使用:

在本地安装yagmail模块

python发送邮件代码:

#以前用 smtplib模块发邮件,但是很麻烦,现在我们用yagmail

import yagmail

username='[email protected]'
passwd = 'xxxxxx'  #授权码
mail=yagmail.SMTP(user=username,
                  password=passwd,
                  host='smtp.163.com',
                  # smtp_ssl=True,
                  # port=465,  #可以不写port,默认465
                  )  #如果使用的是qq邮箱(因为使用了安全协议),需要加 smtp_ssl=True

mail.send(
    to=['[email protected]','[email protected]'],  #如果是单个收件人,直接写string即可,如果是多个写成list
    cc='[email protected]', #抄送
    subject='测试邮件',  #title
    contents='测试邮件内容',  #内容
    attachments=[r'D:\xx\自动化\须知.txt']  #附件,多个用逗号隔开,放在list里
    )

 PS:如果报错554,说明被认为成了广告或者垃圾邮件

二.面向对象编程

1.类

class Person:  #经典类,类名首字母要大写
    def __init__(self,name): #构造函数  #在实例化这个类时会执行的初始化函数
        # self.name='zl'  #这样就把名字写死了,不好,所以,可以构造函数传入一个参数,作为name
        self.name=name
        self.nose=2  #鼻子   #类里面的变量,叫做属性
        self.face=2 #
        self.head=10 #脑子
        self.wing=4  #翅膀
        print('开始造人。。。')

    def driver(self):    #其他函数
        print('%s老司机开车非常稳!' %self.name)  # self的作用,在类中其他方法中可以直接使用self中的内容
        self.eat()  #self可以用来在函数里调用类里面的其他函数

    def fly(self):
        print('会飞')

    def eat(self):
        print('%s吃火锅' %self.name)


#类在使用的时候,首先必须要实例化

zlg=Person('zl')     #实例化,类名加上括号就是实例化, 在实例化时传入name参数,self不算参数,是类中的固定写法
# zlg=Person(name='zl')  #过个参数的传参方法

zlg.eat()  #引用类中的函数
zlg.driver()
zlg.fly()
print(zlg.name)   #引用类中的变量
print(zlg.face)
print(zlg.nose)


class Person2(object): #新式类
    pass

#类名首字母大写
#在python3中经典类和新式类没有区别

一个练习: 

需求:

1、得到一个请求数据:

vendorId=1697&posCode=pos006&ip=127.0.0.1&posVersion=2.1.1.1.1&mac=;D4-81-D7-CA-20-29;7C-67-A2-9A-06-05;7C-67-A2-9A-06-06;7C-67-A2-9A-06-09;00-00-00-00-00-0000E0
2、提取到商家编码 vendorId=1697
3、将商家编码进程2次md5 得到astr
4、再将请求数据进行一次urldecode得到url_str
5、astr+url_str 进行一次MD5

什么是url编码,解码:

python基础教程     ---->    %DFS%DFDFGD4RG3FD       url编码
%DFS%DFDFGD4RG3FD    <----     python基础教程       url解码

url编码加密和解密方法:

from urllib import parse  #用来url编码,解码

#例如:
url='http://www.baidu.com?query=python基础教程'
print(parse.quote_plus(url))  #url编码 加密

url2='http%3A%2F%2Fwww.baidu.com%3Fquery%3Dpython%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B'
print(parse.unquote_plus(url2))  #url解码,解密

先用我们之前的定义普通函数的写法:

 
 
from urllib import parse  #用来url编码,解码
#下面的方法是原始的函数写作方法,之后我们用类来写,更简洁

import hashlib  #md5需要用的模块

def my_md5(s):
    md=hashlib.md5()
    md.update(s.encode()) #需要先转换成byte格式然后再进行加密
    return md.hexdigest()   #返回加密结果

def get_vendorid(req_data):
    data_dict={}
    # sub_list=req_data.split('&')[0].split('=')[1]  #因为传入的字符串可能是无序的所以这种直接分割的方式不准确,所以我们循环get key和value,写入字典,然后通过key=vendorId来取得 vendorId
    sub_list = req_data.split('&') #先把字符串按照&分割为一个list
    #[vendorId=1697,posCode=pos006,ip=127.0.0.1....]

    for i in sub_list:
        k,v=i.split('=')  #vendorId=1697 按照=号把list中的元素再分割为list,分别赋给key和value
        #[vendorId,1697]
        # data_dict.setdefault(k,v)  #存在不覆盖
        data_dict[k]=v   #得到key和value后,写入一个新定义的字典
    # print(data_dict)

    return  data_dict.get('vendorId')  #根据vendorId这个key得到我们需要的值return

def sign(req_data):
    verid=get_vendorid(req_data)  #调用函数得到vendorid
    first=my_md5(verid)
    astr=my_md5(first) #按照需求两次加密verid
    url_str=parse.quote_plus(req_data)   #把整个string 进行url编码
    res=my_md5(astr+url_str)  #两个字符串相加再进行一次md5加密
    return res

s='vendorId=1697&posCode=pos006&ip=127.0.0.1&posVersion=2.1.1.1.1&mac=;D4-81-D7-CA-20-29;7C-67-A2-9A-06-05;7C-67-A2-9A-06-06;7C-67-A2-9A-06-09;00-00-00-00-00-0000E0'

print(sign(s))   #调用函数得到加密结果

下面用类来写:

#下面用类的方式写:

from urllib import parse
import hashlib

class Sign(object):
    def __init__(self,req_data):
        self.req_data=req_data   #这写了self,在其他的函数里可以使用self
        self.get_verid()
        self.get_sign()

    def md5(self,s):
        md = hashlib.md5()
        md.update(s.encode())
        return md.hexdigest()

    def get_verid(self):
        data_dict={}
        sub_list=self.req_data.split('&')
        for i in sub_list:
            k,v=i.split('=')
            data_dict[k]=v
        self.verid=data_dict.get('vendorId')   #这写了self,在其他的函数里可以使用self.verid来使用

    def get_sign(self):
        # self.get_verid()  #或者把这句放在__init__里面,总之需要互相调用
        first=self.md5(self.verid)
        astr=self.md5(first)
        url_str=parse.quote_plus(self.req_data)
        self.sign=self.md5(astr+url_str)
        # return self.sign    #不return,也是一样的,因为定义了self.sign, 所以可以直接使用abc.sign来得到sign


    abc=Sign(s)  #实例化
    print(abc.sign)  #打印出结果,因为函数中定义了变量self.sign来保存结果,所以可以直接通过对象来引用这个变量

2.下面来看一下if __name__=='__main__': 的作用是什么:

if __name__=='__main__': 
       pass                 #这句话一般是调试的时候用,
                            #1.如果是直接运行这个python文件,这句话没有作用
                            #2.在别的文件中import这个文件时,就有作用了,如果有这句话,不执行他下面的代码,如果不写这句话,会执行
                            #这句话的意思,就是判断使用的时候是不是本文件在使用,否则表示是外部文件在引用,引用就不执行下面的代码
print(__name__)  #如果自己这个文件运行时是__main__ , 如果别的文件引用时,是这个文件的文件名 可以在本文件和引用本文件时打印这个变量试试看

3.析构函数

 前面我们介绍了构造函数,是在实例化的时候会执行的函数,那么在对象不再使用即将销毁之前,能不能做一些操作呢,python也提供了函数,叫做析构函数

举例:一个优化过的mysql类

#一个优化过的mysql类:

import pymysql
class MyDb(object):
    def __del__(self):  #析构函数  会在脚本运行完,也就是实例化的对象不再使用被释放时执行这个析构函数,这里不写释放mysql连接,也会在一定时间自动释放,数据库有配置连接多久后断开,这里只是举例析构函数可以怎么用,用在哪里
        self.cur.close()
        self.conn.close()
        print('over....')

    def __init__(self,host,user,passwd,db,port=3306,charset='utf8'):
        try:
            self.conn=pymysql.connect(
                host=host,user=user,passwd=passwd,port=port,charset=charset,db=db,
                autocommit=True,#自动提交,不需要commit操作
            )
        except Exception as e:
            print('数据库连接失败!%s' %e)
        else:
            self.cur=self.conn.cursor(cursor=pymysql.cursors.DictCursor)  #返回字典类型

    def exsql(self,sql):
        try:
            self.cur.execute(sql)
        except Exception as e:
            print('sql语句有问题,%s' %e)
        else:
            self.res=self.cur.fetchall()
            return self.res

my= MyDb('118.24.3.40','jxz','123456','jxz')
my.exsql('select * from stu;')

4.类中的各种特殊的方法类型:

class Baby():
    country='china' #类变量,公共的变量,每个实例都可以用
    
    def __init__(self,name):  #构造函数
        # print('self的内存地址:',id(self))  #self和实例化后的对象的内存地址是相同的
        self.name=name
        self.money=5000

    @property         #定义一个属性方法
    def hhh(self):
        return 198

    @classmethod      #定义一个类方法,不需要实例化就可以调用, 可以通过cls来使用类变量,但是不能调用这个类里面的其他实例方法、实例变量,因为他只能通过cls来调用其他,而不是self
    def xm(cls):        #在不想实例化的时候,就可以定义成类方法
        print(cls.country)
        print('我是类方法')

    @staticmethod   #静态方法
    def xh():
        print('这是个静态方法,他和一个没写在类里面的函数一样')    #不能使用类变量,类方法,实例变量,实例方法

Baby.country='usa' #类变量可以直接通过类名.xxx来修改的
Baby.xm()  #类方法在不实例化也可以调用,和实例化后调用相同

abc=Baby('lily')
abc.xm()
print('实例化1的内存地址',id(abc))
print(abc.hhh)
print(abc.hhh()) #如果没有加@property,需要这样调用

print(abc.name)
print(abc.money)
abc.car='bmw'   #给对象添加一个类属性
print(id(abc.car))

#self 代表的是本类对象, 就是实例化之后的对象, 所以class里的内容加上self,那么在这个类里面就都可以调用了,因为self表示的是同一块内存地址

5.继承:

class Lz(object):   #父类
    def __init__(self):
        self.money=1000000000
        self.house='三环20套'

    def sing(self):
        print('唱歌')

    def dance(self):
        print('跳舞')

    def friend(self):
        print('朋友')


class Xz(Lz):   #继承Lz的内容,子类
    def dance(self):   #如果定义了和父类相同的方法,就在子类里重写了这个方法
        print('交谊舞')
    pass

a=Xz()
a.dance()
print(a.money)

#用法:
#例如,可以这样定义函数的公共部分
class Base(object):
    def __init__(self,host,port,password):
        self.host=host,
        self.port=port,
        self.password=password

class Mysql(Base):  #减少代码重复
    pass
class Redis(Base):
    pass

6.私有:

例子:优化一个redis的类:(待完成)

import redis
class My(object):
    def __init__(self):
        self.__host='118.24.3.40'        #self.host在前面加__,就定义成了私有变量,只能在类里面使用,外部不能调用, 同理在方法名前面加__,就定义成了私有方法,外部不能调用
        self.__port=6379
        self.__password='HK139bc&*'

        self.r=redis.Redis(host=self.host,port=self.port,password=self.password)

    def get(self,k):   #根据key查询string类型的value
        res=self.r.get(k)
        if res:
            return res.decode()
        return None
    def str_set(self,k,v):   #新增一个string类型的key
        self.r.set(k,v)
        pass
    def str_del(self):  #删除stringl类型的key
        pass
    def hash_get(self):
        pass
    def hash_set(self):
        pass
    def hash_getall(self):
        pass
    def hash_del(self):
        pass

my=My()
my.port=9999   #如果可以随意修改很容易出错,所以我们可以把它设置为私有的 self.__port=6379
print(my.__port)   #不能调用

总结:

1、发邮件
    1、在你的邮箱设置里面打开smtp服务
    2、开启邮箱授权码,记住这个授权码

    yagmail
        要用群里我给你的那个.whl的安装包
        直接pip install的话,发中文附件的时候,文件名是乱码

2、 面向对象编程  class
    面向过程编程      执行者
        1、4S店 掏钱买车
        2、保险公司 上保险
        3、税务局 交购置税
        4、交管局 验车、选号、交钱、取牌、上牌
    面向对象       指挥者
        买车办事处
            1、4S店 掏钱买车
            2、保险公司 上保险
            3、税务局 交购置税
            4、交管局 验车、选号、交钱、取牌、上牌


    类
        一个种类,一个模型。汽车模型
    对象
        指具体的东西,模型造出来的东西叫做对象。
    实例
        实例和对象是一样的。
    实例化
        实例化就是造东西的这个过程。
    属性
        就是变量
    方法
        就是类里面的函数
    继承
    封装
    多态
    self代表的是本类对象。
    因为函数里面的变量都是局部变量,出了函数就不能用了。
    用self给对象绑定了之后,就可以self.xx随便用了

    构造函数
        def __init__():
            pass
     构造函数就是类在实例化的时候执行的函数。
     类在实例化的时候,会自动执行它

    析构函数
        def __del__():
            pass
      实例被销毁的时候执行的。

    属性方法
        看起来像属性的一个方法。
    类变量
        类变量,公共的变量,每个实例都可以用
    实例变量(成员变量)
    实例方法
        实例化之后才可以用的。
    类方法
        1、不用实例化就可以直接调用。
        2、它可以通过cls使用类变量
        3、它不能调用这个类里面的其他实例方法和实例变量
    静态方法
        #你不想实例化的时候,就可以定义成类方法
        #静态方法就是一个普通函数,只不过是写在类里面而已,它用不了类变量、类方法、实例变量、实例方法
    私有
        私有方法
        私有变量
            出了类之后,就不能用了。

    if  __name__ == '__main__':
        判断这个python是在别的地方导入的,还是直接运行的这个python文件
        这句话一般是做调试的时候用的。
        1、如果是直接运行这个python文件的时候,这句话一点用都没有
        2、其他文件引用时,这个判断为false,就不会执行后面的内容

3、多线程和多进程  (还没有讲)
4、单元测试框架unittest  (还没有讲)


作业:(未完成)
    1、把我写的操作redis的类,
        1、加上异常处理
        2、把剩下的方法封装好
       3、redis这个类day9下面私有.py文件中
    2、博客好好整整,好好写写
    3、选做题
        1、读Excel,获取里面的测试用例,
        2、根据Excel里面的测试用例,调用接口,把返回结果和是否通过写入Excel
        3、发送测试报告到邮箱
            xx你好:
                本次测试共运行xxx条用例,失败xx条,成功xx条。。

猜你喜欢

转载自www.cnblogs.com/lilyzhang-2018/p/9069951.html