俗话说:“工欲善其事,必先利其器”,做好一件事,准备工作是非常重要的,一门编程语言的学习,重要的当然是基础
,基础就需要学习该门语言特有的语法
和特性
。
Python这门语言真的很简洁
,很酷
,简洁到实现一个功能或判断仅需一句话。
举例:
# 判断是奇数还是偶数
is_odd = lambda num:True if num % 2 == 0 else False
# 调用测试一下
is_odd(1) # False 奇数
is_odd(2) # True 偶数
# 快速创建二维数组列表
my_list = [[x,y]for x in range(1,3) for y in range(1,3)]
# 调用测试一下
print(my_list) # [[1, 1], [1, 2], [2, 1], [2, 2]]
# 获取重复列表里大于2的值
my_list = [1,1,2,2,3,3,4,4,5,6,7,7]
my_set = set(n for n in my_list if n > 2)
# 调用测试一下
print(my_set) # {3, 4, 5, 6, 7}
其实还有很多很多的例子,后续会有讲到。
我会按照下面的章节逐一讲解python:
- 1.快速安装python及pycharm编辑器
- 2.基本知识点及逻辑判断
- 3.数据类型:列表、元组、字典、集合
- 4.特性知识点:切片、拆包、可变类型和不可变类型、复制和继承、列表生成式
- 5.各类函数及装饰器
- 6.模块、包的导入和导出
- 7.文件IO的操作
- 8.面向对象、类和对象、封装、继承、多态、异常
- 9.单例模式、迭代器和生成器
- 10.序列化和反序列化、线程和进程、消息队列
1.快速安装python及pycharm编辑器
1.安装python最新版
# 第一步:安装Homebrew,打开终端,输入安装
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
# 第二步:安装python3
brew install python3
# 第三步:设置默认Python为3.7版本的
# 找到bash_profile配置,没有就新建
vim /Users/YourMacUserName/.bash_profile
# 添加以下代码
alias python='python3'
alias pip='pip3'
# 更新配置
source .bash_profile
这样操作后在终端输入,pip或python命令时都是默认调用python3.7的而非Mac自带的python2.7版本。
2.安装pycharm编辑器
# 第一步:去官网下载pycharm
# 地址:http://www.jetbrains.com/pycharm/download/#section=mac
# 第二步:去百度找注册码激活,完成安装
建议下载的时候选择pycharm的专业版Professional,功能更强大。
万事俱备只欠东风,下一步当然会详细介绍python这门语言的语法和知识点,尽管枯燥,熬过去就算入门
,相信自己。
2.基本知识点及逻辑判断
1.基本知识点
# 1.变量的介绍
a = 1
a = 'ww'
a = 3.14
a = True
# type(a) 查看数据类型
# 常用数据类型:int、str、float,bool、list、tuple、dict、set
# 2.变量名的命名规则
# 由字母、数字、下划线组成,不能以数字开头
# 小驼峰:
myName = 'ww'
# 大驼峰:
MyName = 'ww'
# 下划线:
my_name = 'ww' # (推荐)
# 3.公共运算符
# + 拼接列表,元祖,字符串
# * 复制列表,元祖,字符串
a = [1, 2]
b = [3, 4]
c = a + b # [1, 2, 3, 4]
d = a*2 # [1, 2, 1, 2]
# 4.关键字
# 具有特殊功能的关键字,不能作为函数名和变量名
'''
变量名:
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
'''
import keyword
kw = keyword.kwlist
print(kw)
# 5.注释
# 单行注释
'''
多行注释
'''
# 快捷键:command + /
# 6.数据类型的转换
# str 转 int
int(str)
# str 转 float
float(str)
# int 转 str
str(int)
int + float = float
# 7.输入和输出
# print默认会换行
print('ww')
a = 'hello'
b = 'world'
print(a, b) # hello world
print(a, b, sep=",") # hello,world
# 8.global的使用
global表示内存地址发生改变
num = 1
def show():
global num
num = 2
show()
print(num)
my_list = [1,2]
def show():
my_list.append(3)
show()
print(my_list)
2.逻辑判断
# 1.条件语句的应用
score = int(input('请输入您的分数:'))
if score >= 90 and score <= 100:
print('优秀')
elif score >= 70 and score < 90:
print('良好')
elif score >= 60 and score < 70:
print('及格')
else:
print('不及格')
# 2.循环语句
# 0=False, 0非=Ture
num = 5
while num <=5:
num += 1
print('hello word')
# for循环 结合range
# range
for value in range(5):
print(value)
# (1,6)
for value in range(1, 6):
print(value)
# 步长2
for value in range(1, 6, 2):
print(value)
# for和while可以结合else使用
num = 5
while num <=5:
num += 1
print('hello word')
else:
print('循环结束')
for value in range(5):
print(value)
else:
print('循环结束')
# 3.continue&break
# continue:结束本次循环,进入下次循环
# break:跳出当前循环
# 4.enumerate增加下标index
# 元素遍历,要下标 enumerate
# 获取容器类型的每一个元素(遍历)
#(字符串, 列表, 元祖, 字典, 集合)
# 字符串
for i,val in enumerate('hello'):
# 列表
for i,val in enumerate(['苹果', '草莓']):
# 元祖
for i,val in enumerate((1, 5)):
# 字典
for key,val in {'name': 'ww','age': 18}.items():
# 集合
for val in {1, 3, 5}:
这节没什么需要特别说明的,按照语法去写就行。
Python语法So Easy,妈妈再也不用担心我的学习了~
3.数据类型:列表、元组、字典、集合
前面讲过python数据类型有:
int、str、float,bool、list、tuple、dict、set
前面四个都是很简单的数据类型,整型、字符串、浮点型、布尔型,后面就是接下来讲到的稍复杂的数据类型。
数据类型:列表list
、元祖tuple
、字典dict
、集合set
首先说下它们各自如何声明的及它们的区别:
# 列表list[] 元祖tuple() 字典dict{} 集合set{}
# 列表与元祖区别:list 可修改 tuple 不可修改
# 字典与集合区别:dict 可重复 set 不可重复
my_list = [1, 5]
my_tuple = (1, 5)
my_dict = {'1':1, '5':5}
my_set = {1, 5}
1.列表list常用方法
# 声明
my_list = []
my_list = [1, 1.2, 'abc', True]
# 增末尾
my_list.append(1)
# 增任意位置
my_list.insert(1, 'abc')
# 删末尾
my_list.pop()
# 删指定数据,没有会奔溃
my_list.remove('abc')
# 删下标
del my_list[0]
# 改
my_list[-1] = '葡萄'
# 查
result = my_list[-1]
# 是否在列表
# 在列表
'西瓜' in my_list
# 找下标,没有会奔溃
my_list.index('草莓')
2.元祖tuple常用方法
能用tuple的地方就不用list,性能比list好,存储空间比list小。 不可增删改,所以只能查询。
# 声明
my_tuple = (1, 4, 'abc', True, 1.2)
# 查
my_tuple[-1]
# 注意:一个元素,类型即元素类型;多个元素,类型即元祖类型(1, )
type((1)) # <class 'int'>
type((1,)) # <class 'tuple'>
3.字典dict常用方法
# 声明
my_dict = {'name': 'ww', age: 18}
# 增
my_dict['sex'] = '男'
# 删
del my_dict['sex']
# 随机删除键值对
my_dict.popitem()
# 指定删除键值对
my_dict.pop('sex')
# 改
my_dict['sex'] = '女'
# 查 找键,没有会奔溃
my_dict['sex']
# 查 找键,不会奔溃,且默认值男
my_dict.get('sex', '男')
# 获取所有key
my_dict.keys()
# 获取所有value
my_dict.values()
# 是否在字典中
'age' in my_dict
4.集合set常用方法
# 声明
my_set = set()
my_set = {1, 4, 'abc', 'hello'}
# 增
my_set.add(5)
# 删,没有会奔溃
my_set.remove('abc')
# 删,不会奔溃
my_set.discard(1234)
5.列表list,元祖tuple,集合set,互相转换
为什么没字典dict,因为它是key-value格式的,不支持。
my_list = [1, 5]
my_tuple = (1, 5)
my_set = {1, 5}
# list转set,排除重复值
my_list = [1, 3, 3, 5]
my_set = set(my_list) # {1, 3, 5}
# list转tuple,变成常量,不可增删改
my_tuple = tuple(my_list) # (1, 3, 3, 5)
4.高级知识点:切片、拆包、可变类型、不可变类型、复制、继承
1.切片
切片,简单理解就是快速获取值的一种方式,很强大。
# (列表list、元祖tuple、字典dict、集合set、字符串str)
# 获取需要的值,举例list,其他类型类似
Arr = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
# 第一个
Arr[0] # 'Michael'
# 最后一个
Arr[-1] # 'Jack'
# 跳过第三个,其余的所有
Arr[3:] # ['Bob', 'Jack']
# 获取前四个
Arr[:4] # ['Michael', 'Sarah', 'Tracy', 'Bob']
# 每隔一个,获取
# 参数[开始:结束:步长值]
Arr[0:5:2]
# 可简写成
Arr[::2] # ['Michael', 'Tracy', 'Jack']
2.拆包
拆包,简单理解成javascript的ES6解构。
# 把一个数据使用不同的变量保存
# (列表list、元祖tuple、字典dict、集合set、字符串str)
# 列表
num1, num2 = [1, 5]
# 元祖
num1, num2 = (1, 5)
# 字典
key1, key2 = {'name':'ww', 'age':18}.values()
# 集合
num1, num2 = {1, 5}
# 字符串
a, b, c = 'abc'
3.可变类型和不可变类型
可变类型:列表list、字典dict、集合set 赋值时,原来的堆销毁,创建新堆,内存地址改变。
不可变类型:字符串str、数字number、元祖tuple 赋值时,栈引用重新指向堆,内存地址不变。
不可变类型性能大,存储空间小。
# 引用
# 通过id访问内存地址
a = 1
b = a
id(a) # 4506634176
id(b) # 4506634176
# 列表
my_list = [1, 2, 3]
id(my_list) # 4330354760
my_list2 = [1, 2, 3]
id(my_list2) # 4330354824
# 集合
my_dict = {'name':'ww', 'age':18}
id(my_dict) # 4329891952
my_dict2 = {'name':'ww', 'age':18}
id(my_dict2) # 4330352216
# 字典
my_set = {1, 2, 'ww'}
id(my_set) # 4329889576
my_set2 = {1, 2, 'ww'}
id(my_set2) # 4330319208
# 字符串
my_str = 'hello'
id(my_str) # 4330358240
my_str2 = 'hello'
id(my_str2) # 4330358240
# 数字
my_num = 1
id(my_num) # 4297644416
my_num2 = 1
id(my_num2) # 4297644416
# 元祖
my_tuple = (1, 2, 3)
id(my_tuple) # 4329967760
my_tuple2 = (1, 2, 3)
id(my_tuple2) # 4329967760
4.复制和继承
my_list = [1, 1.2, 'abc', True]
# 复制
my_list_copy = my_list.copy()
my_list2 = [3, '草莓']
# 继承
my_list.extend(my_list2)
my_list # [1, 1.2, 'abc', True, 3, '草莓']
5.列表生成式
# 快速创建列表
my_list = [value for value in range(0,6)]
# 统计每个元素的个数
my_list = [len(value) for value in ['abc', 'ab']]
# 所有的元素乘2
my_list = [value*2 for value in range(0,6)]
# 所有字符串增加字符
my_list = [value + ',name' for value in ['abc', 'ab']]
# 双层循环
my_list = [[x,y]for x in range(1,3) for y in range(1,3)]
# 结合if语句使用
my_list = [value for value in range(1,11)if value % 2 == 0]
5.各类函数及装饰器
1.内置函数
# 可以直接使用
# print、len、max、min、sorted、del、open...
2.基本函数和变量
# 1.函数的介绍 对代码进行复用
def show():
print('hello')
show()
# 2.函数的定义和调用
# 定义:
# def 函数名(参数):
# 功能实现
# 调用:
# 函数名()
def show(name, age):
print('name:%s,age:%d'%(name, age))
show('ww', 18)
# 3.函数的四种类型
# 无参无返回值
def show():
print('hello')
# 有参数无返回值
def show(name):
print(name)
# 无参数有返回值
def show():
return 'hello'
# 有参数有返回值
def show(name):
return name
# 4.局部变量
# 函数内定义的变量
# 5.全局变量
# 函数外定义的变量
score = 100
def show():
score = 99
show()
print(score) # 100
3.传参
# 1.缺省参数
# 定义时,参数就有值
# 缺省参数必须在必选参数的后面
def sum(a, b = 1):
return a + b
sum(20) # 21
# 2.位置传参和关键字传参
def sum(a, b = 1):
return a + b
sum(b = 2, a = 20) # 22
# 3.不定长参数
# 封装成tuple
def sum(*args):
count = 0
for num in args:
count += num
return count
sum(1, 2, 3, 4)
# 封装成dict
def show(**kwargs):
for key, value in kwargs.items():
print(key, value)
show(a = 1, c = 2, b = 3, d = 4)
# 4.不定长关键字参数的使用
def show(**kwargs):
print(kwargs)
def show_msg(**kwargs):
show(**kwargs)
show_msg(a = 1, b = 2)
# 5.不定长位置参数的高级使用
def show(*kwargs):
print(kwargs)
def show_msg(*kwargs):
show(*kwargs)
show_msg(1, 2)
4.复杂的函数
# 1.复杂的函数使用
# 最常见的方式
def show(name, age, *args, **kwargs):
print(name, age, args, kwargs)
# 2.函数的注意事项
# a.函数名相同会被覆盖掉
# b.变量名和函数名不能一样
# 3.必须使用关键字参数调用函数
def show(*, name, age):
print(name, age)
show(name = 'ww', age = 16)
# 4.函数的嵌套
# 函数里定义一个函数
def show:
def test()
print('hello')
test()
show()
5.高阶函数
# 1.递归函数
# 特性:传递+回归
# 阶乘
def calc_num(num):
if num == 1:
return 1
else:
return num * calc_num(num - 1)
calc_num(6)
# 获取递归次数,默认1000次
import sys
sys.getrecursionlimit() # 1000
sys.setrecursionlimit(1200)
# 2.匿名函数
# 简化代码 lambda关键字
(lambda x,y:x+y)(1,2)
# 乘法
func = (lambda x,y:x*y)
func(2, 3)
# 是否偶数
is_odd = lambda num:True if num % 2 == 0 else False
is_odd(1)
# 字典列表排序
my_list = [{'name':'ww', 'age':18},{'name':'zl', 'age':16}]
# 简写
my_list.sort(key=lambda item:item['age'])
# 全写
def get_value(item):
return item['age']
my_list.sort(key=get_value)
# 3.偏函数
import functools
def show(a, b, c=1):
return a + b + c
# 定义偏函数
show2 = functools.partial(show, b = 4)
show2(2) # 7 2+4+1
# 可以对内部函数使用偏函数
int2 = functools.partial(int, base = 2)
int2("11") # 3 十进制转二进制
# 4.返回函数
# 函数嵌套
# 返回函数是高级函数的一种
def show():
def draw():
print('--draw--')
return draw
draw = show()
draw()
# 定义返回函数
def calc(operation):
if operation == '+':
return (lambda x,y:x+y)
elif operation == '-':
return(lambda x,y:x-y)
else:
pass
# 调用返回函数
add = calc('+')
reduce = calc('-')
add(1, 2) # 3
reduce(1, 2) # -1
# 5.高阶函数
# 函数的参数是另一个函数,返回一个函数,就是高阶函数
def add(a, b):
return a+b
def reduce(a, b):
return a-b
def calc(a, b, add):
return add(a, b)
calc(1, 2, add) # 3
calc(1, 2, reduce) # -1
# 6.闭包
# 闭包也是一个高阶函数
# 闭包应用场景:根据参数生成不同的返回函数
def hello(msg, count):
def return_msg():
result = msg * count
return result
return return_msg
new_func1 = hello('A', 2)
new_func2 = hello('B', 2)
new_func1()
new_func2()
6.装饰器
# 本质上是一个函数,可以给原函数的功能进行扩展
def show():
print('AAA')
def decorator(func):
# 定义
def inner():
print('---', end=' ')
# 调用show
func()
return inner
# 重新给show赋值
show = decorator(show)
show() # '--- AAA'
# 1.装饰器
def decorator(func):
# 定义
def inner():
print('---', end=' ')
# 调用show
func()
return inner
# 重新给show赋值
# 语法糖修饰(修饰show函数,给show函数增加新的功能)
@decorator
def show():
print('AAA')
show() # '--- AAA'
# 2.装饰器修饰带有参数的函数
def decorator(func):
def inner(a, b):
print('计算结果如下')
return func(a, b)
return inner
@decorator
def sum(a, b):
return a + b
sum(1, 5)
# 3.通用的装饰器
装饰器可以修饰任何函数
def decorator(func):
def inner(*args, **kwargs):
print('计算结果如下')
return func(*args, *kwargs)
return inner
@decorator
def sum1(a, b):
return a + b
sum1(1, 5)
@decorator
def sum2(a, b, c):
return a + b + c
sum2(1, 5, 10)
# 4.带有参数的的装饰器
def get_decorator(char):
def decorator(func):
def inner():
print(char)
print('---', end=' ')
func()
return inner
return decorator
@get_decorator('AAA')
def show():
print('OK')
show() # 'AAA --- OK'
6.模块、包的导入和导出
# 1.模块的介绍
# 一个py文件就是一个模块
# 模块里面可以定义类,定义函数,定义全局对象,实现某些功能
# 2.内置模块
# python自带的模块
# 举例:datetime 、sys、os、time、html、random
# 循环两次
for i in range(2)
# 从99递减到0
for i in range(99, 0, -1)
# 查询一个对象
dir(obj)
# 间隔1秒执行
time.sleep(1)
# 生成1~60之间的随机数
random.randint(1, 60)
# 一个对象是否在另一个对象
for cha in 'Hello'
# 一个对象的大小
len('Hello')
# 3.自定义模块
# 定义一个全局变量
# first_module.py:
g_num = 10
def show():
pass
class Teacher():
pass
# 导入
import first_module
first_module.num
first_module.show()
first_module.Teacher()
# 查看当前主模块
__name__
if __name__ == '__main__':
pass
# 4.模块的导入
# 1.直接导入
# import 导入模块名
import first_module
# 2.部分导入
# from 模块名 import 功能代码
from first_module import show
# 3.限制导入特定的功能
# first_module.py里面
__all__ = ['g_num']
# from 模块名 import *
import first_module
first_module.show() # 报错
# 4.给import模块名设置别名
import first_module as first
first.show()
from first_module import show as show_msg
# 5.模块导入的注意点
# 这种导入需要保证当前模块不要定义导入的功能代码
from first_module import show
def show():
pass
show() # 覆盖了功能代码
import first_module
first_module.show()
# 自定义模块名不要和系统模块名重复
# 查看模块搜索的顺序
import sys
sys.path
# 6.包
# 文件夹里面有__init__.py的文件
# 包是管理模块的,模块是整理功能代码
# 7.包的导入
# 和模块导入类似
# 导入第一个模块
import first_package.first_module
from first_package import first_module
# 设置模块别名
import first_package.first_module as first
first.show()
# 直接导入包,不会自动导入对应模块,
# 需去__init__.py里面指定导入的模块。
# first_package里面的__init__.py,设置
__all__ = ['first_module']
import first_module
import first_package
first_module.show()
7.文件IO的操作
# 1.文件的介绍
# 文件做到永久存储,可以放硬盘,数据库,mysql,mongodb等
# 2.文件的读写
# 打开文件 open
# ------r模式(只读) 没有会报错
file = open('1.txt', 'r')
file.read()
file.close()
# ------w模式(只写)
# 文件不存在,会创建一个打开
# 文件存在,会清空原有数据
file = open('1.txt', 'w',encoding='utf-8')
# 多次写入,不会覆盖
file.write('A')
file.write('B')
file.close()
# 查看文件格式
file.encoding
Mac,Linux('utf-8') Windows('gbk') cp936
# ------a模式(追加写入)
# 文件存在,会追加原有数据
file = open('1.txt', 'a')
file.write('C')
file.close()
# ------rb模式(二进制方式读取)
file = open('1.txt', 'rb')
# 中文会出现\xe4\xb8\xad,一个中文三个字节
file.read() # A\xe4\xb8\xad
# 可以解码
file.read().decode('utf-8')
file.close()
# ------wb模式(二进制方式写入)
file = open('1.txt', 'wb')
# 包装成二进制编码
file.write('A果'.encode('utf-8'))
file.close()
# ------ab模式(二进制方式追加)
file = open('1.txt', 'ab')
file.write('C果'.encode('utf-8'))
file.close()
# ------爬视频、图片、文本、音频,常用的rb、wb、ab
# r+ w+ a+ 支持读写
# rb+ wb+ ab+ 支持二进制读写
file = open('1.txt', 'r+')
file.write('abc')
res = file.read()
print(res)
file.close()
# 7.文件的不同读取操作
read() # 读全部
readLine() # 读一行
readLines() # 读全部,但每行读
# 8.文件的拷贝
file = open('1.txt', 'rb')
file_data = file.read()
new_file = open('1[副本].txt', 'wb')
new_file.write(file_data)
file.close()
new_file.close()
# 9.模拟大文件的拷贝
file = open('1.txt', 'rb')
new_file = open('1[副本2].txt', 'wb')
# 一次性只读1024个字节
while True:
file_data = file.read(1024)
# 判断数据是否读取完毕
# 判断file_data是否为None
if file_data:
new_file.write(file_data)
else:
print('数据读取完成', new_file)
break
file.close()
new_file.close()
# 10.if判断的扩展
# 原来if判断:True False(非False即真)
# 容器类型(非0非None即真)
if False:
....
if 0:
....
if None:
....
# 11.文件和文件夹相关的操作
# 导入模块
import os
# 重命名文件|文件夹
os.rename('1.txt', '2.txt')
os.rename('TEST', 'TEST2')
# 创建文件夹
os.mkdir('TEST')
# 当前路径
os.getcwd()
# 切换到指定目录
os.chdir('TEST')
# 删除文件
os.remove('1.txt')
# 删除文件夹
os.rmdir('TEST')
# 12.StringIO和ByteIO
# StringIO和文件写入、读取操作类似
# 向内存写入和读取String数据、二进制数据
import io
str_io = io.StringIO()
byte_io = io.BytesIO()
byte_io.write('哈哈'.encode('utf-8'))
# 1.读取所有
data = byte_io.getvalue()
# 2.读取,需设置光标
byte_io.seek(0)
data = byte_io.read()
content = data.decode('utf-8')
8.面向对象、类和对象、封装、继承、多态、异常
1.面向对象
# 1.面向对象和面向过程
# 面向过程:提供方法(自己干)
# 面向对象:功能对象提供方法(对象干)
# 举例:
# 实现炒菜的功能
# 过程:洗菜->切菜->准备作料->进行翻炒->出彩
# 对象:厨师(洗菜->切菜->准备作料->进行翻炒->出彩)
# 2.类和对象的关系
# 类:事或物的一个分类,类只是一个概念
# 对象:具体到某一个事或物
# 举例:
# 汽车->类
# 奥迪Q7->对象
# 电瓶车->类
# 我的电瓶车->对象
2.类和对象
# 1.类的定义
# 类:属性(特征)和方法(行为)
# python3默认继承object
# 旧式类的创建方式
class Teacher():
country = None
def show(self):
pass
teacher = Teacher()
teacher.show()
teacher.country
# 继承的类
Teacher.__bases__
# 2.新式类的创建方式
# 为了兼容不同的python版本,建议使用该方式创建类
class Teacher(object):
country = None
def show(self):
pass
# 3.动态添加对象的属性,获取属性值
# 创建对象
teacher = Teacher()
# 动态添加的属性
teacher.name = None
# 获取属性值
teacher.country
# 调用方法
teacher.show()
3.常见魔法方法
# 含__xxx__的方法
# 1.__new__魔法方法
# 创建对象是自动调用两个方法,先__new__,再__init__
class Teacher(object):
def __new__(cls):
print('创建一个对象')
return object.__new__(cls)
def __init__(self):
print('初始化')
# 2.__init__魔法方法
# 对象初始化时__init__会被调用
class Teacher(object):
# init方法里面添加参数,self表示当前对象
def __init__(self, country):
self.country = country
def show(self):
pass
# 3.__del__魔法方法
# 对象释放时回自动调用
class Teacher(object):
def __init__(self, country):
self.country = country
def __del__(self):
print('对象销毁了', self)
teacher = Teacher('小明')
# 退出程序时
exit() # 对象销毁了 <__main__.Teacher object at 0x101ac5e80>
# 销毁对象
del teacher
# 4.__str__魔法方法
# 使用print对象时__str__会被调用
class Teacher(object):
def __init__(self, country):
self.country = country
def __str__(self):
return '出生地:%s'%(self.country)
def show(self):
pass
teacher = Teacher('成都')
print(teacher) # 出生地:成都
# 5.__slots__魔法方法
# 创建对象时不能再添加其他属性
class Person(object):
# 对象固定属性
__slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('小明', 18)
p.sex = '男'
4.继承
# 1.单继承
# 类的三大特征:继承、封装、多态
# 继承好处:子类可以复用父类的属性和方法
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print(self.name, self.age)
class Student(Person):
pass
xiao_ming = Student('小明', 18)
xiao_ming.show()
xiao_wei = Student('小伟', 16)
xiao_wei.show()
# 2.多继承
# 多个父类,方法会遵循mro法则
# 类的继承顺序决定方法的调用顺序
class A(object):
def show(self):
print('A类')
class B(object):
def show(self):
print('B类')
class C(A, B):
pass
c = C()
c.show()
C.mro() # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
# 3.子类重写父类的方法
class Person(object):
def run(self):
print('跑起来')
class Student(Person):
def __init__(self, name):
self.name = name
def run(self):
print('%s跑起来了'% self.name)
stu = Student('小明')
stu.run()
# 4.使用类名调用父类的方法
class Animal(object):
def show(self):
print('动物')
class Dog(Animal):
def show(self):
# self指定类的继承链,获取Dog的下一个类Animal
super(Dog, self).show()
print(self.__class__.mro())
dog = Dog()
dog.show()
# 5.多继承super的使用
class A(object):
def show(self):
print('A类')
class B(object):
def show(self):
print('B类')
class C(A, B):
def show(self):
super(C, self).show()
print('C类')
c = C()
c.show() # A类 C类
# 6.重写方法里使用super
class A(object):
def show(self):
print('A类')
class B(object):
def show(self):
print('B类')
def f():
pass
class C(A, B):
def show(self):
# 方法重写
super(A, self).show()
c = C()
c.show() # A类 super(C, self).show()
c.show() # B类 super(A, self).show()
# 7.私有属性和私有方法
class Person(object):
def __init__(self, name, age):
# 公有属性
self.name = name
# 私有属性
self.__age = age
# 公有方法
def show(self):
print(self.name, self.age)
# 私有方法
def __show(self):
pass
class Student(Person):
pass
person = Person('小明', 18)
person.__dict__ # 对象中的所有属性
Person.__dict__ # 对象中的所有方法
# 约定俗成(以__开头的就是私有的)
# 子类继承父类,不能直接使用父类的私有属性和方法
# 8.类属性和实例属性
class Person(object):
# 类属性
type = '黑人'
def __init__(self):
# 实例属性
self.name = '人'
# 查看类属性和方法
Person.__dict__
# 对象可以访问类属性但是不可以修改类属性
# 9.对象方法、类方法、静态方法
# cls当前类 self当前对象
class Person(object):
# 对象方法
def show(self):
pass
# 类方法
@classmethod
def show_self(cls):
pass
# 静态方法
@staticmethod
def showmsg():
pass
5.多态
# python本质上没有多态(假象)(约定俗成)
# 多态:关注的是同一个方法,但会出现不同形式
class Text(object):
def show(self):
print('显示文字')
class Image(object):
def show(self):
print('显示图片')
class Video(object):
def show(self):
print('显示视频')
# 显示数据的方法
def show_data(object):
object.show()
image = Image()
text = Text()
video = Video()
show_data(image)
show_data(text)
show_data(video)
6.异常
# 1.异常的介绍
# python解释器去执行代码时出错
name = ''
name + 10
# 2.异常捕获
try:
name = ''
name + 10
except Exception as e:
print(e)
try:
pass
except Exception as e:
pass
else:
pass
finally:
pass
# 3.自定义异常类
class NumberException(Exception):
def __init__(self):
pass
def __str__(self):
return '不是数字,所以异常'
# 抛异常
raise NumberException()
# 抛系统异常
raise NameError('系统异常')
9.单例模式、迭代器和生成器
1.单例模式
# 常用设计模式
# 不管创建多少次对象,都是一个对象
class Teacher(object):
__instance = None
def __new__(cls):
if cls.__instance == None:
print('创建一个对象')
cls.__instance = object.__new__(cls)
return cls.__instance
def __init__(self):
print('初始化')
# 创建一个对象
teacher = Teacher()
# 再创建一个对象
teacher2 = Teacher()
# 内存地址都一样
2.迭代器和生成器
# 1.可迭代对象
# 使用for循环遍历取值的对象:列表,元祖,字典,集合,字符串,range
# 判断是否是可迭代对象
from collections import Iterable
isinstance([1, 2], Iterable)
isinstance(value, type)
# 可迭代对象有一个__iter__方法
# 2.迭代器
# 用的不是很多
# 作用:根据数据的位置获取下一个位置的值
占用内存少
from collections import Iterable
class MyIterable(object):
def __init__(self):
self.mylist = [4, 5, 9]
self.current_index = 0
def __iter__(self):
return self
def __next__(self):
if self.current_index < len(self.mylist):
res = self.mylist[self.current_index]
self.current_index += 1
return res
else:
raise StopIteration
# 创建迭代器
my_iterable = MyIterable()
isinstance(my_iterable, Iterable)
next(my_iterable)
# 3.生成器
# 生成器:特殊的迭代器,可以通过next函数和for取值
# 占用内存相当少
# 值只能向后取值,不能向前取值
# 使用生成器的表达式
next( [x for x in range(4)] ) # 'list' object is not an iterator
next( (x for x in range(4)) )
def show():
for x in range(4):
# 代码遇到yield会暂停,然后把结果返回过去
# 下次启动生成器会暂停该位置
# yield特点:可以返回多次值,return只能返回一次
yield x
g = show()
next(g)
9.序列化和反序列化、线程和进程
1.序列化和反序列化
# 1.序列化
# 把内存的数据保存到本地,数据持久化
# 比较通用,可以序列化任何数据
# 任何数据,列表,对象等
import pickle
my_list = [{'name':'ww', 'age':18},{'name':'zl', 'age':16}]
# 得到二进制数据,写入二进制文件
file = open('1.serialize', 'wb')
pickle.dump(my_list, file)
file.close()
# 2.反序列化
import pickle
file = open('1.serialize', 'rb')
my_list = pickle.load(file)
file.close()
# 3.json序列化
import json
my_list = [{'name':'ww', 'age':18},{'name':'zl', 'age':16}]
file = open('mylist.json', 'w', encoding='utf-8')
# 序列化
json.dump(my_list, file)
file = open('mylist.json', 'r', encoding='utf-8')
# 反序列化
my_list = json.load(file)
file.close()
# 自定义类型
class Student(object):
def __init__(self, name, age):
self.name = name
self.age = age
file = open('student.json', 'w', encoding='utf-8')
stu = Student('ww', 18)
# 序列化对象的属性值
json.dump(stu.__dict__, file)
file.close()
2.线程和进程
# 1.线程
# 线程:执行代码的分支,默认只有一个线程
# python本质上没有线程(假象)
import threading
def A(count):
for i in range(count):
print('A')
def B(count):
for i in range(count):
print('B')
# 创建子线程
# target:表示目标函数 args:元祖的方式给函数传参
one = threading.Thread(target = A, args = (10, ) )
two = threading.Thread(target = B, kwargs = {'count': 10} )
one.start()
two.start()
# 2.主线程会等待所有子线程执行完毕之后再退出
# 线程相关设置,都要放在线程启动之前
one.setDaemon(True) //设置守护线程
one.start()
# 3.互斥锁
lock = threading.Lock()
# 上锁
lock.acquire()
# 释放锁
lock.release()
# 4.进程
# 进程:每次创建一个进程操作系统会给这个进程分配对应的资源
# 一个进程里默认有一个主线程
# 真正干活的是线程,进程只通过资源
# 多进程可以完成多任务
import multiprocessing
def A(count):
for i in range(count):
print('A')
def B(count):
for i in range(count):
print('B')
# 创建子进程
# target:表示目标函数 args:元祖的方式给函数传参
one = multiprocessing.Process(target = A, args = (10, ) )
two = multiprocessing.Process(target = B, kwargs = {'count': 10} )
one.start()
two.start()
# 5.主进程会等到子进程执行完毕之后退出
one.daemon = True //设置守护线程
one.start()
# 6.进程之间不共享全局变量
one.join()
3.消息队列
import multiprocessing
# 创建消息队列
queue = multiprocessing.Queue(3)
# 消息队列里面添加数据
queue.put(1)
queue.put(2)
queue.put(3)
# 获取队列值
queue.get()
# 进程之间可以使用消息队列通信
# 多任务使用线程和进程
# 从资源的角度来说,进程更加节省资源
# 进程消耗的资源比较多
# 从代码稳定性来说:多进程要比多线程稳定性要强
# 因为一个进程挂掉,不会影响其他应用程序
此致,python的基础篇就全部结束了,知识点确实有点多,但不求每个都记住,但前八章的知识点和概念必须掌握
,因为后续的python开发中几乎都能有所涉及。每周进步一点点!