python3-学习(2)

python类的继承
实例:

class people:
    name=''
    age=0
    __weight=0    #定义私有属性,私有属性在类外部无法直接进行访问

    def __init__(self,n,a,w):
        self.name=n
        self.age=a
        self.__weight=w
    def speak(self):
        print ("%s 说,我 %d 岁"%(self.name,self.age))

class student(people):
    grade=''
    def __init__(self,n,a,w,g):
        people.__init__(self,n,a,w)    # 调用父类的构函
        self.grade=g
    def speak(self):      # 覆写父类的方法
        print ("%s 说,我 %d 岁,我在读 %s年级"%(self.name,self.age,self.grade))

i=people("wu",45,"50kg")
i.speak()        # wu 说,我 45 岁

s=student("liu",65,"58kg","6")
s.speak()      # liu 说,我 65 岁,我在读6年级
*args 和 **args用法
def printinfo(name,age,**args):        #输入多余参数有变量名,就保存在**args中,保存方式为字典
    # 打印任何传入的字符串
    print ("name:",name)
    print ("age:",age)
    print (args)    
if __name__=='__main__':
    printinfo("sad",18,a=123,b=5)

def max_num(*args):
    print (args)    # *args 以元组的方式传入
    print (max(args))

def test(name,age,*args1,**args2):    # 多余参数中既有*args类型,也有**args类型 必须*args在前,**args在后
    print (args1)
    print (args2)

max_num(44,12)

test("asd",15,85,12,a=123,b=478)    #在传递参数时,也需先传*args类型,再传**args

输出:
    name: sad
    age: 18
    {'a': 123, 'b': 5}
    (44, 12)
    44
    (85, 12)
    {'a': 123, 'b': 478}
base64
  • base64原理:把3字节的二进制数据编码为4字节的文本数据,长度增加33%
  • 编码后的文本数据可以在邮件正文、网页等直接显示编码的二进制数据不是3的倍数时,用 \x00 字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码时自动去掉
  • b’str’ 表示字节

##### 文件操作

  • 打开文件的模式有(默认为文本模式):
    r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
    w,只写模式【不可读;不存在则创建;存在则清空内容】
    a, 之追加写模式【不可读;不存在则创建;存在则只追加内容】
  • 对于非文本文件,我们只能使用b模式,”b”表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
    rb wb ab
    注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
正则表达式
模式             描述
^             匹配字符串的开头
$             匹配字符串的末尾    #  'abc$'匹配以'abc'结尾的字符串
.             匹配任意一个字符(除换行符),当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]         匹配在一个范围内的单个字符   #  [amk] 匹配 'a','m'或'k'
[^...]      不在[]中的字符      #  [^abc] 匹配除了a,b,c之外的字符。
r'..'       匹配原始字符集
re*         匹配0个或多个的表达式。
re+         匹配1个或多个的表达式。
re?         匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n,}     精确匹配n个前面表达式。
re{ m, n}     匹配 m 到 n 次由前面的正则表达式定义的片段,贪婪方式
a| b         匹配a或b
(re)         G匹配括号内的表达式,也表示一个组
(?imx)         正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)     正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)     类似 (...), 但是不表示一个组
(?imx: re)     在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#...)     注释.
(?= re)     前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边
(?! re)     前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re)     匹配的独立模式,省去回溯。
\w             匹配字母数字及下划线
\W             匹配非字母数字及下划线
\s             匹配任意空白字符,等价于 [\t\n\r\f].
\S             匹配任意非空字符
\d             匹配任意数字,等价于 [0-9].
\D             匹配任意非数字
\A             匹配字符串开始
\Z             匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c
\z             匹配字符串结束
\G             匹配最后匹配完成的位置。
\b             匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B             匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t 等   匹配一个换行符,匹配一个制表符等
\1...\9     匹配第n个分组的内容。
\10         匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。
re.compile()函数

定义: 根据包含正则表达式的字符串创建模式对象

格式: re.compile(pattern,flags=0)

匹配模式 flags 参数:

  • re.I(re.IGNORECASE): 忽略大小写
  • re.M(MULTILINE): 多行模式,改变’^’和’$’的行为
  • re.S(DOTALL): 点任意匹配模式,改变’.’的行为
  • re.L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
  • re.U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
  • re.X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释
re.match() 函数
  • 定义:
    re.match 尝试从字符串的起始位置匹配一个模式,匹配成功re.match方法返回一个匹配的对象,如果不是起始位置匹配成功的话,match()就返回none
  • 函数语法:

    re.match(匹配的正则表达式, 匹配的字符串, flags=0)  
    
  • 实例: 邮箱地址验证

    # 可进行两种邮箱地址验证 (1) some123@any.any (2) some.some@any.any
    
     import re
    
     r1=re.compile('^[a-zA-Z0-9]+@[a-zA-Z]+\.[a-zA-Z]{3}$')
     r2=re.compile('^[a-zA-Z]+\.[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]{3}$')
    
     addr=input("please input email:")
    
     def email(addr):
         if r1.match(addr):
             print ("输入地址合法")
             m=re.match(r1,addr)
             print ("您输入的地址为:"+m.group())
         elif r2.match(addr):
             print ("输入地址合法")
             m=re.match(r2,addr)
             print ("您输入的地址为:"+m.group())
         else:
             print ("false")
    
     email(addr)
    
