Python入门到精通
python从入门到精通
内存中存储的时数据的二进制形式
存储数据:
1、计算机先开辟空间,在存储数据,计算机开辟空间的最小单位时字节。
2、在数据存储时,用最高标识符号位,0表示正数,1表示复数。
原码,反码,补码
原码:规定了字节数,写明了符号位,得到了数据的原码
反码:正数的反码就是其原码,复数的反码就是其原码的符号位不变其他位取反
补码:正数的补码是其原码(正数三码合一)
运算符:
算数运算符 | + - * / % // ** |
---|---|
赋值运算符 | = |
成员运算符 | in not in 如果在指定序列中找到值返回True,否则返回False |
逻辑运算符 | and or not |
位运算符 | & | ^ << 左移 > |
三目运算符 | 类似这种的 'a大于b' if a > b else "a不大于b" "a>b" ? 1:2 |
比较运算符 | > < >= <= == |
# 转义字符: 特殊的字符串
-
\b 退格符 类似删除键
-
\n 换行符
-
\r 回车符 每次遇到\r光标都会回到最开始
-
\t 制表符 4个空格
-
" 双引号
-
' 单引号
-
\ 反斜线
python的七个基本数据类型
-
数字类型——int
-
布尔类型——bool
-
字符串类型——string
-
字典——dict
-
列表——list
-
集合——set
-
元祖——tuple
字符串:
1.字符串的索引
# 定义一个字符串,进行索引 str = 'https://blog.csdn.net/qq_37171353/article/details/77943817' str[0]
str[start:ends:step] -----> 第一位:开始位置;第二位结束位置;第三位:步长值(通过正负值判断正反向) 常用函数: find 、replace、count、lower、upper、startwith、endswith、strip # 更多字符串的操作请点击---> www.baidu.com path = 'http://www.baidu.com/image/logo.jpg' print(path[path.rfind('.')+1:]) # 先找到位置,再切片 result1 = path.replace('/','$',path.count('/')) # 将path中的所有’/‘ 替换位$ print(result1) print(path.isdigit()) # 判断path是否位数字 print(path.isalpha()) # 判断path是否位字母 print(path.islower()) # 判断是否位小写 print(path.isupper()) # 判断是否位大写 print(path.startswith('http')) # 判断是否为http开头 print(path.endswith('jpg')) # 判断是否为jpg结尾 path = 'c://image/img/a1.jpg' # 文件上传里类型 if path.endswith('jpg') or path.endswith('png') or path.endswith('gif'): print('允许上传') else: print('不是图片格式') s = 'Hello' result = path.strip() # 去除字符串的空格(lstrip、rstrip)左右侧 **#字符串的索引中index()和find() 的不同之处,index--》ValueError: substring not found,而对于find -->返回 -1。**
2.对字符串的连接:
join() enumerate()找字符串的位置**
names = ['妹妹1','黄头发的妹妹','短头发的妹妹'] result = ':'.join(names) 妹妹1:黄头发的妹妹:短头发的妹妹 print(list(enumerate(list2))) # 找出字符串的位置 # [(0, '马化腾'), (1, '马云'), (2, '任正非'), (3, '李宏彦'), (4, '刘强东')] for index,name in enumerate(list2): print(list2[index])
str.center(20,“”) #居中给左右填充*
ljust()将字符串左对齐右侧填充
rjust()将字符串右对齐左侧填充
encode() 转换字符集
str.strip():删除字符串两边的指定字符,括号的写入指定字符,默认为空格 str.lstrip():删除字符串左边的指定字符,括号的写入指定字符,默认空格 str.rstrip():删除字符串右边的指定字符,括号的写入指定字符,默认空格 str.upper() str.lower() 转换为大小写
4.格式化字符串:
# 如果不给变量起名字,默认一一对应
name = '小花'
content = '二狗哥!真帅啊!'
s = '{}说:{}听说他学完python了,挣了{}个亿'.format(name, content, 2.5)
# 可以通过给变量起名,达到复用的作用
s1 = '{name1} 说:有一个小目标!{name2}说:我不喜欢钱!'.format(name1='王健林', name2='马云')
print(s1)
# 保留小数位置
s2 = '{:s}这个月挣到了:{:.2f}'.format('马哥', 19999.5323)print(s2)
5.字符串的切片:
split('/',2) # 从开始位置切
rsplit() #从右侧切
splitline() #对长文本按行替换
replce('#',2) #字符串的替换
列表(list):
指令操作符:
1.添加字符
append() extend() insert()
list1 = []
# 增加:append extend insert
list1.append('马云') # 按照队列顺序添加
list1.append('刘强东')
list1.append('马化腾')
print(list1)
list1.extend('str') #对可迭代对象,继承
print(list1)
print('---->insert')
list1.insert(1,'kk') #按照下标添加
print(list1)
2.删除字符
pop() remove() clear()
list1.pop(1) # 默认从结束位置删除
print(list1)
list1.remove('马云') # 按照内容删除
print(list1)
list1.clear() # 清除list内容
print(list1)
del list1 # 清除所占内存
print(list1)
3.改变字符
list1[1]=0 # 改变列表中的值
print(list1)
4.查看列表中的值---in (not in)
i=1
if i in list1:
print('{}在列表中'.format(i))
5.对列表中的整体数据进行操作
排序sort() ---> reverse=True 翻转
sum() min() max() count() 统计字符次数
list6 = [2, 4, 6, 2, 2, 7, 8]
list6.sort(reverse=True) # 对列表进行排序sort()
print(list6)
steps = [1, 2, 3, 4, 5, 6, 2, 5]
result = sum(steps) # list的和
print(result)
result1= max(steps) # list的最大值
print(result1)
result2=min(steps) # list的最小值
print(result2)
# 列表进行添加/删除元素时,循环体中下标的变动会使结果出现跳号
# (找到元素所在位置的四种方法)
numbers = [1, 6, 5, 6, 4, 3, 8, 2, 1, 9]
# 方法一:
# index = 0#
for num in numbers:
#
# if num == 6:
# print('找到元素:{},位置:{}'.format(num, index))
# index += 1
# 方法二:
# for index,num in enumerate(numbers):
# if num==6:
# print('找到元素:{},位置:{}'.format(num, index))
#
# 方法三:
# for num in numbers:
# if num == 6:
# print('找到元素:{},位置:{}'.format(num, numbers.index(6)))
#
# result = numbers.index(6) -->只能找到第一个
# print(result)
print('$$$$$$$$$$$$$$$$$$$$$$$$$$$')
# 方法四
# i=0# while i<len(numbers):
# if numbers[i]==6:
# print('找到元素:{},位置:{}'.format(numbers[i],i))
# i+=1#
list支持切片操作:
list1 = [[1,2,3],[4,5,6][7,8,9]]
print(list1[0]) # [1, 2, 3]
print(list1)
list1[1].insert(0,8)
print(list1) # [[1, 2, 3], [8, 4, 5, 6], [7, 8, 9]]
元祖(tuple):
元祖可以进行 加/减/乘法的操作,并且应该注意元祖中的数据只能进行读取(可以惊醒强制转换—————list(tuple)
tuple3=(3,) # 元组中只有一个元素,不加逗号默认为int
tuple4=tuple2+tuple3 # 元组支持加法
print(tuple4)
print((3,)*5) # 元组支持乘法 (3, 3, 3, 3, 3)
tuple0 =(1,2,3,4,5) # 判断 元组中在不在
print(1 in tuple0)
print(3 not in tuple0)
系统函数: sum max min sorted len sum max min sore
转换: list(变量) 变量:tuple ,str tuple()
变量为字符串:将字符产拆开放入列表
集合:
关键字:set {} 可以用来去除重复项
引入:无序 不重复
列表和元祖:支持下标
1.创建
set1 = set() # 空集合这样创建
print(type(set1))
set2 = {1, 2, 3, 4, 1, 2} # 不重复
print(set2)
set3 = {} # 表示创建一个dict
print(type(set3)) # <class 'dict'>
2.无序:
保存的顺序和输出的顺序不是一致的,所以没有下标
list:链表实现
set: hash表实现
3.增删
iterable: list tuple str set
添加:add() update(iterbale) 一组添加
删除:pop() remove(e) del discard类似remove(区别---当没有元素是不会报错)
# 1.交集
result = set1.intersection(set2)
print(result)
result = set1 & set2
print(result)
# 2.并集
result = set1.union(set2)
print(result)
result = set1 | set2
print(result)
# 3.差集 set1中有,set2中没有的部分
result = set1.difference(set2)
print(result)
result = set1 - set2
print(result)
# 4.对称差集 set1中有,set2中也有,但是不是共同拥有的部分
result = set1.symmetric_difference(set2)
print(result)
result=set1^set2
print(result)
字典:
# 字典的创建
dict1={} # 空字典
dict2={'001':'张三','002':'list','003':'王五'}
print(dict2)
1.添加
dict1['001']='xingdong'
print(dict1)
2.修改
如果字典中存在这个key,则会发生值的修改,判断值替换旧的值
dict1['001']='xingdong'
print(dict1)
3.删除 查询get()
pop(key) 表示根据key删除键值对
popitem() 表示随机删除任意一对(实际删除最后一个【字典也是根据哈希值保存,因此是随机】)
clear()
del
dict1.pop('001')
print(dict1)
dict1.popitem() # 随机删除任一对键值对
print(dict1)
dict1.clear()
print(dict1) # 清空dict1
del dict1['001'] # 删除键值对
print(dict1)
del dict1 # 删除内存
print(dict1)
3.查看
print(students['wangwu']) # 当key不存在是报错(使用get方法则返回NULL)
print(students.get('wangwu1'))
result = students.keys() # key值
print(list(result))
result = students.values() # value 值
print(list(result))
result = students.items() # 得到 key 和 value
print(list(result))
for key,value in students.items(): # 字典的遍历
print(key,value)
可变与不可变:
可变: 内存地址没有发生改变,但是里面内容可以变化
不可变: 只要值有变化则内存地址就变啦
不可变的类型: int str tuple float bool
可变的类型: list set dict
可迭代的:
可迭代的类型: list tuple set dict str
总结: 所有可迭代的可以与for..in
判单值的类型 与 迭代
a = 10
print(isinstance(a, int)) # 判断是否是int型
print(isinstance(a, str))
from collections import Iterable # 判断可迭代必须导入迭代
print(isinstance(a, Iterable))
推导式
列表推导式:[x for i in range(100)]
字典推导式:{k:v for k,v in item}
集合推导式:{k for k in list1}
# 列表推导式
list1 = [i for i in range(1, 21) if i % 2 == 0]
print(list1)
# 1~9的平方组成的列表
list2 = [i ** 2 for i in range(1, 10)]
print(list2)
# if... else.. 格式放前面
result = [i - 1 if i % 2 != 0 else i + 1 for i in list5] # if... else.. 格式放前面
print(result)
# 字典推导式:{key:value for key,value in dict1.items()}
dict2 = {value: key for key, value in dict1.items()}
print(dict2)
list1 = ['aa', 'bb', 'cc', 'dd']
dict3 = {value: index + 1 for index, value in enumerate(list1)}
print(dict3)
# 集合推导式
set1 ={i for i in range(10) if i%2==0}
print(set1)
函数:
函数: 执行某个特定任务的一段代码。通过def关键字将此代码封装起来。 封装起来的整体称作'函数'。
作用: 减少代码的重复,提高代码的可读性
# 可变参数
# 打包 装包
a,b,*c =[1,2,3,4,5]
print(a) # 1
print(b) # 2
print(c) # [3, 4, 5]
x,y,*z=1,2,3,4
print(x,y,z) # 1 2 [3, 4]
x,*y,z=1,2,3,4
print(x,y,z) # 1 [2, 3] 4
a,b,*c=[1,2,3,4,5] # 1.拆列表 2.将多余的包装到c
print(a,b,c) # 1 2 [3, 4, 5]
# 可变参数在函数中的应用:
*args **kwargs(位置参数)
引入:
positional arguments:
def func(**kwargs):
print(kwargs) --->kwargs就是字典
func(name='',age=18) -->只有**kwargs 必须传入 位置参数:name=‘’ 得到字典类型 {‘age’:18}
func('kk',*list) #### 将列表拆开传入
参数:
无参
有参:
1.普通参数
2.默认参数
3.关键字参数
4.可变参数
返回值:
return
def func():
print('hello world!')
list1=[4,5,6,7,8,9]
sum=0
for i in list1:
sum+=i
print('累加和:',sum)
return sum
result = func() # 返回值需要一个result来接收
print(result)
func()
# 注意:定义的参数的个数 与调用时的参数个数要一致
L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内建作用域
全局的变量是每个函数都可以访问的,但是如果想修改全局变量则需要添加global声明
注意: 如果全局变量是不可变的(int str tuple xfloat),在函数中发生修改则需要添加global
但是如果是可变的(list set dict) 可以不添加global
def test1():
print('----------->test1')
def test2():
print('----------->test2')
def func(): # 函数之间可以调用,不需要参数
test1()
test2()
func()
高阶函数:
匿名函数:lambda x,y:x+y 这样的简单语句叫匿名函数
系统中,有些函数可以将函数作为参数使用,这些函数就是高阶函数。
filter(function,iterable) ----> function通常函数是一个匿名函数,而且该函数返回值是True或者False
list1 = [1, 2, 3, 4, 'a', 'b', 'c', 'd']
list2 = filter(lambda x: isinstance(x, int), list1)
print(list(list2))
list3 = [1, 3, 4, 5, 6, 2, 0, 8]
list4 = filter(lambda x: x % 2 == 0, list3)
dict1 = {'zhangsan': 18, 'lisi': 12, 'wangwu': 22, 'zhaoliu': 19}
result = filter(lambda x: x > 20, dict1.values())
print(list(result))
sorted(iterable,key=function[,reverse=True]) ----> 根据key指定的条件进行排序,其中key的值是一个函数(匿名函数)
goods = [('防脱发洗发水', 60,3), ('格子衫', 156,1), ('牛仔裤', 99,7)]
goods = sorted(goods, key=lambda g:g[2],reverse=True)
print(goods)
books={'001':['防脱发指南',45,9,'李某'],'002':['颈椎康复指南',49.8,'雷某'],'003':['活着',28,'张某']}
books=sorted(books.items(),key=lambda x:x[1][1])
print(books)
map(function,*iterables) ----->映射, 给一个可迭代对象返回一个新的可迭代的(依赖函数function产生)
list1 = [1, 2, 3, 4]
result = map(lambda x: x ** 2, list1)
print(list(result)) # [1, 4, 9, 16]
list2 = [5, 6, 7, 8]
result = map(lambda x, y: x + y, list1, list2)
print(list(result)) # [6, 8, 10, 12]
from functools import reduce
reduce(function,sequence,[initial]) ---> function: 必须两个参数, sequence: 序列 (list,元组,set)
作用就是对序列中的元素进行迭代运算
闭包:
闭包:在一个外层函数中定义了一个内部函数,内部函数使用了外部函数的临时变量,并且外部函数的返回值是内部函数。
重点:
1. 嵌套
2. 内部使用了外部变量
3. 返回的是内部函数
装饰器:
# 定义一个装饰器
def decorator(func): # 将函数gift当作参数(func)传入
print('-------->1')
def wrapper(): # wrapper指向gift(参数也当一致)
# 调用原函数
func()
print('包装上漂亮的包装纸')
print('机上漂亮的蝴蝶结')
print('-------------->2')
return wrapper
@decorator
# 1.将gift作为参数传递给decorator的func参数 2.执行了decorator 3.将返回值丢出,给gift重新赋值
def gift(): # gift = wrapper
print('买了一个毛绒玩具!')
print('-------------------------->3')
gift() # wrapper()
结果:
-------->1
-------------->2
-------------------------->3
买了一个毛绒玩具!
包装上漂亮的包装纸
机上漂亮的蝴蝶结
====================================================================
装饰器如何装饰多个函数:
格式:
def decorator(func):
def wrapper(*args,**kwargs):
...
...
fun()
...
return wrapper
@decorator
def test():
print('----->test')
test
# 带参数的装饰器
def decorator(args1): # args1 是装饰器传入的参数
def wrapper_outer(func):
def wrapper(*args, **kwargs):
print('------>装饰前',args1)
if args1=='AA':
func(*args, **kwargs)
print('成功进入bb')
else:
print('路径错误!!!')
print('------>装饰器',args1)
return wrapper
return wrapper_outer
@decorator('cc')
def test1():
print('---------->test1')
多层装饰器:
如果一个函数有多层装饰器,谁离函数最近,谁先使用哪个装饰器,装完之后再使用外层装饰器开始拆
def decorator(func):
print('------包装纸---->A')
def wrapper(*args, **kwargs):
print('------->包装纸 before')
func()
print('--包装纸----->after')
print('------包装纸--------->B')
return wrapper
def decorator1(func):
print('-------蝴蝶结-----A')
def wrapper(*args, **kwargs):
print('------->蝴蝶结 before')
func() # 包装纸的wrapper
print('----蝴蝶结----->after')
print('-------蝴蝶结-------->B')
return wrapper
@decorator1
@decorator
def test():
print('---------->test')
test()
总结:遇见装饰器先加载离函数最近的,加载完成后从外层开始拆解即可。
递归函数:
定义一个函数,函数的内部调用了自身函数。
1.关键要有出口
2.逐渐要向出口靠近
斐波那契数列
生成器:
产生生成器:
1.列表生成式 g=(i for i in range(1000))
2.函数+yield=生成器
yield 关键字 · return i + 暂停
下次再次调用的时候就暂停的位置向下执行
如果向获取生成器的值:
1.next(g生成器对象) --》 产生一个元素
如果使用next()获取生成器对象元素,如果没有元素了 ,再调用next()则会报错stopiteration
2.借助于生成器自身方法
list str
生成器对象.__next__() 类似 next(生成器对象)
send(值) 类似 生成器__next__() + 传值
注意 :
第一次必须传None
#产生方法一
g = (i for i in range(100) if i % 5 == 0)
print(next(g))
print(next(g))
print('------------------------')
# 产生方式二
def func():
print('-------->来啦!')
for i in range(1, 5):
yield i # 暂停 + return
print('------>hello',i)
print(func) # 打印函数对象
g = func() # 产生生成器对象(必须产生才能使用)
print(g)
# print(next(g))
# print(next(g))
g.__next__()
g.__next__()
# 产生方式三
def func():
print('-------->来啦!')
for i in range(1, 5):
e=yield i # 暂停 + return
print('------>hello',i,e)
g.send(None)
print(g.send('good'))
print(g.send('good1'))
迭代器、生成器、可迭代对象
迭代器,可迭代的,生成器
可迭代的未必肯定是迭代器(比如list列表,set,tuple,dict,str是可迭代的值但不是迭代器)
但是生成器是可迭代的也是迭代器
可以通过系统函数next(对象)得到一个元素的,称作迭代器
可迭代的 ————> 迭代器 ————> 生成器
可以遍历的 可以通过系统函数net() 生成的过程
from collections import Iterable, Iterator
list1 = [1, 2, 3, 4, 5] # 可迭代对象
print(isinstance(list1, Iterable)) True
print(isinstance(list1, Iterator)) False
g = (x for x in range(5)) # 迭代器
print(isinstance(g, Iterable)) # True
print(isinstance(g, Iterator)) # True
print('--------------------')
li = iter(list1) # 通过iter()强制转换可得到迭代器
print(isinstance(li, Iterable)) # True
print(isinstance(li, Iterator)) # True
面向对象:
类属性的修改:类名.属性名=新值
对象的属性: 对象.属性名=新值 (对象中有没有这个属性,如果有相当于更新值,没有则
再对象中添加一个新的属性)
属性的搜索顺序: 对象名.属性
1.先找对象本身,如果有则去自身的属性
2.没有属性,则去类中获取,有则取出
3.没有则报错
class Student():
# 类属性
name = 'kk'
age = 20
# 类方法
def func(self):
print('------->hello')
shijie = Student() # 创建对象
print(shijie.name) # 调用类属性
Student.name='李四' # 修改类的属性
shijie.name='张三' # 动态赋值----> 修改对象的属性
# 对象中如果没有此属性,就会再对象中添加一个属性,如果存在此属性改变原有的值
初始化对象
'''
使用__init__ 实现对象的统一(使每个对象都有相同的属性)
作用:
1.创建对象的'必经之路‘__init__
2.通过__init__达到所有对象属性的统一
3.__init__函数的self是指当前对象(对象本身)
'''
class Game:
# 创建对象的时候规定每个对象的属性 init 初始化方法
def __init__(self,name,company):
self.name=name
self.company=company
print('----->创建对象了')
def eat(self,*food): # *food传入的是元组,需要遍历
print(self.name+'喜欢吃:')
for i in food:
print(i+'\t',end='')
print()
def sleep(self,hours):
# print(self.name+'睡觉啦!一下睡了'+str(hours)+'小时')
print('{}睡觉了,一下睡了{}小时'.format(self.name,hours))
# 只要创建对象,系统默认会调用__init__方法
lol=Game('反恐精英1','拳头公司1')
类方法:@clssmethod
类方法的定义:
@classmethod
def 方法名(cls)
pass
类方法特点:
1.类方法中无法访问对象属性和方法
2.必须使用classmethod装饰器定义
3.类方法的参数式:cls 贷表的式类对象 类本身person
4.访问方法:类名.类方法 对象.类方法名()
class Person:
# 类属性
country="china"
def __init__(self,name):
self.name=name
def show(self):
print('姓名是:{}'.format(self.name))
@classmethod
def test(cls):
# print('国家:{},姓名{}'.format(Person.country,cls.name)) 不可访问类方法之外的属性
# cls.show() 不可访问类方法之外的方法
print('国家:{}'.format(Person.country))
@classmethod
def test1(cls):
cls.test() # 可以访问‘兄弟’ test()
# 对象可以调用类方法,但是类方法中只能访问类属性和类方法
print('---------------->test1')
p1=Person('zhangsan')
p1.test() # 类方法的调用 对象.类方法名()
Person.test() # # 类方法的调用 类.类方法名()
静态方法:
定义:
class类名:
@staticmethod
def 静态方法():
pass
魔术方法:
魔术方法就是一个类的特殊方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法由系统自动调用。(有很多可以查看文档使用)
-
所有类的super默认都是object
-
触发时机: 在实例化对象时触发
-
参数:至少一个cls 接收当前类
-
返回值:必须返回一个对象实例
class Person: def __init__(self): print('------->init person') def __new__(cls): # 先调用这个方法,再调用__init__ print('------->new Person') # 该方法传入参数将重新开辟空间,勿动 # return super(Person,cls).__new__(cls) return object.__new__(cls) def __del__(self): print('---------->我被回收了!') # 对象内存自动回收 def __str__(self): return '商品:{},数量:{},价格:{}'.format(self.gname, self.gnum, self.price) def __repr__(self): return '商品:{},数量:{},价格:{}'.format(self.gname, self.gnum, self.price) p = Person() print(p) # 本该打印对象地址,str方法修改了打印结果,( repr类似不过print(repr(p))调用 ) del p # 手动释放对象内存空间
__new作用:实例化对象
注意:
-
实例化对象是Object类底层实现,其他类继承了Object的new才能够实现实例化对象。
-
没事别碰这个魔术方法,先触发new才会触发init
-
del():析构函数 垃圾会收,释放调用对象的空间
当两个对象需要进行比较的时候出发对应的函数
lt <
gt >
le <=
ge >=
eq == 需要重写方法
class Goods:
def __init__(self, gname, price):
self.gname = gname
self.price = price
def __lt__(self, other): # 传入> 或 < 都可以比较
print('----<lt')
return self.price < other.price
def __gt__(self, other):
print('=====>gt')
return self.price > other.price
# 涉及到商品内容的比较
def __eq__(self, other): # 需要重写方法
# 比较地址
if id(self)==id(other):
return True
else:
# 比较内容
if self.gname==other.gname:
# 比较价格
if self.price==other.price:
return True
else:
return False
good1 = Goods('酸奶', 5)
good2 = Goods('牛奶', 3)
print(good1 > good2)
print(good1 < good2)
print(good1 == good2)
封装:
-
属性和方法封装到类中
-
将属性私有化,定义公有的set和get方法设置或者访问值
-
私有化:属性或者方法只能在类体中被访问
-
之所以私有化外界访问不到是因为,解释器在底层给__属性偷偷改名了格式
get() set() 方法获取私有化对象
@property @setter 方法获取私有方法
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
@property # 类似get方法
def age(self):
return self.__age
@age.setter # 类似set方法
def age(self, age):
if isinstance(age, int):
if 120 > age > 0:
self.__age = age
else:
print('年龄错误')
else:
print('年龄必须是一个整型的')
person = Person('sicong', 30)
# 改名
person.name = 'wangsicong'
person.age=23
print('我的名字是:', person.name)
print('年龄是:', person.age)
总结:
-
私有化:_ _属性名 双下划线 只能在类中访问
-
公有化:属性名
-
受保护的:_属性名 在类体中,对象,子类可以访问
继承:
子类只能继承父类公有的属性和方法,受保护属性和方法也是可以继承
class Animal:
def __init__(self, type, name, color):
self.type = type
self.name = name
self.color = color
self.__age = 1
self._gender = '公' # 子类是可以继承的
def __eat(self, food):
print(self.name + '太喜欢吃' + food)
def printAge(self):
print(self.__age) # 只能访问自己的__age方法
def __str__(self):
return self.type + '\t' + self.name + '\t' + self.color
class Cat(Animal):
def __init__(self, type, name, color, age):
# 调用父类的__init__方法
Animal.__init__(self, type, name, color)
self.__age = age
def catch_mouse(self):
print('我是小猫,就喜欢抓老鼠!'+self._gender)
def getAge(self):
return self.__age # 访问子类自己的私有属性__age
# 创建对象
xiaohua = Cat('猫', '小花', '黄色', 3)
xiaohua.catch_mouse()
# xiaohua.__eat('小鱼')
print(xiaohua.getAge())
xiaohua.printAge()
重写 override
父类的属性或者方法不能满足子类需求,子类中定义了一个跟父类的方法或者属性同名的,
这种情况下就会发生重写(覆盖)
如果子类的方法中需要调用父类的方法
-
父类名.方法名(self)
-
super(子类名,self).方法名()
class Person(object):
def __init__(self):
print('----->Person')
def run(self):
print('喜欢跑步!')
def sleep(self):
print('人人都喜欢睡觉')
class Student(Person):
def __init__(self, name):
# Person.__init__(self) 调用父类方法
super(Student, self).__init__() #调用父类方法
self.name = name
def run(self):
# super(Student, self).run()
Person.run(self)
print(self.name+'每天跑步5公里')
class MiniStudent(Student):
def test(self):
print('测试ministudent')
s = Student('小耕')
s.run()
s.sleep()
ms = MiniStudent('土行孙')
ms.test()
python多继承的搜索顺序:
-
深度优先
-
广度优先
通过打印 Child.mro可以得到类的先后顺序
新式类: 多继承的搜索顺序都是:深度优先
class Father1:
def testA(self):
print('---------------->father1 test')
def test(self):
print('----------->AAAAAAAAA test')
class Father2:
def testB(self):
print('-------------------->father2 test')
def test(self):
print('---------->bbbbbbbbbb test')
class Child(Father1, Father2):
def testC(self):
print('----------------->child test')
c = Child()
c.testA()
c.testB()
c.testC()
c.test()
print(Child.__mro__) # 查看搜索顺序
has a 关系:
'''
class Student:
def borrow_book(self,book):
pass
student has a book
一个对象可以作为参数传给另一个对象
book对象作为参数传给Student对象
is a 继承
'''
class Student:
def __init__(self, name):
self.name = name
self.books = []
# 借书
def borrow_book(self, book): # book 就是书对象
for booka in self.books:
if booka == book:
print('已经借过此书!不能再借')
break
else:
# 借书
self.books.append(book) # [book对象,book对象,....]
book.reduce_book() # 图书的减少
print('借阅成功!')
self.show_book()
# 还书
def send_book(self, book):
for booka in self.books:
if booka == book:
answer = input('查找到借过此书!是否确认归还?(yes/no)')
if answer == 'yes':
self.books.remove(book)
book.add_number()
print('归还成功!')
else:
print('不愿意还回去了,还书失败!')
break
else:
print('没有借过此书!')
# 查看书
def show_book(self):
print('{}所借的书如下:'.format(self.name))
if len(self.books) > 0:
for book in self.books:
print(book) #
else:
print('共借图书{}本'.format(len(self.books)))
else:
print('还没有借书!')
class Book:
def __init__(self, bname, author, price, publish):
self.bname = bname
self.author = author
self.price = price
self.number = 10
self.publish = publish
def reduce_book(self):
self.number -= 1
def add_number(self):
self.number += 1
def show(self):
print('书名:{},作者:{},价格:{},出版社:{},数量:{}'.format(self.bname,self.author, self.price, self.publish, self.number))
def __str__(self):
return self.bname
def __eq__(self, other):
if id(self) == id(other):
return True
else:
if self.bname == other.bname and self.author == other.author and self.price == other.price and self.publish == other.publish:
return True
else:
return False
# 创建对象
zq = Student('志强')
# 创建book对象
book1 = Book('斩龙1', '失落叶A', 23.9, '清华大学出版社')
book2 = Book('斩龙2', '失落叶B', 55.9, '南京大学出版社')
book3 = Book('斩龙3', '失落叶C', 21.9, '北京大学出版社')
book4 = Book('斩龙4', '失落叶D', 38.9, '东北大学出版社')
book5 = Book('斩龙4', '失落叶D', 38.9, '东北大学出版社')
zq.borrow_book(book1)
zq.borrow_book(book2)
zq.borrow_book(book4)
print('-------------------')
zq.send_book(book2)
zq.show_book()
print('--------------')
book1.show()
多态:
'''
java: 面向对象特点: 封装,继承,多态
python 面向对象的特点是: 封装,继承
多态:弱类型 假多态
issubclass(Cat,Animal): 第一个参数是子类,第二个参数是父类
返回值就是Cat是否是Animal的子类 True False
if issubclass(Cat,Animal):
print('yes')
else:
print('no')
'''
class Person:
def __init__(self, name):
self.name = name
def feed_pet(self, animal): # animal动物的统称 cat dog bird ...
if isinstance(animal, Cat) or isinstance(animal, Dog):
print('我养了一只宠物:', animal.type)
print('宠物名字是:', animal.name)
else:
print('养宠物要慎重!。。。是不是黄金狮呀!')
class Animal:
type = '动物'
def __init__(self, name):
self.name = name
def eat(self, food):
print(self.name + '正在吃东西:' + food)
class Cat(Animal):
type = '猫'
def catch_mouse(self):
print(self.name + '喜欢抓老鼠')
class Dog(Animal):
type = '狗'
def see_house(self):
print('看家专业户....')
class Tiger:
type = '老虎'
def eat_person(self):
print('---------->person over!!!')
# 创建对象
person = Person('小耕')
# 宠物
huahua = Cat('花花')
dahuang = Dog('大黄')
goldenlion = Tiger()
person.feed_pet(goldenlion)
# 限制对象动态添加的属性内容
__slots__ = ('name', 'age', 'gender')
模块
'''
模块:Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 语句,函数,类,对象。
包: 其实就是一个文件夹,存放多个模块
导入模块的方式:
1. import 模块名
2. from 模块名 import 函数,类,变量
from 模块名 import * ----> 代表的是该模块中所有内容
'''
__all__ = ['number', 'func', 'Person']
# 作用:就是限制*的使用。如果外界使用*导入只能访问到__all__里面指定的内容
模块:
1,__all__限制__init__.py 文件中对外访问内容限制**
在[]列表中的是对外界可以访问的,不再列表的就是不可以访问的。
2.__all__里面还可以添加模块名。
目的:如果在一个模块中,from包名 import
外界想要访问模块,模块名.函数() ————————》必须在all=[添加的模块名....]
__init__.py的作用
把某一个目录(文件夹)变成一个包,使得其他模块使用包.包名的某一块模块/函数/变量/类 这种方法时可用
__all__在该文件中指定*可以调用的模块
避免循环导入:
-
代码重构
-
将导入放到函数中
-
放在模块的最后(不推荐)
__name__ == '__main__' 判断外部调用(___name__=包名),还是自身调用
**导入时所搜的顺序:sys.path
异常:
异常即是一个事件,该时间在程序执行过程中发生,影响了程序的正常执行
一般情况下,在python无法正常处理程序时就会发生。
异常处理
1.try ...except
格式:
try:
**可能发生异常的代码
except:
**只有异常才会执行的代码块
2.try... except...except... 后面跟多个except
except 错误后应添加相应的错误类型
exception Value as err: 后面打印err错误类型
3.try... except...else...(异常处理的时候才会报else)
多个异常处理时将Excepion最大的方最后(默认先后顺序找错误的)
4.try... except...finally...
使用场景:无论有没有异常都会执行的代码
文件操作 打开文件 finally 往往释放文件的链接
数据操作 数据库连接
在else 与 finally 同时加return值 在末尾的可以覆盖之前的
try:
pass
except TypeError:
print()
except ValueError as err:
print(err)
except Exception as err:
print('except 最后一个是最大的')
else:
print('没有报错,执行此命令')
return result
finally:
print('无论有没有,都会执行此命令')
return result #在else 与 finally 同时加return值 在末尾的可以覆盖之前的
常用模块
math 数学模块
random 随机数模块
time 和 sys 模块
datetime: 日期时间模
类:
datetime 重点 now()
date 重点: today()
time 了解
timedelta 重点 设置时间差 + -
加密算法-hashlib
md5算法:单向**
str————》md5加密 十六进制 是32位**
sha1 算法 十六进制 是40位**
sha256 算法:单向 十六进制 是64位**
secret='123456'
sha1=hashlib.sha1(secret.encode('utf-8'))
print(sha1)
浅层和深层copy
拷贝
深拷贝
浅拷贝
python中对象三要素:
id (地址) type(类型) value(值)
浅层和深层copy
logging模块用于开发的程序查看保错信息
logging: 日志操作步骤:
1. 日志对象
2. 设置日志级别:
3.创建handler对象,用于文件的写入file_name = 'log.txt'
4. 定义写入文件格式
5. 将handler添加到logger中
文件的操作:
文件的读写
# 1. 通过open创建一个流对象
wstream = open('a1.txt', mode='w') # 写入文件一:
str1 = '志强传了妹子图片\n'
# 2. 将内容通过流对象写入
for i in range(10):
wstream.write(str1)
# 3. 关闭流
wstream.close()
# with open('a1.txt',mode='a') as wstream: # 写入文件二:
# str1 = '楷元下载了妹子图片1\n'
# for i in range(10):
# wstream.write(str1)
with open('a1.txt') as rstream: # 文件读取一:
# while True:
# line = rstream.readline()
# if not line:
# break
# print(line)
content = rstream.read()
print(content)
os模块
os.getcwd() 获取当前文件所在的目录,以绝对路径方式返回
os.mkdir() # 新建文件夹 如果文件存在则报错FileExistsError
os.rmdir() 删除空白的文件夹directory
os.listdir() 列出所有的文件到列表中
os.remove() 删除文件file
os.chdir(路径) 切换目录 类似cd 路径
os.path模块:
os.path.exists() 判断文件或者目录是否存在
os.path.join() 路径的连接
os.path.dirname(file) 获取当前文件所在的文件夹
os.path.isdir() 是否是文件夹
os.path.isfile() 是否是文件
os.path.split(path) 分割的是文件夹与文件名
os.path.splitext(path) 分割的是:(文件夹/文件名,扩展名)
csv
'''
csv: 类似一个excel表格
后期 数据阶段
读取
写入
'''
import csv
# 读取
def reader_csv():
with open(r'..\file\students.csv', mode='r') as rstream:
csv_reader = csv.reader(rstream)
# 每遍历一次则取到一行信息
for student in csv_reader:
print(student)
# 写入内容
def write_csv():
with open(r'..\file\students.csv', mode='a', newline='') as wstream:
writer_csv = csv.writer(wstream)
stu1 = ['zhangsan', '95']
# stu2 = ['yuanyuan', '98']
# stu3 = ['qiangqiang', '99']
writer_csv.writerow(stu1)
# writer_csv.writerow(stu2)
# writer_csv.writerow(stu3)
print('写入成功!')
if __name__ == '__main__':
write_csv()
# reader_csv()
# reader_csv()
序列化与反序列化
什么是序列化与反序列化 将对象转化为可通过网络传输或可以存储到本地磁盘的数据格式(如:xml,json或特定格式的字符串)的过程称为序列化
import json # 方法一:
print('----------序列化-----------')
dict1 = {'北京': {'海淀区': ['清河', '西二旗']}}
result = json.dumps(dict1, indent=1)
print(result)
print('----------反序列化-----------')
result1=json.loads(result)
print(result1)
import pickle # 方法二:
dict2={'001':'神话','002':'仙剑'}
s=pickle.dumps(dict2)
print(s)
s=pickle.loads(s)
print(s)
正则表达式
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex,regexp或RE),计算机科学的一个概念,正则表达式通常用来检索,替换那些符合某个模式(规则)的文本。
python 也有正则表达式:
re 模块
函数:
compile
search : 全局扫描字符串搜索匹配内容,如果有匹配的内容则会终止,没有匹配成功则返回None
match : match(正则表达式,要校验字符串) 有匹配的则返回match对象,没有则返回None
match特点就是从头开始匹配的,头没有匹配成功则返回None
split : 按照正则表达式分割字符串。返回一个列表
findall : 查找字符串中所有符合正则表达式的内容,将符合的内容保存到列表中 像: ['k8l', 'p6p']
finditer
sub : 替换
subn :返回替换的个数
'''
import re
# # 1. 得到‘公式’pattern
# pattern = re.compile('abc')
# # 2. 使用公式对象匹配要校验的字符串 match 匹配,返回一个匹配对象match对象
# match_obj = pattern.match('abcdef')
# print(match_obj)
#
# print(match_obj.group()) # 获取匹配的内容
#
# print(match_obj.span()) # 匹配内容的位置 (0,3)
r = re.match('abc', 'helabclo')
print(r)
r = re.search('abc', 'helabclo')
print(r)
# r 是match对象: group() 匹配的内容 span() 匹配内容在字符串的位置
print(r.group())
print(r.span())
# a3b 查找字符串中是否存在左右是字母中间数字 x1y f7u
s = 'hjK8loP6p'
# [] 表示的是一个范围 [abck] [a-z] [0-9]
# .表示任意字符
m = re.search('[a-z][0-9][a-z]', s, re.I)
print(m)
m = re.findall('[a-z][0-9][a-z]', s, re.I) # 忽略大小写匹配字符
print(m)
# z123b z156b s989b
s = 'h88ex890loK123Jldkl90gd3o'
m = re.findall('[a-z][0-9]*[a-z]', s, re.I)
print(m)
m = re.findall('[a-z][0-9]{3}[a-z]', s, re.I)
print(m)
# * + ?
'''
* : >=0
+ : >=1
? : 0 或者 1
{n}: 具体的个数n
{n,}: >=n
{n,m}: m到n之间的个数
'''
'''
\d 同 [0-9] 表示纯数字 digit
\D 非数字 同[^0-9]
\w 同[a-zA-Z0-9_] 字母数字下划线 word
\W 非字母数字下划线 同[^a-zA-Z0-9_]
\s 空格 space 类似 [ \t\n\r\f\v]
\S 非空格
'''
# 验证qq号码 5位到11位之间 不能0开头 全部是数字
qq = '734873984'
m = re.search('^[1-9]\d{4,10}$', qq)
print(m.group())
# 验证用户名 字母数字下划线 首字母不能是数字 长度必须6位以上
username = 'admin123'
m = re.match('[a-zA-Z_]\w{5,}$', username)
print(m.group())
s = 'ab cd#jkdf8jdf**dfj0kl'
m = re.search('[a-z]\s+[a-z]', s)
print(m.group())
print('-------------------------------------->')
m = re.split('[\s#\d*]+', s)
print(m)
# 电话号码: 13/8/5/9XXXXXX 11位
phone = '15989015634'
m = re.search('^1[3589]\d{9}$', phone)
print(m.group())
# 8到20位的密码,可以是大小写英文字母、数字、下划线
m = '123KLkl_123'
s = re.search('^\w{8,20}$', m)
print(s.group())
# 匹配出163的邮箱地址,且@符号之前有4到20位字符,例如hello@163.com
email = 'louzm_@163.com'
m = re.search('^.{4,20}@163.com$', email)
print(m.group())
分组与命名匹配
s = 'hello tom!'
m = re.search('(abc|xyz|tom)', s)
print(m.group())
# 匹配出163,126,qq,sina的邮箱地址,且@符号之前有4到20位字符,例如hello@163.com
email = 'louzm_@sina.com'
m = re.search('^.{4,20}@(163|126|qq|sina).(com|net|cn)$', email)
print(m.group())
print(m.group(1)) # 捕获第一组中匹配的内容
print(m.group(2))
s = '<div>hello beauty</div>'
m = re.match(r'<(.+)>.+</\1>$', s)
print(m.group())
print(m.group(1))
# 使用带命名的方式匹配?P<名字>
m1 = '<div><a href="sdf">历史上的今天</a></div>'
m = re.match(r'<(?P<name1>\w+)><(?P<name2>\w+) href="sdf">(.+)</(?P=name2)></(?P=name1)>$', m1)
print(m.group())
print(m.group(1))
print(m.group(2))
print(m.group(3))
sub:替换
s = '白鑫宇喜欢苍老师'
m = re.sub(r'(苍井空|苍老师|白鑫宇)', '***', s)
print(m)
# 支持函数使用其中temp就是一个match对象
def add(temp):
print(temp)
score = temp.group() # 获取匹配的内容
score = int(score) + 1
return str(score)
m = re.sub(r'\d+', add, msg)
print('---->', m)
多任务
编程处理多任务,如何实现?多任务操作系统使用某种任务调度策略允许两个或更多进程并发共享一个处理器时,事实上处理器在某一时刻只会给一件任务提供服务。因为任务调度机制保证不同任务之间的切换速度十分迅速,因此给人多个任务同时运行的错觉。多任务系统中有3个功能单位:任务、进程和线程;
import os
import time
from multiprocessing import Process
'''
os.getpid() : 获取当前进程编号
os.getppid() parent process id
总结:进程
1.如何创建进程?
Process(target=任务函数名, name= 进程名字 ,args=函数的参数,kwargs=关键字参数)
Process(target=weichat, kwargs={'name':'小芳'})
2.进程方法:
p1.start() 开启进程
p1.join() p1进程插队
p1.run() 只要启动进程,默认就会调用run()可以重写该方法
p1.terminate() 终止进程p1
p1.is_alive() 判断p1进程是否活着
'''
def study():
for i in range(5):
print('欣东很爱学习:', i, os.getpid(), os.getppid())
time.sleep(0.2) ------>实现任务切换进行
def listen_music():
musics = ['大海', '只因你太美', '麻婆豆腐', '大碗宽面']
for i in musics:
print('欣东喜欢听:', i, os.getpid(), os.getppid())
time.sleep(0.2)
def weichat(name):
for i in range(5):
print('欣东跟{}聊第{}句,当前进程:{},父进程:{}'.format(name, i, os.getpid(), os.getppid()))
time.sleep(0.2)
# 创建多个进程
if __name__ == '__main__':
print('主进程编号:', os.getpid())
# 1. 创建了多个进程对象
p1 = Process(target=study, name='学习')
p2 = Process(target=listen_music, name='听歌')
p3 = Process(target=weichat, name='聊天', args=('小芳',))
start = time.time()
# 2. 启动进程
p1.start()
p2.start()
p3.start()
# 子进程插队: 让主进程让步
p1.join()
p2.join()
p3.join()
end = time.time()
print('主进程创建了三个子进程,名字是:', p1.name, p2.name, p3.name)
print('用时:', (end - start))
'''
进程锁:
进程锁:为了解决多个进程同时访问同一资源产生的冲突,这时候我们使用进程锁来进行解决,
在使用进程锁的时候,需要将进程锁作为参数传递到该进程。
'''
import time
from multiprocessing import Process, Lock,current_process
import json
# 查看票
def search():
flag = False
with open(r'file\tickets.txt', 'r') as rstream:
dict1 = json.load(rstream)
print('当前剩余的票数是:', dict1['number'])
if dict1['number'] > 0:
flag = True
return flag
# def write1():
# with open(r'file\tickets.txt', 'w') as wstream:
# dict1 = {'number': 9}
# json.dump(dict1,wstream)
# print(dict1)
# print('保存成功!')
# 抢票
def get_ticket():
with open(r'file\tickets.txt', 'r') as rstream:
dict1 = json.load(rstream)
# 获取数据库中票数
count = dict1['number']
time.sleep(0.5)
if count>0:
count -= 1
time.sleep(0.2)
# 修改数据
dict1['number'] = count
with open(r'file\tickets.txt', 'w') as wstream:
json.dump(dict1, wstream)
print(current_process().name+'购票成功!')
else:
print(current_process().name + ',票已经售空!请查看其他车次!')
# 任务
def task(lock):
f = search()
# 如果有票则抢票
if f:
# 加锁
lock.acquire() # 阻塞等待
# 抢票
get_ticket()
# 释放锁
lock.release()
else:
print(current_process().name+',票已经售空!请查看其他车次!')
if __name__ == '__main__':
# 创建一把锁
lock = Lock()
# 模拟有10个售票窗口抢票
for i in range(1, 11):
# 创建进程
p = Process(target=task, name='售票窗口'+str(i),args=(lock,))
p.start()
'''
信号量:限制同一时间执行的进程的个数。
志强,养生馆: spa
4张床
'''
import random
import time
from multiprocessing import Process, Semaphore
def goto_spa(name, semaphore):
print('{}进入养生馆'.format(name))
# 看信号灯
semaphore.acquire()
print('{}占了一张床!'.format(name))
time.sleep(random.randint(1, 3))
print('{}spa完成!'.format(name))
semaphore.release()
if __name__ == '__main__':
# 定义一个信号量对象
semaphore = Semaphore(4)
names = ['志强', '楷元', '欣东', '小芳', '国俊']
for name in names:
p = Process(target=goto_spa, name=name, args=(name, semaphore))
p.start()
垃圾回收机制 当Python中某个对象的引用计数变成0,说明没有任何的引用了,则垃圾回收机制开始回收此空间。
并发和并行
并行和并发:
并行:多个任务同时运行,只有具备多个cpu才能实现并行,含有几个cpu,也就意味着在同一时刻可以执行几个任务。
并发:是伪并行,即看起来是同时运行的,实际上是单个CPU在多道程序之间来回的进行切换。
同步与异步:
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去。
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进行处理,这样可以提高执行的效率。
打电话的过程就是同步通信,发短信时就是异步通信。
线程
# 在python当中,在同一时刻,一个进程当中只能有一个线程处于运行状态。
import os
import time
import threading
def saySorry(name):
print('hello%s'%name,'当前线程id:',os.getpid())
time.sleep(1)
if __name__ == '__main__':
ks=time.time()
print('开始执行程序:%d'%(ks),"当前进程id:",os.getpid())
for i in range(5):
t=threading.Thread(target=saySorry,args=('李强',))
t.start() # 启动线程,即让线程开始执行
print('程序结束:%d'%(time.time()-ks))
本文地址:https://blog.csdn.net/zx1213144536/article/details/107322021