Python编程
前言
包括pycharm使用;冒泡算法;request爬虫;面向对象与面向过程的区别,面向对象概念,初始化方法,实例方法与类的实例化,新建类,类方法与静态方法;反射,单例模式;完全继承,重写父类的方法,改写父类的方法,多继承。
一、pycharm使用
1、常用配置
(1)、新建文件时,自动生成注释:settings → editor → file and code templates,选择python script
${NAME} 文件名
${DATE} 日期
(2)、自动补齐
if __name__ == '__main__': # 先输入main,然后按tab键
print() # 先输入pr,然后按tab键
(3)、自动补齐自定义段落:settings → editor → live templates,点击右侧的+号,添加自定义的内容,完成之后,在下方勾选python
(4)、修改注释的颜色:settings → editor → color scheme → python
(5)、取消语法检查:settings → editor → inspections,选择python,取消勾选PEP8的两个选项(去掉代码中的灰色波浪线:语法规范)
(6)、快速较准代码格式:Ctrl + Alt + L
(7)分屏:settings → keymap,查询split关键字,找到分屏的图标,设置快捷键
2、真实环境与虚拟环境
(1)、cmd安装的第三方库,Python用不了,第一种排查方法:查看有没有同名文件;第二种:新建项目时,选虚拟环境时,需勾选Inherit global site-packages(允许使用本地的第三方库)、Make available to all projects(允许别的项目使用本项目的第三方库)
(2)、如果导入一个第三方库没有安装,可以点击“灯泡”,点击Install package selenium
3、调试
4、pycharm中的常用快捷键
快捷键 | 含义 |
---|---|
Ctrl + 悬浮/单击鼠标左键 | 简介/进入代码定义 |
Ctrl + / | 行注释/取消行注释 |
Ctrl + Alt + L | 代码格式化 |
Ctrl + R | 替换 |
Ctrl + Shift + F 或者连续2次敲击shift | 全局查找{可以在整个项目中查找某个字符串什么的,如查找某个函数名字符串看之前是怎么使用这个函数的} |
Ctrl + Shift + R | 全局替换 |
Ctrl + / | 行注释/取消行注释 |
Ctrl + Alt + L | 代码格式化 |
Shift + F11 | 显示所有书签 |
Ctrl + Alt + L | 代码格式化 |
Tab | 向后缩进4格 |
Shift + Tab | 向前缩进4格 |
Icon Description | 含义 |
---|---|
c代表Class:类 | |
m代表Method:类实例方法 | |
F代表Function:函数 | |
f代表Field:类属性,域 | |
v代表Variable:变量 | |
p代表Property:python内置函数 | |
p代表Parameter:参数 | |
<>代表Element:元素 |
二、冒泡算法
列表中的数字,两两比较,如果前面的数比后面的大,则两数互换,每一轮确定一个最大的数
# 原始数据[4,3,2,1] n个数,第一轮比较n-1次
# 第一次比较,将4和3的位置互换 3421
# 第二次比较,将4和2的位置互换 3241
# 第三次比较,将4和1的位置互换 3214
# 第二轮原始数据[3,2,1,4] 第二轮比较n-1-1次
# 第一次比较,将3和2的位置互换 2314
# 第二次比较,将3和1的位置互换 2134
# 第三轮原始数据[2,1,3,4] 第三轮比较n-1-2次
# 第一次比较,将2和1的位置互换 1234
# from random import randint
# list1 = []
# for i in range(10):
# list1.append(randint(0,100)) # 获取随机的10个元素数组
list1 = [15, 77, 98, 39, 76, 14, 90, 9, 36, 81]
for i in range(len(list1)-1): # 外层循环,控制比较多少轮
# print(f'开始第{i+1}轮比较')
for j in range(len(list1)-1-i): # 内层循环,控制每轮比较多少次
if list1[j] > list1[j+1]: # 如果前面的数比后面的大,则两数互换
# print(f'{list1[j]}大于{list1[j+1]},两数互换')
# print(f'互换前--------------------------->{list1}')
list1[j],list1[j+1] = list1[j+1],list1[j]
# print(f'互换后--------------------------->{list1}')
# print(f'第{i+1}轮比较结束')
print(list1)
三、requsets爬虫
1、正则表达式
从一段字符串中按照一定规则提取符合条件的数据
import re
str1 = 'ABCDEFGDYUIOPG'
print(re.findall('D(.*?)G',str1)) # (.*?)提取D段和G段之间的数据,返回值是列表
import re
str2 ='''helloabcdefg
abcdefgworld'''
print(re.findall('hello(.*?)world',str2,re.S)) # re.S允许跨行匹配
2、爬虫的原理
(1)、模拟浏览器向服务器发送请求
(2)、下载网页代码
(3)、提取有用的数据
(4)、保存数据
import re,requests #加载正则表达式模块与爬虫模块
url = 'http://www.quannovel.com/read/620/'
resp = requests.get(url) # 获取网页内容
# print(resp) # 获取响应码
# print(resp.text) # 获取html中的内容
book_name = re.findall('<h2>(.*?)<i class',resp.text)[0] # 获取书名
print(book_name)
import re,requests #加载正则表达式模块与爬虫模块
url = 'http://www.quannovel.com/read/620/'
resp = requests.get(url) # 获取网页内容
title_list = re.findall('class="name ">(.*?)</a>',resp.text) # 获取章节名称
for one in title_list:
print(one)
import re,requests #加载正则表达式模块与爬虫模块
url = 'http://www.quannovel.com/read/620/'
resp = requests.get(url) # 获取网页内容
url_list = re.findall('<a href="(.*?).html"',resp.text) # 获取正文网址
for one in url_list:
print(one)
import re,requests #加载正则表达式模块与爬虫模块
url = 'http://www.quannovel.com/read/620/'
resp = requests.get(url) # 获取网页内容
title_list = re.findall('class="name ">(.*?)</a>',resp.text) # 获取章节名称
url_list = re.findall('<a href="(.*?).html"',resp.text) # 获取正文网址
for one in url_list:
print(one)
dict1 = {}
for i in range(len(title_list)):
dict1[title_list[i]] = f'{url}{url_list[i]}.html' # 将章节名称和正文地址保存到字典
for k,v in dict1.items():
print(k,v)
四、面向对象基础
1、面向对象与面向过程的区别
以编写一个五子棋程序举例
(1)、面向过程的方式,先判断谁落子,然后判断是否获胜,如果没有获胜继续判断谁落子,判断是否获胜
(2)、面向对象的方式,事先写好各种函数或方法,主程序只负责调用,调用判断落子的方法,调用判断获胜的方法
(3)、面向对象的方法主要是把事物给对象化,包括其属性和行为。面向对象编程更贴近实际生活的思想
2、面向对象概念
类和实例的概念
(1)、类是抽象的模板,实例是根据模板创建出来的具体的对象
(2)、比如人类就是一个类,彭于晏是人类的一个实例
(3)、汽车是一个类,邻居买的那辆车是汽车的实例
3、初始化方法
(1)、初始化方法:__init__
(2)、在实例产生时,赋予实例属性值
def __init__(self, length, width): # 初始化方法
self.length = length # 将用户传的length转为实例自身的length
self.width = width # 将用户传的width转为实例自身的width
(3)、self表示实例本身,这个参数是默认的,不需要传值。用户在实例化一个长方形时,需要传长和宽两个值,之后初始化方法将其转为长方形实例的属性
(4)、初始化方法里的length转换为self.length之后,类当中的所有含有self参数的方法都可以使用这个属性
4、实例方法与类的实例化
(1)、实例方法,定义的方式与函数类似
(2)、调用时,实例.方法名()进行调用,实例方法不可以由类调用
def perimeter(self):
return (self.length + self.width) * 2
def area(self):
return self.length * self.width
(3)、方法里的self表示实例本身,所以可以直接使用实例的属性,比如长方形实例的长和宽,调用时,用户不需要传长和宽就可以计算出周长和面积
(4)、类是抽象的概念,不能被直接调用,要调用具体的实例,也就是实例化
(5)、实例化=类(属性) 实例化一个类
rec = Rectangle(5, 4) # 实例化一个长方形,长为6,宽为4
(6)、实例化之后,就可以调用类里面的所有方法和属性
print(rec.perimeter())
print(rec.area())
5、新建类
(1)、新建一个类,方法封装在类里,写法:
class 类名: # 类名首字母大写
def 方法名():
代码
def 方法名():
代码
(2)、新建一个长方形的类:
# 面向过程的写法
def perimeter(length, width):
return (length + width) * 2
def area(length, width):
return length * width
print(perimeter(5, 4))
print(area(5, 4))
1)、self表示实例本身,这个参数是默认的,不需要传值
2)、用户在实例化一个长方形时,需要传长和宽两个值,通过初始化方法将其转为长方形实例的属性
3)、类当中的所有含有self参数的方法都可以使用含有self的属性或方法,比如self.length与self.width
# 面向对象的写法
class Rectangle:
def __init__(self, length, width): # 初始化方法
self.length = length # 将用户传的length转为实例自身的length
self.width = width # 将用户传的width转为实例自身的width
def perimeter(self): # 周长的方法
return (self.length + self.width) * 2
def area(self): # 面积的方法
return self.length * self.width
rec = Rectangle(5, 4) # 实例化
print(rec.__dict__) #打印实例具有的属性
print(rec.perimeter())
print(rec.area())
6、类方法与静态方法
(1)、类方法是类具有的方法
# 类方法可以直接由类调用,也可以由实例调用
@classmethod # 修饰器,表示下面的方法是类方法
def features(cls):
pass
(2)静态方法与每个具体实例无关
@staticmethod # 静态方法,本质上是函数
def sumdata(a, b):
pass
class Rectangle:
def __init__(self, length, width): # 初始化方法
self.length = length # 将用户传的length转为实例自身的length
self.width = width # 将用户传的width转为实例自身的width
def perimeter(self): # 周长的方法
return (self.length + self.width) * 2
def area(self): # 面积的方法
return self.length * self.width
@classmethod # 装饰器,声明下面的方法是类方法
def features(cls): # 声明装饰器后,写完方法名cls会自动补齐
print('两边的长相等,两边的宽也相等,长和宽的角度是90°')
@staticmethod # 装饰器,声明下面的方法是静态方法
def sumdata(a, b): # 静态方法本质上是函数,与类无关,只是写在了类里面
return a + b
rec = Rectangle(5, 4) # 实例化
Rectangle.features() # 类方法可以被类调用,也可以被实例调用
print(Rectangle.sumdata(3, 6)) # 静态方法可以被类调用,也可以被实例调用
print(rec.sumdata(3, 6))
(3)、type() 查看对象类型
class Rectangle:
def __init__(self, length, width): # 初始化方法
self.length = length # 将用户传的length转为实例自身的length
self.width = width # 将用户传的width转为实例自身的width
def perimeter(self): # 周长的方法
return (self.length + self.width) * 2
def area(self): # 面积的方法
return self.length * self.width
@classmethod # 装饰器,声明下面的方法是类方法
def features(cls): # 声明装饰器后,写完方法名cls会自动补齐
print('两边的长相等,两边的宽也相等,长和宽的角度是90°')
@staticmethod # 装饰器,声明下面的方法是静态方法
def sumdata(a, b): # 静态方法本质上是函数,与类无关,只是写在了类里面
return a + b
rec = Rectangle(4, 5)
print(type(rec.perimeter)) # 实例方法是method
print(type(Rectangle.features)) # 类方法是method
print(type(Rectangle.sumdata)) # 静态方法是function
(4)、inspect python的自检模块,返回某个对象是否是某个类型,返回值是布尔型
import inspect
class Rectangle:
def __init__(self, length, width): # 初始化方法
self.length = length # 将用户传的length转为实例自身的length
self.width = width # 将用户传的width转为实例自身的width
def perimeter(self): # 周长的方法
return (self.length + self.width) * 2
def area(self): # 面积的方法
return self.length * self.width
@classmethod # 装饰器,声明下面的方法是类方法
def features(cls): # 声明装饰器后,写完方法名cls会自动补齐
print('两边的长相等,两边的宽也相等,长和宽的角度是90°')
@staticmethod # 装饰器,声明下面的方法是静态方法
def sumdata(a, b): # 静态方法本质上是函数,与类无关,只是写在了类里面
return a + b
rec = Rectangle(4, 5)
print(inspect.ismethod(rec.perimeter)) # inspect.ismethod判断是否是方法,True
print(inspect.ismethod(Rectangle.features)) # True
print(inspect.ismethod(Rectangle.sumdata)) # 静态方法实际是函数False
print(inspect.isfunction(rec.perimeter)) # inspect.isfunction判断是否是函数,False
print(inspect.isfunction(Rectangle.features)) # False
print(inspect.isfunction(Rectangle.sumdata)) # True
五、反射与单例模式
1、反射
(1)、反射的定义:主要是应用于类的对象上,在运行时,将对象中的属性和方法反射出来
(2)、使用场景:可以动态的向对象中添加属性和方法。也可以动态的调用对象中的方法或者属性
(3)、反射的常用方法:
- 1)hasattr(参数1,参数2) 查询参数1对象里有没有参数2,返回值是布尔型
print(hasattr(str, 'replace'))
print(hasattr(list, 'append'))
- 2)getattr(参数1,参数2,[参数3]) 查询参数1对象里有没有参数2,如果能找到返回参数2本身,如果找不到,返回参数3
print(getattr(str, 'replace'))
print(getattr(str, 'replace1', '没有该属性或方法'))
- 3)setattr(参数1,参数2) 在参数1对象里修改参数2的属性,如果找不到属性,新建属性并赋值
class Class1:
a = 1
setattr(Class1, 'a', 100)
setattr(Class1, 'b', 200)
print(Class1.a, Class1.b)
2、单例模式,一个类只允许生成一个实例
class Single:
# 构造方法
def __new__(cls, *args, **kwargs): # 构造方法,cls表示类本身,*args运行传任意参数,**kwargs运行传任意参数(键值对)
if not hasattr(cls, 'obj'): # 判断类当中有没有实例,如果没有则新建
cls.obj = super().__new__(cls) # 生成实例对象,继承父类object的new方法
return cls.obj
s1 = Single()
s2 = Single()
print(id(s1), id(s2)) # id打印在内存中的编号
六、类的继承
class Rectangle:
def __init__(self, length, width): # 初始化方法
self.length = length # 将用户传的length转为实例自身的length
self.width = width # 将用户传的width转为实例自身的width
def perimeter(self): # 周长的方法
return (self.length + self.width) * 2
def area(self): # 面积的方法
return self.length * self.width
@classmethod # 装饰器,声明下面的方法是类方法
def features(cls):
print('两边的长相等,两边的宽也相等,长和宽的角度是90°')
1、完全继承
class Square(Rectangle): # Rectangle继承类的名字,Rectangle是Square的父类
pass
squ = Square(6, 6)
print(squ.perimeter())
print(squ.area())
2、重写父类的方法
class Square(Rectangle):
def __init__(self, side):
self.length = side
self.width = side
squ = Square(6)
print(squ.perimeter())
print(squ.area())
3、改写父类的方法,在父类代码的基础上增加其他的代码
class Square(Rectangle):
@classmethod
def features(cls):
super().features() # 继承父类的features方法
print('长和宽也相等')
Square.features()
4、多继承
(1)、一个类可以有多个父类,调用多个父类中的同名方法时,按继承顺序进行调用
class Money1:
def money(self):
print('一个亿')
class Money2:
def money(self):
print('两个亿')
class Human(Money1, Money2): # 继承多个父类时,用逗号隔开,多个父类中有同名方法时,按继承顺序进行调用
pass
man = Human()
man.money()
(2)、所有的类都是object的子类,或者子类的子类
(3)、一个类,无论是否声明继承object,实际都继承,继承object之后,就可以使用object的属性
class Class1:
'''
莫听穿林打叶声
何妨吟啸且徐行
'''
print(Class1.__name__) # 返回类的名称
print(Class1.__base__) # 返回父类的名称
print(Class1.__bases__) # 返回所有父类的名称,返回元组
print(Class1.__dict__) # 返回类的属性
print(Class1.__doc__) # 返回类的注释,在类中写注释使用'''