re.search()函数

定义: 返回成功匹配的第一个对象

序列化 反序列化
  • 变量从内存中变成可存储或传输的过程称之为序列化,python 中叫 pickling
  • 变量内容从序列化的对象重新读到内存里称之为反序列化,即 unpickling

    实例:
    import pickle
    
    # 序列化
    
    d = dict(name="wu",age=20)
    
    file=pickle.dumps(d)    # pickle.dumps()方法把任意对象序列化成一个bytes
    print (file)    # 输出 b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x02\x00\x00\x00wuq\x02X\x03\x00\x00\x00ageq\x03K\x14u.'
    
    f=open('dump.txt','wb')
    pickle.dump(d,f)    # pickle.dump()直接把对象序列化后写入一个file-like Object
    f.close()
    
    # 反序列化
    
    file1=pickle.loads(file)    # pickle.loads()方法先把内容读到一个bytes然后反序列化出对象
    print (file1)    # 输出 {'name': 'wu', 'age': 20}
    
    f=open('dump.txt','rb')        #pickle.load()方法从一个file-like Object中直接反序列化出对象
    file2=pickle.load(f)
    f.close()
    print (file2)    # 输出 {'name': 'wu', 'age': 20}
    
JSON 用法
  • json.dumps()用于将dict类型的数据转成str
  • json.dump()用于将dict类型的数据转成str,并写入到json文件中
  • json.loads()用于将str类型的数据转成dict
  • json.load()用于从json文件中读取数据

    实例:
    import json
    
    f = open("shodan-export.json",'r')
    str = f.readlines()    #读取整个文件所有行,保存在一个列表(list)中,每行作为一个元素,但读取大文件会比较占内存。
    
    ips = []
    for line in str:
        str_json = json.loads(line)    #将json对象str类型转化为python字典(dict)
        ip = str_json['ip_str']        #获取键值为ip_str的value值
        ips.append(ip)
    f.close()
    
    f1 = open('iplist.txt',"w")        #写入新文件
    for ip in ips:
        f1.write(ip+"\n")
    f1.close()
    
网络编程
  • Socket是网络编程的一个抽象概念。通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可。
  • 创建Socket时,AF_INET 指定使用IPv4协议,AF_INET6 指定使用IPV6协议,SOCK_STREAM 指定使用面向流的TCP协议
  • 参考链接: https://ciphersaw.me/2018/05/23/Python%20%E7%BB%9D%E6%8A%80%20%E2%80%94%E2%80%94%20TCP%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF/
  • socket 对象方法(服务端):
    s.bind(address)
    s..listen(backlog)
    s.accept()
  • socket 对象方法(客户端):
    s.connect(address)
    s.connect_ex(address)
  • socket 对象方法(公共):
    s.recv(bufsize[,flag])
    s.send(string[,flag])
    s.send_all(string[,flag])
    s.recvfrom(bufzize[,flag])
    s.sendto(string[,flag],address)
    s.close():关闭套接字
    s.getsockname():返回套接字自己的地址,通常是一个元组(ipaddr,port)
    s.getpeername() :返回套接字远程地址,通常是一个元组(ipaddr,port)
  • Socket 编程实例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
          # TCP 连接

    import socket

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    s.connect(('www.baidu.com',80)) # 建立连接

    s.send(b'GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n') # 发送数据

    buffer=[] #接收数据
    while True:
    d=s.recv(1024) #每次最多接受1k字节
    if d:
    buffer.append(d)
    else:
    break
    data=b''.join(buffer) # join()于将序列中的元素以指定的字符连接生成一个新的字符串

    s.close() # 关闭连接

    header,html=data.split(b'\r\n\r\n',1) # 以\r\n\r\n为分隔符对接收到的data进行分割,分割1次
    print (header.decode('utf-8'))

    with open('baidu.html', 'wb') as f: # 把接受的数据写入文件
    f.write(html) # 文件打开模式带b,写入文件内容时参数要用encode方法转为bytes形式,否则报错
urllib
  • urllib的request模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应

     实例:
    from urllib import request
    
    with request.urlopen('https://www.baidu.com') as f:
        data=f.read()
        print ('status:',f.status,f.reason)
        for k,v in f.getheaders():
            print ('%s %s' %(k,v))
        print ('Data:',data.decode('utf-8'))