python介绍
- python是面向对象的解释性计算机程序设计语言,胶水语言 需要解释器(翻译)成机器语言 1991年公开发行第一版,1989年由guido van rossum开发,作为ABC语言的继承 guido是monty python喜剧团体的爱好者,所以将这个语言命名python 2000年发布2.0,2008发布3.0,2020年开始不再更新2.0
python特点
1、运行速度较慢(编译型语言-解释性语言),差别在毫秒级
2、代码不能加密,已源码发布
3、强制缩进
4、GIL全局解释器锁:在任意时刻,只有一个运行在解释器中运行,对python虚拟机的访问由全局解释器锁GIL来控制,这个锁保证同一时刻只有一个线程在运行。python多线程不是真正多线程。但因为CPU效率较高,人感受不到区别。
python可以做什么
1、WEB:Flask、django、tornado
2、爬虫开发:scrapy、urllib、requests、beautifulsoup、selenium
3、数据分析BI:pandas、numpy、matplotlib、pyplot、scipy、seaborn
4、机器学习:scikit-learn、tensorflow、keras、opencv
5、运维开发:
6、人工智能
- python开发IDE 1、notepad++ 、sublime、pycharm
python变量和常量
- 取名规则,大小驼峰法、见名知意 import keyword keyword.keywordlist # 查看系统的关键字不能作为变量名
数据类型、数据结构
基本数据类型:int、float、bool
高级数据类型,数据结构:字符串、列表、元组、字典、集合
- 序列是一组按顺序排列的数据集合 python内置序列类型:字符串、列表、元组 序列支持索引和切片操作 abs()函数,求绝对值;ord()函数,返回ASCII码值;chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象),ASCII码转字符;id()函数,查看内存地址;join()函数,字符串函数,用字符连接字符串的每个元素;swapcase()字符串函数,转换所有字母的大小写; 公用方法:in + * not in 通用方法len()、shuffle()、del()、sorted a.isdigt() 判断a是否是整数
list列表:
- 是有序的数据集合,支持增删改查,数据可变,内存地址不变。数据项可以是任何类型的数据,比如:列表、元组、字典、字符、数字、字符串等。 常用方法:append、count、extend、index、insert、pop、remove、reverse、sort、keys、values 列表推导式 # 列表推导式 lst = [x**2 for x in range(1,5) if x%2==0] # [4,9] lst = [x**2 if x%2==0 else 0 for x in range(1,5)] # 有else,if放的位置不一样 # [0, 4, 0, 16]
tuple元组
- 是不可变的序列,不能做任何修改,只有一个元素要加逗号,不能对元组元素进行赋值操作,可以对元组中的列表元素进行修改。创建元组可以不加括号 a = 10,20,30。 zip()函数合并多个列表,元祖,返回一个zip对象,zip对象可以转换成字典、列表。 列表推导式同样适用于元组,生成一个生成器,可以转换成元组、列表。 生成器只能访问一次。
dict字典
- 键值对,通过键访问效率高(类似索引),支持增删改查,没有下标概念(不是序列类型),键不可变不重复,值可以重复可以是任意类型。 dict.keys() dict.items() dict.values() dict.update()修改添加键值对 dict.add()。可以嵌套 dict.sort_values()按值排序 dict.sort_keys() 按键排序 sorted(dcit.items() , key=‘a’) 按键a排序。 sorted()函数也可以对元祖进行排序,排序后返回的是列表 a = dict.fromkeys([‘name’,‘age’,‘gender’]),通过fromkeys创建一个空字典 popitem() 随机移除一个键值对
set集合
- set集合是无序不重复元素序列 set.add() 添加元素 set.clear()清空集合 set1.defference(set2)求差集 同 set1-set2 set1.intersection(set2)求交集 ,取相同元素,同set1&set2 set1.union(set2)求并集 ,同set1 | set2 set1.pop()删除元素 ,返回删除的元素 set1.discard(3) 指定移除3 set1.update(4) 插入4,set1.update(set2) 集合不支持索引和切片,类似字典,只有key没有value
格式化输出
- 格式化输出,%占位符,后面跟变量类型,%s %d %f %i %c: print(‘我的名字是%s’ % ( name )) format方式: print(‘我的名字是{1}年龄是{0}’.format(age, name )) 前面可以设定变量值提取的顺序 格式化字符串 u:表示unicode,以unicode编码chucun,能够储存中文。python3中默认以unicode编码储存字符串 b:以Ascll码形式储存字符串,无法储存中文 r:表示raw string,不识别转义 f:表示format,用来格式化字符串
流程控制
1、顺序流程:默认从上到下执行代码
2、选择流程 判断语句:if … elif … else
3、循环流程、循环语句:for、while、continue、break,一定要有结束条件,不然会陷入死循环
4、流程控制:pass、函数中return的使用
运算符
- :+ - * / // ** % = : -= += /= **= *= & | or and not ~ == != > < <= >= >> << 三目运算符 #三目运算 #格式是 : 表达式?真:假 不存在这种 result = (8>10) ? 正确 : 错误 print(result) # 真的结果 if 表达式 else 假的结果 a=5 b=6 print = (a+b) if a>b else (a-b) # 结果为后面那个,假的结果-1 运算符重载: + 实际上是类方法 __add__() 可以在类里面重新定义__add__()
函数基础
1、函数的定义,命名规则
2、函数的参数:传参、调用、缺省参数(参数默认值)、*args 、kwargs、函数中所有的参数,不管是字典型还是字符串型等可变与不可变型的数据结构,都是属于*args;但是如果是这种key=value键值对的形式传入的参数,那么这种参数就属于kwargs。
3、参数arg、*args可变参数(元组、列表)、**kwargs(课表关键字参数字典)三个参数的位置必须是一定的
4、*kwargs在调用的时候,参数前面要加 *
def stuinfo(**kwargs): print(kwargs) # 打印字典 print(*kwargs) # 打印key for i,v in kwargs.items(): # 遍历键值 print(i,v) dictA= { name:marvin,age:30} if __name__ == __main__: stuinfo(**dictA) # 传参
5、列表推导式
list1 = [1,2,3,4,5,6,7,8,9] list2 = [ list1[i] for i in range(len(list1)) if i%2==0] # 返回list1偶数位的元素 list2 = list1[0::2]
6、函数返回值return,执行了return函数体就执行完毕退出
7、变量作用域:全局变量、局部变量、global
8、python中万物皆对象
匿名函数lambda
1、(lambda x,y : x if x>y else y)(12 ,2 ) # 后面跟参数可以直接调用
2、g = lambda x,y : x*y # 一般定义方式
g(12,2) # 调用方式
生成器
# 生成器 def func(): n = 0 while True: n += 1 yield n # return n 并 暂停 g = func() print(next(g)) # print(g.__next__()) #1 print(next(g)) # print(g.__next__()) #2 print(next(g)) # print(g.__next__()) #3 # 练习,打印斐波拉契数列 def fib(length): n = 0 a, b = 0, 1 print(0) while n < length - 1: # 第一个元素0已经打印 print(b) a, b = b, a + b n += 1 length = int(input(输入需要的个数:)) fib(length) # 练习,使用生成器,打印斐波拉契数列,和报错信息 def fib(length): n = 0 a, b = 0, 1 print(0) # 打印第一个元素 while n < length - 1: yield b a, b = b, a + b n += 1 return 没有更多了 # 输出结果完了以后,就输出这个错误 length = int(input(输入需要的个数:)) print(next(fib(length))) # 调用一次输出一个
递归函数
1、调用自己本身的函数,一般来说实现循环,必须有结束条件
2、递归方式实现阶乘:
def jiecheng(n): if n > 1: return n * jiecheng(n-1) else: return n if __name__ == __main__: print(jiecheng(6))
3、递归的执行逻辑是:带入第一个参数不返回值,直到带入最后一个参数才开始返回值,然后依次倒退返回倒数第2个参数的返回值。
内置函数
1、数学函数:round() eval() abs() pow() sqrt()
2、类型转换函数:int() hex() oct() bin() # 进制转换 bytes() # 字符转换成字节码 str() list() bool() # 数据类型转换 ord() char() # ASCII码和字符转换
3、
print(bytes("我爱你",encoding=utf-8)) # 输出 bxe6x88x91xe7x88xb1xe4xbdxa0
4、序列操作函数:
all() # 判断可迭代参数是否每个元素都为true,相当于每个元素进行and操作,列表有一个空元素也为True
any() # 判断可迭代参数是否有任一个为True,相当于每个元素进行or操作
sorted() # 可迭代参数进行排序,默认升序,与sort的区别是,sorted生成新的序列
reverse() # 可迭代参数进行转置(逆向)
range() # 创建一个整数列表,(start , stop ,step)
zip() # 将参数中对应的元素组合打包成一个元组,参数可以是1个及以上的序列
enumerate() # 参数是可迭代对象,返回对象的下标和值。enumerate(sequence, [start=0]),sequence – 一个序列、迭代器或其他支持迭代对象。start – 下标起始位置。主要目的是给对象加索引。
seasons = [Spring, Summer, Fall, Winter] print(list(enumerate(seasons))) # 输出:[(0, Spring), (1, Summer), (2, Fall), (3, Winter)]
- 列表推导式list3 = [i for i in list1 if i%==0 ]
面向对象
类、父类、子类
1、面向对象OOP类似老板看到的层面:比如 老板出差是一个对象,老板只需要提供时间、目的地,秘书和财务具体去买票、订酒店、定饭店等。
3、类是一个模板,一个种类。对象是类的一个实例。类是图纸,对象是根据图纸做出来的一个个实物。
4、示例:
# 定义一个人的类 class Person: def __init__(self,name,age): self.name = name self.age = age print(name+"今年",age,"岁") def eat(self,food): print(self.name+"在吃"+food) if __name__ == __main__: xiaoming = Person(小明,20) xiaoming.eat("米饭")
继承:单继承、多继承
1、多继承的类中如果有同名方法,遵循广度优先查找
2、间接继承:son继承father,father继承grandfather,则son也能继承grandfather
3、所有的类默认都继承object基类
4、isinstance(m,man) 返回m是否继承于man
重写父类的方法
1、在子类中定义与父类同名的方法,则可以重写父类的方法
2、__init__()重写时,如果是在父类基础上增加功能,则,先调用父类的init函数,再写自己的功能
__new__()方法在__init__()方法之前执行
3、__mro__():
python 类有多继承特性,如果继承关系太复杂,很难看出会先调用那个属性或方法。
为了方便且快速地看清继承关系和顺序,可以用__mro__方法来获取这个类的调用顺序
4、__str__():
当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
str’方法需要返回一个字符串,当做这个对象的描写
5、super().func() :调用父类的方法
多态
1、发生在继承时
2、子类要去重写父类的方法
3、多态的好处,通过obj抽象对象,统一调用多态的函数
4、所谓多态就是定义时和执行时不一样
- 类属性和实例对象的属性 1、类可以访问类属性 2、实例对象可以访问类属性和自己的实例属性 3、可以通过对象修改对象属性,通过类名修改类属性 class Person(object): def __init__(self,name,sex): self.name = name self.sex = sex class Child(Person): # Child 继承 Person def __init__(self,name,sex,mother,father): Person.__init__(self,name,sex) # 子类对父类的构造方法的调用,可以减少代码冗余 self.mother = mother self.father = father May = Child("May","female","April","June") print(May.name,May.sex,May.mother,May.father)
类方法
1、类方法在类中定义,类似类属性,可以被类和实例调用,第一个参数必须是类本身cls
2、定义方式
@classmethod # 这是一个类方法的装饰器
def class_func(cls):
pass
3、与普通方法的区别:普通方法需要类的实例去调用,不能用类名直接调用
4、在类方法中可以修改类属性的值
静态方法
1、声明@staticmethod
2、一般不通过实例对象访问静态方法,减少类对象的实例化操作,减少计算资源的浪费,但是实例也可以访问
3、用于存放逻辑性代码,不涉及到类属性和方法的操作
4、比如,访问系统时间
5、使用的时候直接用类名调用,不需要参数
time.strftime("%H:%M%S",time.localtime())
6、普通的没有装饰器的函数,只能通过实例化的对象来访问
7、普通方法第一个参数是实例本身self
私有化属性
1、把类的属性隐藏起来,类的外部不能直接访问,在类的内部可以访问,可用于作为类方法的参数
2、也不能被子类继承
3、在类的内部可以修改私有化属性
class Person: def __init__(self,name,age,nation): self.name = name self.age = age self.__nation = 中国 # 私有化属性 lisi = Person(lisi,30,日本) print(lisi.name,lisi.age) # print(lisi.__nation) 不能访问
私有化方法
1、概念与私有化方法类似
2、定义
class Person: def __read(self,book_name): # 私有化方法 print(正在读,book_name) def acta(self): self.__read(青年志) # 内部可调用 xiaoli = Person() # xiaoli.__read(百年孤独) # 实例无法调用该方法 # xiaoli.acta()
类属性
1、通过类属性函数property()访问不能访问的私有属性
class Person: def __init__(self): self.__age = 18 def get_age(self): return self.__age def set_age(self,age): self.__age = age age = property(get_age,set_age) xiaoli = Person() # xiaoli.__read(百年孤独) # 实例无法调用该方法 print(xiaoli.age) xiaoli.age= 20 print(xiaoli.age)
2、可以通过装饰器实现上面的功能
魔术方法_str_
1、只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
2、__str__方法需要返回一个字符串,当做这个对象的描写
3、直接打印实例对象时,就会输出__str__()返回的字符串
4、dir(类) 显示类拥有的方法和属性
5、__new__() 实例化前执行的方法
析构方法
- 当对象被删除时,自动调用_del_()方法,析构方法 class Animal: def __init__(self,name): print("这是初始化方法,我有一只小猫叫{}".format(name)) def __del__(): print("这是析构方法") cat=Animal("小花") 这是初始化方法,我有一只小猫叫小花 这是析构方法
类对象的赋值操作,深拷贝,浅拷贝
class CPU: pass class Disk: pass class Computer: def __init__(self,cpu,disk): self.cpu = cpu self.disk = disk cpu1 = CPU() cpu2 = cpu1 print(cpu1:,id(cpu1)) print(cpu2:,id(cpu2)) # cpu2的id与cpu1相同,两个不同的变量,指向同一个内存空间 disk = Disk() print(------------) computer1 = Computer(cpu1,disk) import copy # 浅拷贝 computer2 = copy.copy(computer1) # 浅拷贝,只拷贝computer类对象 print(computer1:,id(computer1)) print(computer2:,id(computer2)) # computer2的内存地址与computer1 不同,但是,所包含的cpu,disk属性的id一致 print(computer1.cpu:,id(computer1.cpu)) print(computer2.cpu:,id(computer2.cpu)) # 与上面的一致 print(------------) # 深拷贝 computer3 = copy.deepcopy(computer1) # 深拷贝computer类对象,以及它的子对象cpu,disk print(computer1:,id(computer1)) print(computer3:,id(computer3)) # computer3的内存地址与computer1 不同,所包含的cpu,disk属性的id也不同 print(computer1.cpu:,id(computer1.cpu)) print(computer3.cpu:,id(computer3.cpu)) # 与上面的不同
组合,类似继承
# 继承 class A1: def say_a1(self): print("a1a1a1") class B1(A1): # B1继承A1 pass b1 = B1() b1.say_a1() # 打印 a1a1a1 # 组合 class A2: def say_a2(self): print("a2a2a2") class B2: def __init__(self,a): # a 是类B2的一个属性,这个属性可以是一个类 self.a = a b2 = B2(A2()) # 把A2实例化的对象座位B2的一个属性,传给B2 b2.a.say_a2() # 通过b2的属性a(即A2的实例化对象),再调用A2实例化对象的say_a2方法,打印 a2a2a2
以主程序方式运行
if __name__ == __main__: pass # 只有直接运行本文件,才会执行的代码
包-模块-代码
1、import能导入包 和 模块
2、使用from 时,可以从包 和 模块中导入 函数、变量、类
编码格式
1、ASCII,ISO8859-1,UNICODE,utf-8,gk2312,gbk,gb18030
2、python文件的默认编码是utf-8,最前面加 # encoding = GBK 可以修改文件编码
3、txt保存成utf-8,一个汉字4个字节,ANSI 一个汉字2个字节
进制和转换
#位运算 #bin()转二进制的函数 a=100 print(bin(a)) # 0b1100100 b=0b1100100 print(int(b)) # 100 c=-2 print(bin(c)) # -0b10 # 0o八进制 一位八进制转3位二进制,0x十六进制 d=0o635742 print(int(d)) #八进制转十进制 e=0x9ff9d print(int(e)) #十六进制转十进制 & 与 | 或 ~ 非 << 左移 >> 右移 ^ 异或 print(8>>1) #8转成二进制,然后逐位右移1位,左边第一位补0 print(5 & 3) #5和3转成二进制,补齐8位即1byte,逐位进行与计算,1&1=1,其余为0,得出新的二进制,并转成十进制输出 print(8^6) # 转成二进制对齐,逐位进行异或运算,即相同为0,不同为1
文件读写
1、文件读写俗称IO
2、open(filepath,mode), mode=r读取从开头,w写没有就创建,a没有就创建追加内容,rb、 wb二进制,a+,r+,w+读写
3、常用方法,使用方法 filestrem.funciont() 文件流调用
- read([size]) 读取size大小的内容,不写就读完 readlines() 读全部内容,分行放入列表 ,readline() 读一行 write(str) writelines(s_list) seek(offset[,whence]) 从第offset字节开始读 tell() 返回文件指针当前的位置 flush() 把缓冲区的内容写入文件,但不关闭文件,flush之后可以继续操作 close() close之后不能再操作文件
4、with open(filepath,mode) as filestrem 可以不用手动关闭,里面有两个函数__enter__()和__exit__(),在文件打开和关闭的时候自动执行
5、内置OS模块
- os.system(‘notepad.exe’) 相当于开始,运行 os.startfile(filepath) 执行某个程序文件 getcwd() 返回当前目录 chdir(path) 更换目录到path listdir(path) 返回path下的文件和文件夹 walk(path) 遍历路径下所有文件和文件夹,逐层遍历 import os path = os.getcwd() lst_files = os.walk(path) # 返回path下的所有文件夹,文件 for dirpath,dirname,filename in lst_files: # 分层遍历 print(dirpath) # 当前路径 print(dirname) # 路径下的目录 print(filename) # 目录下的文件 mkdir(path) 创建目录 makedirs(path1/path2) 创建多级目录 rmdir(path) 删除目录 removedirs(path1/path2) 删除多级目录
6、os.path模块
- abspath(file) 获取文件或目录的绝对路径 exists(path) 判断文件或目录是否存在 join(path,name) 将 split(path) 分离文件名和路径 splitext() 分离文件名和扩展名 basename(path) 从目中提取文件名 dirname(path) 从路径中提取文件路径,不含文件名 isdir(path) 判断是否为目录
正则表达式
异常处理
try…except…基本的异常处理结构
# try..except..基本的异常处理结构 try: pass # 可能出现错误的代码块,出错位置以下的代码不执行。出错前的代码照常执行 except Exception as e: # 捕获异常,exception是包含大部分异常,BaseException包含所有异常 print(e) # 打印异常提示信息,可以对e进行分类,打印出更准确的异常提示信息
try…except…except…异常处理结构
# 异常处理结构 try: pass # 可能出现错误的代码块,出错位置以下的代码不执行。出错前的代码照常执行 except 异常类型1: print("提示信息1") except 异常类型2: print("提示信息2") except BaseException: # 兜底,其他所有异常情况 print("提示信息") # 笼统的提示信息
try…except…else…异常处理结构
# try..except..else..异常处理结构 try: pass # 可能出现错误的代码块,出错位置以下的代码不执行。出错前的代码照常执行 except Exception as e: # 捕获异常,exception是包含大部分异常,BaseException包含所有异常 print(e) # 打印异常提示信息,可以对e进行分类,打印出更准确的异常提示信息 else: pass # 没有异常时继续执行这里的代码块
try…except…else…finally…异常处理结构
# try..except..else..finally..异常处理结构 try: pass # 可能出现错误的代码块,出错位置以下的代码不执行。出错前的代码照常执行 except Exception as e: # 捕获异常,exception是包含大部分异常,BaseException包含所有异常 print(e) # 打印异常提示信息,可以对e进行分类,打印出更准确的异常提示信息 else: pass # 没有异常时继续执行这里的代码块 finally: pass # 无论有没有异常,都要执行这里的代码块
traceback使用模块输出错误信息到文件
import traceback try: print("执行在前面的代码") m = 1/0 except: with open("d:/error.txt",a) as f: traceback.print_exc(file=f) # 将错误信息输出到文件
自定义异常类
class AgeError(Exception): # 继承自exception异常类 def __init__(self,errorinfo): Exception.__init__(self) self.errorinfo = errorinfo def __str__(self): return str(self.errorinfo) + "年龄错误,应该在1-150之间" if __name__ == "__main__": age = int(input("请输入年龄:")) if age<1 or age>150: raise AgeError(age) # 抛出自定义异常 else: print("输入的年龄是:",age)
with上下文管理
1、与try…except…对比
2、方便文件管理和通信管理
3、with open(filepath) as f:
软件设计模式
单例模式
class SingleCase(object): __instance = None # 定义一个私有化属性,用来保存实例对象 def __init__(self,name,age): print(name,age) def __new__(cls,*args,**kwargs): # 如果类属性__instance的值为none,那么新建一个对象 # 如果雷属性__instance的值不为none,则返回__instance保存的对象 if not cls.__instance: cls.__instance = supre(SingleCase,cls).__new__(cls) # 调用父类__new__()方法生成一个实例对象 return cls.__instance else: return cls.__instance obj1 = SingleCase("小明",18) obj2 = SingleCase("小花",28) print(id(obj1)) print(id(obj2)) # 如果两个id相同则是同一个对象,打印的内容也是一样的
工厂模式
class carFactory: def create_car(self,brand): if brand == 奔驰: return Benz() elif brand == 宝马: return BMW() elif brand == 本田: return Honda() else: print("未知品牌,无法生产") class Benz: def __new__(self): print("生产一辆奔驰车") class BMW: def __new__(self): print("生产一辆宝马车") class Honda: def __new__(self): print("生产一辆本田车") factory = carFactory() car1 = factory.create_car("奔驰") car2 = factory.create_car("本田")
hashlib加密算法
# hashlib 库,加密算方法 import hashlib print(hashlib.md5("abc".encode(utf-8)).hexdigest()) # 900150983cd24fb0d6963f7d28e17f72