python 学习查阅笔记
python学习查阅笔记
python 总是一边学,一段时间不用就忘了,这里记录一下自己对python的笔记,方便以后查阅,我发现在案例中理解消化更为容易,做以下笔记,记录成为科学家的道路, 其中参考风变python, 中国大学mooc的 北大郭玮老师的《实用Python程序设计》,北理嵩天老师的《Python语言程序设计》
知识:print
print('我的幸运数字是%d和%d' % (8,16)) ## 用%d 表示点应该在的位置
## %d 整数显示
## %f 浮点数显示
## %s 字符串显示
### print 如何能不换行
print("hello", end=' ')
知识:算数运算符
print(2+1) # 加法
# 》》 3
print(1-2) # 减法
# 》》 -1
print(1*2) # 乘法
# 》》 2
print(1/2) # 除法
# 》》 0.5
print(2**3) # 幂
# 》》 8
print(10%3) # 取余数
# 》》 1
print(10%%3) # 取整数
# 》》 3
知识:if
知识:列表
s = ['a','b','c','d']
print(s) # 打印列表
# 》》 ['a', 'b', 'c', 'd']
print(len(s)) # 打印列表长度
# 》》 4
print(type(s)) # 打印列表长度
# 》》 <class 'list'>
print(s[3]) # 取第四个元素
# 》》 d
print(s[-2]) # 取倒数第二个元素
# 》》 c
print(s[0:4]) #打印列表[0,4)的元素
# 》》 ['a', 'b', 'c', 'd']
print(s[1:3]) ## 打印列表[1,3)的元素
# 》》 ['b', 'c']
print(s[1:]) ## 打印列表第二位及以后的所有的元素
# 》》 ['b', 'c', 'd']
print(s[:2]) ## 打印第二位以前的所有元素
# 》》 ['a','b']
s.append('e') ## 每次只能添加一个元素
print(s)
# 》》 ['a', 'b', 'c', 'd','e']
del s[:2]
print(s) ## 删除元素可以一次多删几个
# 》》 ['c', 'd', 'e']
知识:字典
d = {'a':['j','q','k'], 1:['a','b','c'], '321':456}
a = d['a'] # 取键为'a'对应的值
b = a[0] # 取键为'a'对应的值的第以为
print(a)
# 》》 ['j','q','k']
print(b)
# >> 'j'
print(d[1][0])
# >> 'a'
d['321'] = 654 # 修改'321'对应的内容
print(d['321'])
# >> 654
d[3.14] = 'circle' ## 直接赋值可以往字典中添加新的键值对
print(d)
# >> {'a':['j','q','k'], 1:['a','b','c'], '321':456, 3.14:'circle'}
del d['a']
print(d)
# >> {1:['a','b','c'], '321':456, 3.14:'circle'}
循环
range : 用法 : 取头不取尾
range(a, b, c)
# a : 计算从a开始,不填时候,默认为0
# b : 计数到b结束,不包括b
# c : 计数的间隔,不填时默认为1
for i in range(10):
print(i)
## 》》 [1, ... , 9]
range(0, 10, 3)
## 》》 [0, 3, 6, 9]
for…in… 可以在列表或者字典中遍历(range() 实际上也是一个列表)
while 满足要求时进入循环直到不满足
for i in range(10):
print(i)
j = 0
while j < 10 :
j = j+1
print(j)
bool 的三种判断方法
## 1. 数值的比较
## 6种比较方式 == ,!= , > , < , >=, <=
## 2. 数值做运算
## 以下全为false
bool(false)
bool(0) ## int
bool('') ## str
bool([]) ## 列表
bool({}) ## 字典
bool(None) ## 元组
## 3. bool值之间的运算
## 总共5种运算 and, or, not, in, not in
a = [1, 2, 3, 4, 5]
## in, not in 判断一个元素是否在一堆数据之中
print(0 in a)
4种新的语句
- break
- continue
- pass : 什么都不做
- else
函数
对于不定长情况,会考虑使用*
def menu(*barbeque):
print(barbeque)
menu('meat','chicken','fish')
如果想把局部变量搞成全局变量,可以使用global
def egg():
global quantity
quantity = 108
egg()
print(quantity)
知识 :类
类中定义的函数称为方法 类名.函数()
类中定义的变量称为属性 类名.变量
## 类方法和类属性
class 类A():
变量1 = 100
变量2 = 200
@classmethod ## 说明是类方法
def 函数1(cls): ## 需要使用类属性才需要这么写
print(cls.变量1)
print(cls.变量2)
类A.函数1()
类方法使用内外部参数的案例
## 类方法仅使用外部参数
一首诗 = ['《卜算子》','我住长江头,','君住长江尾。','日日思君不见君,','共饮长江水。']
class 念诗类():
def 念诗函数(参数):
for i in 参数:
print(i)
念诗类.念诗函数(一首诗)
## 类方法仅使用内部参数
class 念诗类():
一首诗 = ['《卜算子》','我住长江头,','君住长江尾。','日日思君不见君,','共饮长江水。']
@classmethod
def 念诗函数(cls):
for i in cls.一首诗:
print(i)
念诗类.念诗函数()
## 类方法同时使用内部参数和外部参数
class 加100类():
变量 = 100
@classmethod
def 加100函数(cls,参数):
总和 = cls.变量 + 参数
print('加100函数计算结果如下:')
print(总和)
参数 = int(input('请输入一个整数:'))
加100类.加100函数(参数)
增加修改类的属性
- 从内部,使用类方法来增加或者修改
- 从外部,用类.变量=xx进行直接添加或者修改
## 从【类的外部】增加/修改类属性
class 类A():
pass
类A.变量1 = 100
print(类A.变量1)
## 从内部增加/修改属性
class 类():
@classmethod
def 增加类属性(cls):
cls.变量 = input('请随意输入字符串:')
类.增加类属性()
print('打印新增的类属性:')
print(类.变量)
实例化后再使用与直接使用的格式略有差异
通过对比可以看到,实例化后再使用的格式,①是空着的,意思是这里不再需要@classmethod的声明,并且在第②处,把cls替换成了self。
同时,实例化后再使用的格式,需要先赋值然后再调用(第③处):
# 直接使用类
class 成绩单():
@classmethod
def 录入成绩单(cls):
cls.学生姓名 = input('请输入学生姓名:')
cls.语文_成绩 = int(input('请输入语文成绩:'))
cls.数学_成绩 = int(input('请输入数学成绩:'))
@classmethod
def 打印成绩单(cls):
print(cls.学生姓名 + '的成绩单如下:')
print('语文成绩:'+ str(cls.语文_成绩))
print('数学成绩:'+ str(cls.数学_成绩))
成绩单.录入成绩单()
成绩单.打印成绩单()
# 实例化之后
class 成绩单(): # ①不用再写@classmethod
def 录入成绩单(self): # ②cls变成self
self.学生姓名 = input('请输入学生姓名:') # ③cls.变成self.
self.语文_成绩 = int(input('请输入语文成绩:'))
self.数学_成绩 = int(input('请输入数学成绩:'))
def 打印成绩单(self):
print(self.学生姓名 + '的成绩单如下:')
print('语文成绩:'+ str(self.语文_成绩))
print('数学成绩:'+ str(self.数学_成绩))
成绩单1 = 成绩单() # ④创建实例对象:成绩单1
成绩单1.录入成绩单() # ⑤实例化后使用
成绩单1.打印成绩单()
ps , cls代表“类”的意思,self代表“实例”的意思,这样写是编码规范(程序员们的共识),但不是强制要求。理论上只要写个变量名占位,写什么都行,比如把self写成bbb,
如果当类支持实例化以后,就不能再直接使用类方法了,需要实例化以后再调用
如果修改类属性,所有实例都会受影响
如果只修改某一个实力的属性,其他的实例不会受影响
新增也是同样道理
实例方法和类方法
重写类方法
class 类():
def 原始函数(self):
print('我是原始函数!')
def 新函数(self):
print('我是重写后的新函数!')
a = 类() # 实例化
a.原始函数()
# 用新函数代替原始函数,也就是【重写类方法】
类.原始函数 = 新函数
# 现在原始函数已经被替换了
a.原始函数()
可以通过重写类方法,让实例方法发生变化,但我们不能重写实例方法
函数的初始化
初始化函数的意思是,当你创建一个实例的时候,这个函数就会被调用。
初始化函数的写法是固定的格式:中间是“init”,这个单词的中文意思是“初始化”,然后前后都要有【两个下划线】,然后__init__()的括号中,第一个参数一定要写上self,不然会报错。
同时,这个初始化函数照样可以传递参数。
class 成绩单():
def 录入成绩单(self):
self.学生姓名 = input('请输入学生姓名:')
self.语文_成绩 = int(input('请输入语文成绩:'))
self.数学_成绩 = int(input('请输入数学成绩:'))
def 打印成绩单(self):
print(cls.学生姓名 + '的成绩单如下:')
print('语文成绩:'+ str(self.语文_成绩))
print('数学成绩:'+ str(self.数学_成绩))
成绩单1 = 成绩单() # 实例化
成绩单2 = 成绩单() # 实例化
成绩单3 = 成绩单() # 实例化
成绩单1.录入成绩单()
成绩单2.录入成绩单()
成绩单3.录入成绩单()
成绩单1.打印成绩单()
成绩单2.打印成绩单()
成绩单3.打印成绩单()
class 成绩单():
def __init__(self,学生姓名,语文_成绩,数学_成绩):
self.学生姓名 = 学生姓名
self.语文_成绩 = 语文_成绩
self.数学_成绩 = 数学_成绩
def 打印成绩单(self):
print(self.学生姓名 + '的成绩单如下:')
print('语文成绩:'+ str(self.语文_成绩))
print('数学成绩:'+ str(self.数学_成绩))
成绩单1 = 成绩单('张三',99,88)
成绩单2 = 成绩单('李四',64,73)
成绩单3 = 成绩单('王五',33,22)
成绩单1.打印成绩单()
成绩单2.打印成绩单()
成绩单3.打印成绩单()
继承
类的继承很大程度也是为了避免重复性劳动。比如说当我们要写一个新的类,如果新的类有许多代码都和旧类相同,又有一部分不同的时候,就可以用“继承”的方式避免重复写代码。
在Python里,我们统一把旧的类称为父类,新写的类称为子类。子类可以在父类的基础上改造类方法,所以我们可以说子类继承了父类。
class 父类():
def __init__(self,参数):
self.变量 = 参数
def 打印属性(self):
print('变量的值是:')
print(self.变量)
class 子类(父类):
pass # pass语句代表“什么都不做”
子类实例 = 子类(2)
子类实例.打印属性()
class 基础机器人():
def __init__(self,参数):
self.姓名 = 参数
def 自报姓名(self):
print('我是' + self.姓名 + '!')
def 卖萌(self):
print('主人,求抱抱!')
class 高级机器人(基础机器人):
def 自报姓名(self):
print('我是高级机器人' + self.姓名 + '!')
def 卖萌(self):
print('主人,每次想到怎么欺负你的时候,就感觉自己全身biubiubiu散发着智慧的光芒!')
安迪 = 高级机器人('安迪')
在子类中可以重写父类的任何方法,包括初始化函数
class 基础机器人():
def __init__(self,参数):
self.姓名 = 参数
def 自报姓名(self):
print('我是' + self.姓名 + '!')
def 卖萌(self):
print('主人,求抱抱!')
class 高级机器人(基础机器人):
def __init__(self,参数,参数2):
self.姓名 = 参数
self.智商 = 参数2
def 自报姓名(self):
print('我是高级机器人' + self.姓名 + '!' + '智商高达' + str(self.智商) + '!' )
子类的多继承
顾名思义,“多重继承”就是一个子类从【多个父类】中继承类方法。格式是class 子类(父类1,父类2,……)
知识:编码
编码,即将人类语言转换为计算机语言,就是【编码】encode();反之,就是【解码】decode()。
‘你想编码的内容’.encode(‘你使用的编码表’)
‘你想解码的内容’.decode(‘你使用的编码表’)
print('凌少'.encode('utf-8'))
print('凌少'.encode('gbk'))
print(b'\xe5\x87\x8c\xe5\xb0\x91'.decode('utf-8'))
print(b'\xc1\xe8\xc9\xd9'.decode('gbk'))
文件读写
文件读写
- 读取文件
- 写入文件
读:
- 打开文件
- 读文件
- 关闭文件
## 第一步 打开文件
file1 = open('/Users/Ted/Desktop/test/abc.txt','r',encoding='utf-8')
## 路径分为绝对路径和相对路径,
## r 表示只读
## encoding 表示编码方式
filecontent = file1.read()
print(filecontent)
file1.close()
写:
- 打开文件
- 写入文件
- 关闭文件
file1 = open('/Users/Ted/Desktop/test/abc.txt','w',encoding='utf-8')
file1.write('张无忌\n')
file1.write('宋青书\n')
file1.close()
如果使用w会覆盖掉原有的内容,如果想要追加内容,需要用’a’
为了避免打开文件后忘记关闭,占用资源或当不能确定关闭文件的恰当时机的时候,我们可以用到关键字with,之前的例子可以写成这样:
# 普通写法
file1 = open('abc.txt','a')
file1.write('张无忌')
file1.close()
# 使用with关键字的写法
with open('abc.txt','a') as file1:
#with open('文件地址','读写模式') as 变量名:
#格式:冒号不能丢
file1.write('张无忌')
#格式:对文件的操作要缩进
#格式:无需用close()关闭
案例分析:
如果有一个叫scores.txt的文件,内容如下
罗恩 23 35 44
哈利 60 77 68 88 90
赫敏 97 99 89 91 95 90
马尔福 100 85 90
希望统计这四个学生的魔法作业的总得分,然后再写入一个txt文件
file1 = open('/Users/Ted/Desktop/scores.txt','r',encoding='utf-8')
## 使用readlines()进行按照行读取
file_lines = file1.readlines()
file1.close()
for i in file_lines:
## split()对字符串进行分割,join()把字符串进行合并
data =i.split() #把字符串切分成更细的一个个的字符串
print(i)
split()对字符串进行分割,join()把字符串进行合并
a=['c','a','t']
b=''
print(b.join(a))
c='-'
print(c.join(a))
常用其他模块的记录
- 使用自己的模块
- 使用别人的模块
random
import random
a = random.randint(1,100)
# 随机生成1-100范围内(含1和100)的一个整数,并赋值给变量a
print(a)
## 从seq(列表,元祖,字符串,字典)中随机选5个数
num = [1, 2, 3, 4, 5, 6,7]
choice = random.sample(num, 5)
a = random.random() # 随机从0-1之间抽取一个小数
print(a)
a = random.choice('abcdefg') # 随机从字符串/列表/字典等对象中抽取一个元素(可能会重复)
print(a)
a = random.sample('abcdefg', 3) # 随机从字符串/列表/字典等对象中抽取多个不重复的元素
print(a)
items = [1, 2, 3, 4, 5, 6] # “随机洗牌”,比如打乱列表
random.shuffle(items)
print(items)
csv
import csv
with open("test.csv",newline = '') as f:
reader = csv.reader(f)
#使用csv的reader()方法,创建一个reader对象
for row in reader:
#遍历reader对象的每一行
print(row)
print("读取完毕!")
import csv
with open('test.csv','a', newline='',encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['4', '猫砂', '25', '1022', '886'])
writer.writerow(['5', '猫罐头', '18', '2234', '3121'])
实操 : python 自动群发邮件
import smtplib
# smtplib 用于邮件的发信动作
from email.mime.text import MIMEText
# email 用于构建邮件内容
from email.header import Header
# 用于构建邮件头
import csv
# 引用csv模块,用于读取邮箱信息
# 发信方的信息:发信邮箱,QQ邮箱授权码
# 方便起见,你也可以直接赋值
from_addr = input('请输入登录邮箱:')
password = input('请输入邮箱授权码:')
# 发信服务器
smtp_server = 'smtp.qq.com'
# 邮件内容
text='''
人生苦短,我用Python
'''
# 待写入csv文件的收件人数据:人名+邮箱
# 记得替换成你要发送的名字和邮箱
data = [['wufeng ', 'wufeng@qq.com'],['kaxi', 'kaxi@qq.com']]
# 写入收件人数据
with open('to_addrs.csv', 'w', newline='') as f:
writer = csv.writer(f)
for row in data:
writer.writerow(row)
# 读取收件人数据,并启动写信和发信流程
with open('to_addrs.csv', 'r') as f:
reader = csv.reader(f)
for row in reader:
to_addrs=row[1]
msg = MIMEText(text,'plain','utf-8')
msg['From'] = Header(from_addr)
msg['To'] = Header(to_addrs)
msg['Subject'] = Header('python test')
server = smtplib.SMTP_SSL()
server.connect(smtp_server,465)
server.login(from_addr, password)
server.sendmail(from_addr, to_addrs, msg.as_string())
# 关闭服务器
server.quit()