Python(四):pycharm使用、冒泡算法、requests爬虫、面向对象、反射与单例模式、类的继承


前言

包括pycharm使用;冒泡算法;request爬虫;面向对象与面向过程的区别,面向对象概念,初始化方法,实例方法与类的实例化,新建类,类方法与静态方法;反射,单例模式;完全继承,重写父类的方法,改写父类的方法,多继承。


一、pycharm使用

1、常用配置

(1)、新建文件时,自动生成注释:settings → editor → file and code templates,选择python script

${NAME} 文件名
${DATE} 日期

在这里插入图片描述

JH67

(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__)  # 返回类的注释,在类中写注释使用'''

在这里插入图片描述


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鹿快跑~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值