Python基础 (下)

Posted 安小

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python基础 (下)相关的知识,希望对你有一定的参考价值。

参考:菜鸟教程

目录

一、读写文件

二、错误和异常

三、XML和JSON解析

四、类

五、Python高级教程

 

 

一、读写文件

1. 打开文件:  open(filename, mode)。 mode有如下几种模式,默认为只读(r)。

      

2. 写入文件

f = open("/home/test.txt", "w")

# write(s) 将s写入到文件中, 然后返回写入的字符数
num = f.write("Come on baby!\\n Let\'s go party")
print(num)

# 写入非字符串数据, 需要类型转化
value = (\'amy\', 14, \'China\')
s = str(value)
f.write(s)

# writelines(seq) 向文件中写入一个字符串列表
seq = ["Come on baby\\n", "Let\'s go party"]
f.writelines(seq)

f.close()

3. 读取文件

f = open("/home/test.txt", "r")

str = f.read()       # f.read(size) 读取指定的字节数, 如果未给定或为负则读取所有内容。
str = f.readline()   # f.readline(size) 读取一行,包括\'\\n\'字符。 当返回一个空字符串, 说明已经读取到最后一行。
str = f.readlines()  # f.readlines(sizeint) 读取所有行,如果设置可选参数sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。
print(str)

# 迭代文件对象然后读取每行
for line in f:
    print(line, end=\'\')
    
f.close()

4. 移动文件位置

seek(offset, from_what)  改变文件当前的位置     from_what为0表示从文件开头移动, 1表示当前位置, 2表示文件的结尾,默认为0

  seek(x,0) : 从起始位置即文件首行首字符开始移动x个字符
  seek(x,1) : 表示从当前位置往后移动x个字符
  seek(-x,2):表示从文件的结尾往前移动x个字符

f = open(\'/home/test.txt\', \'rb+\')
f.write(b\'0123456789abcdef\')
f.tell()      # 16 返回文件对象当前所处的位置
f.seek(5)     # 移动到文件的第六个字节 
f.read(1)     # b\'5\'
f.seek(-3, 2) # 移动到文件的倒数第三字节
f.read(1)     # b\'d\'
f.close()

5. pickle模块 - 对象序列化

a. 将数据对象保存到文件

import pickle

data1 = {\'a\': [1, 2.0, 3, 4+6j],
         \'b\': (\'string\', u\'Unicode string\'),
         \'c\': None}

list1 = [1, 2, 3]
list1.append(list1)

f = open(\'data.pkl\', \'wb\')
pickle.dump(data1, f)     # 使用 protocol 0
pickle.dump(list1, f, -1) # 使用最高的协议
f.close()

b. 从文件中重构python对象

import pprint, pickle

f = open(\'data.pkl\', \'rb\')
data1 = pickle.load(f)
pprint.pprint(data1)

f.close()

6. 其他方法

# flush()方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入。
# 一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法。
f.flush()

# isatty()检测文件是否连接到一个终端设备,如果是返回True,否则返回False
ret = f.isatty()  # False

# fileno()方法返回一个整型的文件描述符,可用于底层操作系统的I/O操作。
fid = f.fileno()  # 文件描述符为 3

# next()获取下一行
line = next(f)

# truncate(size)从文件头开始截取size个字符,无size表示从截取当前位置到文件末的字符
f = open(\'C:/Users/HuangAm/test.txt\', \'r+\')
line = f.readline()  # 1.apple  读取一行
f.truncate()
line = f.readlines() # [\'2.apple\\n\', \'3.apple\'] 从当前读取到文件结束
f.seek(0) 
f.truncate(5)
line = f.readlines() # [\'1.app\']  截取5个字符
f.close()

7. OS 文件/目录方法

  os 模块提供了非常丰富的方法用来处理文件和目录。参考

 

二、错误和异常

1. 异常处理

import sys

try:
    f = open(\'myfile.txt\')
    s = f.readline()
    i = int(s.strip())
    raise NameError(\'Hi there\')    #  raise语句抛出一个指定的异常, 它必须是一个异常的实例或者是异常的类(即Exception的子类)
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise
else:         # else在try语句没有发生任何异常的时候执行
    print("No error!")
    f.close()

2. 用户自定义异常

  可以通过创建一个新的exception类来拥有自己的异常,异常应该继承自 Exception 类。当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类。

class Error(Exception):  # 异常的基类
    pass

class InputError(Error):
    def __init__(self, expression, message):
        self.expression = expression
        self.message = message
    
class TransitionError(Error):
    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message
   
try:
    raise InputError(2*2, "InputError")
except MyError as e:
    print(\'My exception occurred:\', e)

3. 定义清理行为

  try 子句里面有没有发生异常,finally 子句都会执行。如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后再次被抛出。

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("division by zero!")
    else:
        print("result is", result)
    finally:
        print("executing finally clause")
   
>>> divide(2, 1)
result is 2.0
executing finally clause

>>> divide(2, 0)
division by zero!
executing finally clause

>>> divide("2", "1")
executing finally clause    # 出现异常,else没有执行
Traceback (most recent call last): ...
TypeError: unsupported operand type(s) for /: \'str\' and \'str\'

预定义的清理行为

  一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。

# 当执行完以下代码后,文件会保持打开状态,并没有被关闭。
for line in open("myfile.txt"):
    print(line, end="")    

# 使用关键词 with 语句就可以保证诸如文件之类的对象在使用完之后,一定会正确的执行他的清理方法
with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

 

三、XML和JSON解析

1. XML解析

  常见的XML编程接口有DOM和SAX,而python有三种XML解析方法:SAX,DOM,以及ElementTree。

(1) SAX (simple API for XML )

  python 标准库包含SAX解析器,SAX是一种基于事件驱动的API。利用SAX解析XML文档牵涉到两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。SAX适于处理下面的问题:

  • 对大型文件进行处理;
  • 只需要文件的部分内容,或者只需从文件中得到特定信息。
  • 想建立自己的对象模型的时候。

students.xml文件及其解析结果:

<students>
    <student id="1">
        <name>Amy</name>
        <age>16</age>
    </student>
    <student id="2">
        <name>Daniel</name>
        <age>17</age>
    </student>
</students>

输出结果:
Student - 1
name: Amy
age: 16
Student - 2
name: Daniel
age: 17
View Code

SAX解析代码:

import xml.sax

class StudentHandler( xml.sax.ContentHandler ):
    def _init_(self):
        self.currentTag = ""
        self.name = ""
        self.age = ""
    
    def startElement(self, tag, attributes):
        self.currentTag = tag
        if tag == "student": 
            print("Student -", attributes["id"])
    
    def endElement(self, tag):
        if self.currentTag == "name":
            print("name:", self.name)
        elif self.currentTag == "age":
            print("age:", self.age)
        self.currentTag = ""
        
    # 读取字符时调用
    def characters(self, content):
        if self.currentTag == "name":
            self.name = content
        elif self.currentTag == "age":
            self.age = content
            
if(__name__ == "__main__"):
    parser = xml.sax.make_parser()  # 创建一个 XMLReader
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    Handler = StudentHandler()
    parser.setContentHandler(Handler)
    parser.parse("C:/students.xml")
    

(2) DOM (Document Object Model)

  DOM解析器在解析一个XML文档时,一次性读取整个文档,将XML数据在内存中解析成一个树,通过对树的操作来解析XML。可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。

from xml.dom.minidom import parse
import xml.dom.minidom

DOMTree = xml.dom.minidom.parse("C:/students.xml")
root = DOMTree.documentElement
stuList = root.getElementsByTagName("student")
for stu in stuList:
    print("Student -", stu.getAttribute("id"))
    name = stu.getElementsByTagName("name")[0]
    print("name:", name.childNodes[0].data)
    age = stu.getElementsByTagName("age")[0]
    print("age:", age.childNodes[0].data)

2. JSON解析

  JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。python 的原始类型与json类型的转化对应表如下:    

      

(1) 使用json.dumps 与 json.loads 解析JSON对象

import json
data = {
    \'no\' : 1,
    \'name\' : \'Runoob\',
    \'url\' : \'http://www.runoob.com\'
}

json_str = json.dumps(data)     # json.dumps()将Python字典转换为JSON对象
print ("Python 原始数据:", repr(data))
print ("JSON 对象:", json_str)

data2 = json.loads(json_str)    # json.loads()将JSON对象转换为Python字典
print ("data2[\'name\']: ", data2[\'name\'])
print ("data2[\'url\']: ", data2[\'url\'])

(2) 使用 json.dump() 和 json.load() 解析JSON文件

with open(\'data.json\', \'w\') as f:
    json.dump(data, f)   # 写入 JSON 数据

with open(\'data.json\', \'r\') as f:
    data = json.load(f)  # 读取数据

 

四、类

1. 类定义

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("My name is %s and I\'m %d years old." %(self.name,self.age))
        
    def printInfo(self):  # 类方法的第一个参数必须是self, 表示当前对象的地址,self.class 则指向类。
        print(self)
        print(self.__class__)
        

class student(people):    # 多继承时,若基类中有相同的方法名,而在子类使用时未指定,python会从左到右查找基类中是否包含方法。
    grade = \'\'
    def __init__(self,n,a,w,g):
        people.__init__(self,n,a,w)   #调用父类的构函
        self.grade = g
    
    def speak(self):  #覆写父类的方法
        print("My name is %s and I\'m in grade %s."%(self.name,self.grade))
 
 
s = student(\'Amy\',16,80,\'one\')  # 实例化类
s.speak()

2. 类的专有方法

"""
类的专有方法:
    __init__ : 构造函数,在生成对象时调用
    __del__ : 析构函数,释放对象时使用
    __repr__ : 打印,转换
    __setitem__ : 按照索引赋值
    __getitem__ : 按照索引获取值
    __len__:    获得长度
    __cmp__:  比较运算
    __call__:   函数调用
    __add__:  加运算
    __sub__:   减运算
    __mul__:  乘运算
    __div__:    除运算
    __mod__: 求余运算
    __pow__:  乘方
"""

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b
 
   def __str__(self):
      return \'Vector (%d, %d)\' % (self.a, self.b)  # Python同样支持运算符重载,我们可以对类的专有方法进行重载
   
   def __add__(self,other):  # 重载加法运算方法
      return Vector(self.a + other.a, self.b + other.b)
 
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)  # Vector(7,8) 这里用到两个重载方法
View Code

 

五、Python高级教程

1. MySQL数据库操作

import pymysql
 
# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )
 
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

# 建表
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")
sql = """CREATE TABLE EMPLOYEE (
         NAME  CHAR(20) NOT NULL,
         AGE INT,  
         SEX CHAR(1))"""
cursor.execute(sql)

# 插入、更新、删除语句
sql = """INSERT INTO EMPLOYEE(NAME,
         AGE, SEX)
         VALUES (\'Mac\', 20, \'M\')"""
sql = "INSERT INTO EMPLOYEE(NAME, \\
       AGE, SEX) \\
       VALUES (\'%s\', \'%d\', \'%c\')" % \\
       (\'Mac\', 20, \'M\')
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = \'%c\'" % (\'M\')
sql = "DELETE FROM EMPLOYEE WHERE AGE > \'%d\'" % (20)
try:
   cursor.execute(sql)
   db.commit()
except:
   db.rollback()  # 回滚
 

# 查询语句 fetchone(),rowcount()
sql = "SELECT * FROM EMPLOYEE WHERE AGE > \'%d\'" % (18)
try:
   cursor.execute(sql)
   results = cursor.fetchall()  
   for row in results:
      print ("name=%s,age=%d,sex=%s" % \\
             (row[0], row[1], row[2]))
except:
   print ("Error: unable to fetch data")
 
# 关闭数据库连接
db.close()
View Code

2. Socket网络编程

  Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

# 服务器端
# -*- coding: utf-8 -*-
import socket
import sys

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建 socket 对象
host = socket.gethostname()      # 获取本地主机名
port = 9876
serversocket.bind((host, port))  # 绑定地址
serversocket.listen(5)           # 设置最大连接数,超过后排队

while True:
    clientsocket, addr = serversocket.accept()  # (阻塞式)等待客户端连接     
    print("Client Address: %s" % str(addr))
    msg = \'Hello World!\'+ "\\r\\n"
    clientsocket.send(msg.encode(\'utf-8\'))
    clientsocket.close()
    
# 客户端
# -*- coding: utf-8 -*-
import socket
import sys

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建 socket 对象
host = socket.gethostname()  # 获取本地主机名
port = 9876                  # 设置端口号
s.connect((host, port))      # TCP连接服务,指定主机和端口
msg = s.recv(1024)           # 接收小于 1024 字节的数据
s.close()
print (msg.decode(\'utf-8\'))
View Code

3. SMTP发送邮件

# -*- conding:utf-8 -*-
import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header
 
sender = \'12345678@qq.com\'
receivers = [\'779858277@qq.com\']  # 收件人

# 1.普通文本邮件
message = MIMEText(\'Email Content...\', \'plain\', \'utf-8\') 发送普通文本

# 2.HTML格式的邮件
mail_msg = """<p>Email Content...</p> <p><a href="http://www.abc.com">this is abc.</a></p>"""
message = MIMEText(mail_msg, \'html\', \'utf-8\')      # 三个参数分别为:邮件正文,文本格式,编码方式

# 3.有图片的HTML格式的邮件
message = MIMEMultipart(\'related\')
mail_msg = """<p>Email Content...</p> <p><a href="http://www.abc.com">this is abc.</a></p>
              <p>image:</p><p><img src="cid:image1"></p>"""
msgAlternative.attach(MIMEText(mail_msg, \'html\', \'utf-8\'))
fp = open(\'test.png\', \'rb\')
img = MIMEImage(fp.read())
fp.close()
img.add_header(\'Content-ID\', \'<image1>\')  # 定义图片 ID,在 HTML 文本中引用
message.attach(img)

以上是关于Python基础 (下)的主要内容,如果未能解决你的问题,请参考以下文章

C++ 解释器/控制台/片段编译器

201555332盛照宗—网络对抗实验1—逆向与bof基础

20155201 李卓雯 《网络对抗技术》实验一 逆向及Bof基础

python之基础篇——模块与包

[vscode]--HTML代码片段(基础版,reactvuejquery)

逆向及Bof基础实践