python3学习笔记(2)

时间:2022-01-17 18:33:13
一、面向对象(初识)
由类和方法组成,类里面封装了很多功能,根据这个类,可以创建一个这个类的对象,即对象是根据这个类创建的,以后这个对象要使用某个功能的时候就从这个类里面的找。
例:
str
-功能一
-功能二
-功能三
-。。。

s1 = 'alex'
str即是类,s1即是根据这个类创建的一个对象。

二、set集合
set是一个无序、不重复、可嵌套的集合。

1、语法:se = {}或se = set()或se = set((11,22,33,33)),set()时其实是调用这个类里面的__init__方法
写法和字典相似,但字典是由key和值代表一个元素,而set中一个内容就代表一个元素。
例1
se = {'123','345'}

2、添加元素

s = set()
s.add(123)
print(s)
重复添加同一个元素,只打印一个

3、清除集合中的元素

s.clear()
print(s)

4、复制

s1 = s1.copy(s)
copy属于浅拷贝,deepcopy属于深拷贝

5、差值

s1 = {11,22,33}
s2 = {22,33,44}
s3 = s1.difference(s2)
print(s3)
将S1中存在,但在s2中不存在的元素放入s3

6、对称差值

s1 = {11,22,33}
s2 = {22,33,44}
s3 = s1.symmetric_difference(s2)
print(s3)
将s1中存在的,但在s2中不存在的元素放入s3,并且将s2中存在,但在s1中不存在的元素放入s3

7、差值更新

s1 = {11,22,33}
s2 = {22,33,44}
s1.difference_update(s2)
将S1中存在,但在s2中不存在的元素跟更新s1

8、对称差值更新

s1 = {11,22,33}
s2 = {22,33,44}
s1.symmetric_difference_update(s2)
print(s3)
将s1中存在的,但在s2中不存在的元素更新进s1,并且将s2中存在,但在s1中不存在的元素更新进s1

9、移除指定元素(元素不存在,不报错)

s1 = {11,22,33}
s1.discard(11)
print(s1)
如果移除的元素不存在,不会报错

10、移除指定元素(元素不存在,则报错)

s1 = {11,22,33}
s1.remove(11)
print(s1)

11、移除元素(随机移除一个元素,并返回被移除的元素)

s1 = {11,22,33}
ret = s1.pop()
print(s1)
print(ret)

12、取交集

s1 = {11,22,33}
s2 = {22,33,44}
s3 = s1.intersection(s2)
print(s3)
将s1和s2都有的元素,赋值到s3

13、取交集更新

s1 = {11,22,33}
s2 = {22,33,44}
s1.intersection_update(s2)
print(s1)
将s1和s2都有的元素,更新到s1

14、判断是否有交集

s1 = {11,22,33}
s2 = {22,33,44}
p = s1.isdisjoint(s2)
判断两个集合是否有交集,有则返回true,没有则返回false

15、并集

s1 = {11,22,33}
s2 = {22,33,44}
s3 = s1.union(s2)
print(s3)
将s1和s2的元素合并后复制到s3

16、更新

s1 = {11,22,33}
li = [1,2,3,4]
s1.update(li)
批量添加多个元素进s1,update可以接受可被for循环的数据
注,字符串也是一个可循环的数据

练习:
old_dict = {
"#1":8,
"#2":4,
"#4":2
}

new_dict = {
"#1":4,
"#2":4,
"#3":2
}

现有上述两个字典,实现以下需求:
1、应该删除哪几个槽位
2、应该增加那几个槽位
3、应该更新那几个槽位

三、函数初识
面向过程编程:从上到下一点一点的写,遇到重复的操作,一般复制之前的操作进行粘贴,造成代码可读性差、代码重用性差、代码量增加。
函数式编程:将会重复使用到的功能,定义成一个函数,在使用的时候调用函数即可
语法:
def f1(): #使用def关键字创建一个函数,函数名字是f1,解释器在创建函数时在内存中为这个函数开辟一个空间,将函数体添加进内存,并为函数创建一个名字,但不直行函数体,函数体在调用的时候才被直行。
pass #函数中所进行的操作
注,函数中还需定义返回值,来告诉函数调用者函数是否直行成功。
f1() #调用函数

例1:发邮件的函数
def send_mail():
try:
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

msg = MIMEText('邮件内容', 'plain', 'utf-8')
msg['From'] = formataddr(["瞿姜",'18963603513@189.cn'])
msg['To'] = formataddr(["瞿姜",'18963603513@189.cn'])
msg['Subject'] = "主题"

server = smtplib.SMTP("smtp.189.cn", 25)
server.login("18963603513@189.cn", "198787")
server.sendmail('18963603513@189.cn', ['18963603513@189.cn',], msg.as_string())
server.quit()
except:
#发送失败执行
return False
else:
#发送成功执行
return True

ret = send_mail() #ret用来接受函数的返回值
if ret:
print('发送成功')
else:
print('发送失败')
注:try、except、else用来接收异常,并执行相关语句,上文中try尝试运行函数体,如发生异常则运行except下的代码,否则运行else下的代码。

例2
def f1():
print('123')
return '111'
print('456')
f1()
注,在函数中,执行了return语句之后,立即停止执行函数,也就是说return后面的语句永远不会被执行。

例3
def f1():
print('123')
f1()
注:如果函数中没有定义返回值,则默认返回None

1、函数参数
def send_mail(xxoo):
try:
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

msg = MIMEText('邮件内容', 'plain', 'utf-8')
msg['From'] = formataddr(["瞿姜",'18963603513@189.cn'])
msg['To'] = formataddr(["瞿姜",'18963603513@189.cn'])
msg['Subject'] = "主题"

server = smtplib.SMTP("smtp.189.cn", 25)
server.login("18963603513@189.cn", "198787")
server.sendmail('18963603513@189.cn', [xxoo,], msg.as_string())
server.quit()
except:
#发送失败执行
return False
else:
#发送成功执行
return True

ret = send_mail() #ret用来接受函数的返回值
if ret:
print('发送成功')
else:
print('发送失败')

ret = sendmail('18963603513@189.cn')
注:xxoo是形式参数,在调用函数时,括号内传入实际参数,在函数体中相当于将xxoo作为一个变量,将实际参数赋值给xxoo,从而由函数体中使用。

例1
while True:
em = input('请输入邮箱地址:')
result = send_mail(em)
if result == True:
print ('发送成功')
else:
print ('发送失败')

例2
def send_mail(xxoo,content):
print('发送成功:',xxoo,content)
send_mail('18963603513@189.cn','SB')
注:形式参数可以有多个,在传入参数的时候也需要传入相应数量的实际参数。

2、默认参数
例1
def send_mail(xxoo,content,xx='ok'):
print('发送成功:',xxoo,content,xx)
send_mail('18963603513@189.cn','SB')
注:如果形式参数xx设置了默认值,那么在传入参数时,如果没有传入与xx位置对应的实际参数,xx就使用ok作为实际参数,如果为xx传入了实际参数,则使用传入的值作为xx的值。python中规定,如果为某个形式参数指定了默认参数时,这个形式参数必须放到所有形式参数的末尾。

3、指定参数
例1
def send_mail(xxoo,content):
print('发送成功:',xxoo,content)
send_mail(content='18963603513@189.cn',xxoo='SB')
注:可在调用的时候指定实际参数所对应的形式参数,这种情况下,传入的实际参数不需要与形式参数的位置一一对应。

4、动态参数
例1
def f1(*args):
print(args)
f1(11,22,'alex','hhhh')
注:可以使用*代表若干个参数,从而使一个形式参数可以接受多个实际参数,在函数体中,这个传入的若干个实际参数将会形成一个元组赋值给这个形式参数。

例2
def f1(*args):
print(args)
li = [11,22,33,44]
f1(li)
注:如果传入的实际参数是一个列表,那么在函数体内部,只会将这个列表作为元组中的一个元素赋值给形式参数。

例3
def f1(*args):
print(args)
li = [11,22,33,44]
f1(*li)
注:如果传入的实际参数也有*号,则表示将列表中的每个元素都转化成元组的每一个元素,字符串同理

例4
def f1(**args):
print(args)
f1(n1='li')
注:当形式参数有两个*时,表示传入的实际参数将成为字典中的元素,根据字典的特性,需要有key和value,因此在传实际参数时需要传入指定参数

例5
def f1(**args):
print(args)
dic = {'k1':'v1','k2':'v2'}
f1(**dic)
注:如果传入实际参数时也使用两个*,那么代表将参数单独形成一个字典,而不作为字典中的元素。

例6:万能参数
def f1(*args,**kwargs):
print(args,kwargs)
f1(11,22,33,44,k1='v1',k2='v2')
注:在形式参数既有*又有**的情况下,如过传入的实际参数既有列表又有指定参数,则会自动将列表放入*的列表中,将指定参数放入**的字典中。*的形式参数必须在**的形式参数前面,顺序不能够改变。

5、format()
format()函数是用于格式化输出的。
例1
s = 'i am {0},age {1}'.format('alex',18)

例2
s = 'i am {0},age {1}'.format(*['alex',18])

例3
s = 'i am {name},age {age}'.format(name='alex',age=18)

例4
s = 'i am {name},age {age}'.format(**{name:'alex',age:18})

6、补充知识
例1
def f1(a1,a2):
return a1 + a2

def f1(a1,a2):
return a1 * a2

ret = f1(8,8)
print(ret)
注:上述例子中,由于python的执行方式是从上到下的方式,当出现两个f1函数时,最后一次定义的函数生效,而第一次定义的函数所开辟的内存会被垃圾回收机制定期清除掉。

例2
def f1(a1):
a1.append(999)

li = [11,22,33,44]
f1(li)
print(li)
注:python在传参数的时候,传递的是对内存的引用,因此上述结果,li的结果是[11,22,33,44,999]

例3,局部变量
def f1():
name = 'alex'
print(name)
def f2():
print(name)
注:在函数中被定义的变量,只能在本函数体中使用,其作用域就是这个函数体。

例4,全局变量
name = 'alex'
def f1():
age = 18
print(age,name)
def f2():
age = 19
print(age,name)
注:由于变量name在文件中被定义,它的作用域是整个py文件,所有的作用域都可读。
注:定义全局变量时,变量名大写,这是一个潜规则,便于代码阅读。

例5
name = 'alex'
def f1():
age = 18
name = '123'
print(age,name)
注:如果在函数体中出现了一个与全局变量同名的局部变量,当函数在执行的时候会优先执行局部变量。即局部变量优先与全局变量使用。

例6
name = 'alex'
def f1():
age = 18
global name
name = '123'
print(age,name)
注:如果需要在函数体中修改一个全局变量,则需要在修改之前使用global变量名,声明一下这个变量是全局变量方可修改。

例7
name = [11,22,33]
def f1():
age = 18
name.append('44')
print(age,name)
注:如果全局变量是一个列表、字典、元组内的列表元素、集合,那么在函数体中可以直接修改,但不能重新赋值。

7、函数的写法潜规则
需要添加备注说明其作用
函数与函数之间需要空两行

四、三元运算(三目运算)
语法:name = 'alex' if 1 == 1 else 'SB'
等同于
if 1 == 1:
name = 'alex'
else:
name = 'SB'
注:三元运算其实就是对简单的if else语句的简写。

五、lambda表达式
语法:f2 = lambda a1: a1 + 100
等同于
def f2(a1):
return a1 + 100
注:可以是用lambda表达式来实现一些简单的函数。

六、内置函数
1、abs()
取绝对值的函数

n = abs(-1)

2、all()
接收一个可以被迭代的对象,如列表等,如果这个对象中的元素全都为真的时候返回真,有一个元素是假的则返回假
代表False:0,None,"",[],()

3、any()
接收一个可以被迭代的对象,如列表等,如果这个对象中的元素有一个是真的时候返回真,所有元素都是假的时候则返回假

4、ascii()
自动执行对象的__repr__方法

class Foo:
def __repr__(self):
return "333"

n = ascii(Foo())
print(n)

5、bin()
接受一个十进制,并把这个十进制转换为二进制返回,返回值格式为0b+二进制值

6、oct()
接受一个十进制,并把这个十进制转换为八进制返回,返回值格式为0o+八进制值

7、hex()
接受一个十进制,并把这个十进制转换为十六进制返回,返回值格式为0x+十六进制值

8、bool()
接受一个值,并返回这个值代表的布尔值,即True或False
代表False:0,None,"",[],()
代表Ture:1,-1," ",[ ],( )

9、重要:bytes()
一个字节是8位
一个UTF-8编码的汉字占3个字节
一个GBK编码的汉字占2个字节
bytes()的作用是将一个汉字转换成字节,返回的是以16进制形式表示的字节。
例1
s = "李杰"
n = bytes(s,encoding="utf-8")
print(n)

例2
s = "李杰"
n = bytes(s,encoding="gbk")
print(n)

10、bytearray()
原理同bytes(),但bytes()返回的是多个字节组成的字符串,而此函数返回的是将每个字节作为元素的列表。

11、str()
此函数可将已转换成字节的汉字转换成字符串,注意需要提供编码参数

s = "李杰"
n = bytes(s,encoding="utf-8")
a = str(n,encoding="utf-8")
print(a)

七、文件操作,open()函数
1、打开文件之打开方式
例1
f = open("db","r")
已只读方式打开文件

例2
f = open("db","w")
已只写文件方式打开文件,注:打开时会清空文件里面所有内容

例3
f = open("db","x")
如果当db文件存在的时候就报错,如果不存在就创建文件并以w方式打开文件,这是python3.X新增的。

例4
f = open("db","a")
f.write("李杰")
f.close
已追加方式发开文件,可在文件原有内容后追加内容。

注:需要根据文件的保存方式设置encoding,一般情况下以utf-8保存。读出来的是字符串,因此在写的时候也需要是字符串

例5
f = open("db","ab")
f.write(btyes("李杰",encoding="utf-8"))
f.close
注:在打开方式中加上b,表示直接读出来字节类型,因此写的时候也需要是字节类型,即二进制。

例6
f = open("db","r+",encoding="utf-8")
data = f.read()
f.seek(1)
f.write("777")
f.close
注:使用r+以可读、可写的方式打开文件(用的比较多),在python中,只要有了读的操作,指针就会放到最后,当添加内容时默认添加到最后,如果需要修改指针位置,可使用seek方法调整,但添加的内容会覆盖指针位置后面的字符,但seek永远是按照字节的位置定位,因此有可能会破*,因为一个汉字是3个或者2个字节

例7
f = open("db","r+",encoding="utf-8")
data = f.read(1)
print(f.tell())
f.write("777")
f.close
注:f.tell()显示读过以后指针所在的位置(永远以字节为单位)。

例8
f = open("db","w+",encoding="utf-8")
注:使用w+方式打开文件时,会先清除文件内的所有内容,之后进行写的内容才可以读。

例9
f = open("db","a+",encoding="utf-8")
注:使用a+方式打开文件时,所添加的字符永远在最后添加。

2、操作文件
例1
f = open("db","r+",encoding="utf-8")
f.read()
注:如果无参数则读取所有内容,如果打开时有b,则按字节读取,否则按字符读取

例2
f.tell()
注:获取当前指针位置

例3
f.seek()
注:指定指针位置,永远按照字节操作

例4
f.write()
注:写数据,如果有b则写入字节,否则写入字符

例5
f.close()
注:关闭文件

例6
f.fileno()
注:返回一个文件描述符

例7
f.flush()
注:将写入的内容强制刷入硬盘

例8
f.readable()
注:检测文件是否可读

例9
f.seekable()
注:检测指针是否可操作

例10
f.readline()
注:仅读取一行,读取过后指针在本行末尾,如果再次读取则会读取到后面一行

例11
f.write()
注:检测文件是否可写

例12
f.truncate()
注:清空指针所在位置以后的内容

例13(常用)
f = open("db","r+",encoding="utf-8")
for line in f:
print(line)
注:使用for循环,循环文件内容每一行并进行输出

例14
f.readlines()
注:将文件所有行读取,形成列表,并且每一行数据为列表中的一个元素

3、关闭文件
例1
f.close()
注:关闭文件

例2
with open("db") as f:
pass
注:使用with打开一个文件,在内部的代码块执行完毕后,自动关闭文件。

例3
with open("db1","r",encoding="utf-8") as f1,open("db2","w",encoding="utf-8") as f2:
times=0
for line in f1:
time += 1
if times <=10:
f2.write(line)
else:
break
注:使用with同时打开多个文件,执行操作后,同时关闭。使用场景:将db1某些内容写到db2中。

例4
with open("db1","r",encoding="utf-8") as f1,open("db2","w",encoding="utf-8") as f2:
for line in f1:
new_str = line.replace("alex","st")
f2.write(new_str)
注:将f1中每一行读取,然后替换“alex”再写入f2.

作业:
详细见:http://www.cnblogs.com/wupeiqi/articles/4950799.html