Python基础回顾笔记(二)

自定义模块:

_ _ name _ _ :

当一个Python模块或包被导入时,_ _ name _ 会被设为模块的名称。通常,这将是Python文件本身的名称去掉·py后缀,不过如果模块是在最高层级代码环境中执行的,则它的name会被设为字符串 _ _ main _ _。

_ _ all _ _ :

使用_ _ all _ _ 可以控制import * 时,哪些功能被导入,注意:import 模块方式,不受 _ _all _ _ 的限制。

包:

从结构上看,包就一个文件夹,在该文件夹下包含了一个 _ _ init _ _ .py文件,该文件夹可以用于包含多个模块文件,从逻辑上看,包可以视为模块集合。 _ _ init _ _ .py:控制包的导入操作。

_ _ init _ _ . py通过 _ _ all _ _ 控制允许导入的模块。_ _ init _ _ . py中增加 _ _ all _ _ = [允许导入的模块列表] 针对 from 包 import * 方式生效,对import xx方式不生效

导入:

  • import包名 . 模块 使用:包 . 名模块 . 功能

  • from 包名 import 模块 使用:模块 . 功能,不用带包名

  • from 包名 . 模块 import 函数、类、变量 使用:函数、类、变量

1)alt+enter,提示你选择解决方案 2)alt+shift+enter,直接导入

第三方库:

第三方库/包:就是非Python官方提供的库,Python语言有很多的第三方库,覆盖几乎所有领域,比如:网络爬虫、自动化、数据分析与可视化、WEB开发、机器学习等,使用第三方库,可以大大提高开发效率。

pip install -i Simple Index 包名

类与对象:

属性的定义语法同变量,示例:属性名=值,如果没有值,可以赋值None(None是Python的内置常量,通常被用来代表空值的对象),但不能不赋值。

self参数:

  • Python也支持对象动态的添加方法。但添加的方法指针都当前对象。

class Person:
    a = 1
    b = 3
def hi():
    print("hi...".center(30,"-"))
​
p = Person()
p.m1 = hi()
p.m1   #------------hi...-------------
  • 在方法定义的参数列表中,有一个seIf。

  • self表示当前对象本身

  • self是定义成员方法时,需要写上的,如果不写,则需要使用@staticmethod标注,否则会报错。

  • 当我们通过对象调用方法时,self会隐式的传入。

  • 在方法内部,要访问成员变量和成员方法需要使用self。

静态方法:

  • @staticmethod 将方法转换为静态方法,静态方法不会接收隐式的接受第一个参数self

  • 静态方法既可以由类调用(如C.f ( ) ),也可以由实例中调用(如C ( ) . f ( ) )

class Dog:
    name = "藏獒"
    age = 2
​
    def info(self, name):
        print(f"name信息->{name}")
​
    # 静态方法
    @staticmethod
    def ok():
        print("ok()...")
​
dog = Dog()
dog.info("德牧")  #name信息->德牧
Dog.ok()  #ok()...

Python一切皆为对象,所有对象都有一个布尔值,通过内置函数boo()可以获取对象的布尔值。 下面对象的布尔值为False 1、False 2、数值0 3、None 4、空字符串 5、空列表 6、空字典 7、空元组 8、空集合

构造方法:

  • 基本介绍:

def _ _ init _ _ (self,参数列表): ​ 代码

  • 在初始化对象时,会自动执行 _ _ init _ _ 方法.

  • 在初始化对象时,将传入的参数,自动传递给 _ _ init _ _ 方法.

  • 一个类只有一个 _ _ init _ _ 方法,即使你写了多个,也只有最后一个生效

  • Python支特动动态生成对象属性。

class Person:
    def __init__(self, name, age):
        print(f"-_init-执行了..得到了{name}{age}")
        # 将接收到的name和age赋给当前对象name和age属性
        # Python支特动,态生成对象属性
        self.name = name
        self.age = age
p1 = Person("tim", 30)
print(f"p1 name={p1.name}age={p1.age}")  # tim
  • Python也支持对象动态的添加方法。但添加的方法指针都当前对象。

class Person:
    a = 1
    b = 3
def hi():
    print("hi...".center(30,"-"))
​
p = Person()
p.m1 = hi()
p.m1   #------------hi...-------------
  • 构造方法不能有返回值,比如,返回字符串,会报"TypeError: _ _ init _ _ ( ) should return None,not'str"

面向对象编程有三大特征:封装、继承和多态

封装:

默认情况下,类中的变量和方法都是公有的,它们的名称前都没有下划线。 公共的变量和方法,在类的外部、类的内部,都可以正常访问。

私有属性/私有方法:类中的变量或方法以双下划线 _ _ 开头命名,则该变量或方法为私有的,私有的变量或方法,只能在本类内部使用,类的外部无法使用。 访问私有的属性/方法:提供公共的方法,用于对私有成员的操作

Python语言的动态特性,会出现伪私有属性的情况。

继承:

  • python支持多重继承。Object是所以其他类的基类

  • 在多重继承中,如果有同名的成员,遵守从左到右的继承优先级(即:写左边的父类优先级高,写在右边的父类优先级低)

  • 如果子类和父类出现同名的成员,可以通过父类名、super()访问父类的成员

1)访问父类成员方式1

访问成员变量:父类名.成员变量 ​ 访问成员方法:父类名.成员方法(self) , 这是在子类中调用父类的成员方法,因此可以传self,并且self不能少,因为是通过父类名访问的。

2)访问父类成员方式2 ​ 访问成员变量:super().成员变量 ​ 访问成员方法:super().成员方法()

例:

class A:
    n1 = 100
​
    def run(self):
        print("A-run()....")
​
class B(A):
    n1 = 20
​
    def run(self):
        print(f"B-run()...")
​
    def say(self):
        print(f"父类的n1:{A.n1}本类的n1:{self.n1}")
        # 调用父类的尔Un
        A.run(self)
        self.run()
​
    def hi(self):
        print(f"父类的n1{super().n1}")
        # 调用父类的rUn
        super().run()
​
b = B()
b.say()
​

  • 访问不限于直接父类,而是建立从子类向上级父类的查找关系A->B>C.

类型注解:

作用和用法

  • 类型提示,防止运行时出现参数类型、返回值类型、变量类型不符合。

  • 作为开发文档附加说明,方便使用者调用时传入和返回参数类型。

  • 加入后并不会影响程序的运行,不会报正式的错误,只有提醒。

  • PyCharm支持类型注解,参数类型错误会黄色提示。

1、变量的类型注解:

变量名 : 变量类型 = 变量值

2、函数的类型注解:

def 函数/方法名(形参名:类型,形参名:类型..)->返回值类型: ​ 函数/方法体

3、注释中使用注解基本语法: #type : 类型

n1:int = 10 
n2:float = 10.1  
#在注释中使用注解基本语法:
n3 = 89.9 #type:float

类型注解是提示性的,并不是强制性的,如果你给的类型和指定/标注的类型不一致,PyCharm检测到会给出黄色警告,但是仍然可以运行。

Union类型:

typing.Union 联合类型:Union[X,Y,...]等价于X|Y,意味着满足X或Y之一。X、Y、Z...可以有参数。

1)Union类型可以定义联合类型注解 2)在变量、函数(方法)都可以使用Union联合类型注解 3)使用的时候,需要先导入Union : from typing import Union

#联合类型注解,a可以是int或者stn
a:Union[int,str] = 1.2
#my_List是List类型,元素可以是int或者str
my_list:list[Union[int,str]] = [100,200,300,"tim"]

多态:

一个父类,具有多个子类,不同的子类对象调用相同的方法,执行的时候产生不同的状态,就是多态。

但是:

  • Python中函数/方法的参数是没有类型限制的,所以多态在python中的体现并不是很严谨(比如:和java等强类型语言比),所以说python天生就是多态的。

  • Python并不要求严格的继承体系,关注的不是对象的类型本身,而是它是否具有要调用的方法(行为)

class AA:
    def hi(self):
        print("AA-hi()...")
class BB:
    def hi(self):
        print("BB-hi()...")
def test(obj:object):
    obj.hi()
aa = AA()
bb = BB()
test(aa)
  • 当调用对象成员的时候,会和对象本身动态关联

class A:
    i=10
    #self指的是对象本身,而不是类本身,所以b.sum()对象为b,self也为b,调用的是B类中的i
    def sum(self):
        return self.getI() + 10
    def getI(self):
        return self.i
​
class B(A):
    i=20
    # def sum(self):
    #     return self.i+20
    def getI(self):
        return self.i
    def sum1(self):
        return self.i+10
​
b = B()
print(b.sum())
print(b.getI())

isinstance函数

  • 基本说明:isinstance( ) 用于判断对象是否为某个类或其子类的对象

  • 基本语法:isinstance(object , classinfo) ,其中:object:对象,classinfo:可以是类名、基本类型或者由它们组成的元组

魔术方法:

  • 在Python中,所有以双下划线包起来的方法,统称为Magic Method(魔术方法),它是一种的特殊方法,普通

    方法需要调用,而魔术方法不需要调用就可以自动执行。

  • 魔术方法在类或对象的某些事件发生时会自动执行,让类具有神奇的"魔力"。如果希望根据自己的程序定制特殊功能的类,那么就需要对这些方法进行重写。

  • Python中常用的运算符、for循环、以及类操作等都是运行在魔术方法之上的。

魔术方法操作
_ _ init _ _初始化对象的成员
_ _ str_ _(self)定义对象转字符串行为:print(对象)或者str(对象)
_ _ eq_ _(self,other)定义等于号的行为:x==y
_ _ It_ _(self,other)定义小于号的行为:x<y
_ _ Ie_ _(self,other)定义小于等于号的行为:x<=y
_ _ ne_ _(self,other定义不等号的行为:x!=y
_ _ gt _ _(self,other)定义大于号的行为:x>y
_ _ ge _ _(self,other)定义大于等于号的行为:x>=y

Class对象:

类本身也是对象,即:class对象,不实例化也存在。

  1. 通过类名去调用属性时,可以直接:类名 . 属性名

  2. 通过类名去调用非静态方法时,需要传入类型:类名 . 方法名(类名),因为类本身就是对象,通过这种方法,把类名传给了self对象。但当我们通过对象调用方法时,self会隐式的传入。

  3. 通过类名去调用静态方法时,可以直接调用:类名 . 方法名 或 实例对象名 . 方法名。

抽象类:

当父类的一些方法不能确定时,可以使用@abstractmethod声明(说明:@abstractmethod用于声明抽象方法的 装饰器),同时继承ABC类,那么这个类就是抽象类。

抽象类(含抽象方法)不能实例化

抽象类需要继承ABC类 , 至少含有一个抽象方法。

抽象类可以有普通方法。

如果一个类继承了抽象类,则它必须实现抽象类的所有抽象厅法,否则它仍然是一个抽象类

模板设计模式:

基本介绍: 抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。 模板设计模式能解决的问题: 当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。

例题:

原方案:

模板设计改进方案:

import time
from abc import ABC, abstractmethod
class Template(ABC):
    @abstractmethod
    def job(self):
        pass
    def cal_time(self):
        start = time.time() * 1000
        num =0
        self.job()
        end = time.time() * 1000
        print(f"任务所需毫秒:{end-start}")
class AA(Template):
    def job(self):
        num= 1
        for i in range(1,900001):
            num += i
class BB(Template):
    def job(self):
        num= 1
        for i in range(1,900001):
            num -= i
if __name__=="__main__":
    aa =AA()
    aa.cal_time()
    bb=BB()
    bb.cal_time()

异常:

异常介绍

try:

可能出现异常的代码 except [ 异常 as 别名 ] : ​ 发生异常时,对异常处理的代码 [ else ] : ​ 没有发生异常,执行的代码 [finally] : ​ 不管有没有异常,都要执行的代码

  • 如果异常发生了,则异常发生后面的代码不会执衍,直接进入到except子句,如果异常没有发生,则不会进入except子句。

  • 可以有多个except子句,捕获不同的异常(进行不同的业务处理),如果发生异常,只会匹配一个except,建议把具体的异常写在前面,基类异常在后,比如(IndexError在前,Exception在后),这样当具体异常匹配不到时,再由基类异常匹配。

触发异常

raise语句支持强制触发指定的异常。

try:
    '''
    1、raise:用于主动的触发异常
    2.ZeroDivisionError:程序员指定的异常,可以根据需要指定
    3."主动触发ZeroDivisionError异常”是指定的异常信息
    '''
    raise ZeroDivisionError("主动触发ZeroDivisionError异常")
except ZeroDivisionError as e:
    print(f"{e}  类型->{type(e)}")

异常的传递:

自定义异常:

1、程序可以通过创建新的异常类命名自己的异常。不论是以直接还是间接的方式,异常都应从Exception类派生。 2、异常类通常应当保持简单,它往往只提供一些属性,允许相应的异常处理程序提取有关错误的信息。 3、大多数异常命名都以"Ero"结尾,类似标准异常的命名,但是需要注意不要使用内置异常名。

class AgeError(Exception):
    pass
while True:
    try:
        age=int(input("请输入年龄(18-120):"))
        if not(18<=age<=120):
            raise AgeError("年龄需要在18-120之间")
        break
    except ValueError as e:
        print("你输入的不是整数")
    except AgeError as e:
        print (e)
print(f"你输入的age:{age}")

文件:

I/O类型 1、Python用于处理各种I/O类型(Input/Output类型),主要的I/O类型分别为:文本I/O,二进制I/O,也分 别对应处理的文件对象类别:文本文件、二进制文件。 2、文本文件:通常是记事本可以直接打开的,比如 . py 、. txt等文件 3、二进制文件:比如图片、视频、音频等 4、在处理不同类型的文件时,需要用对应的方式打开处理

文件常用操作:

函数介绍
open(file,mode='r',encoding=None)1)打开file并返回对应的file object。如果该文件不能被打开,则引发OSError 2)file表示将要打开的文件的路径(绝对路径或者相对当前工作目录的路径) 3)mode是文件打开的模式,如果是‘w’则为写,如果文件不存在,则自动创建(前提是当前目录存在) ,‘a’打开文件用于写入,如果存在则末尾追加
f.read(size)可用于读取文件内容,它会读取一些数据,并返回字符串(文本模式),或字节串对象(在二进制模式下)。size是可选的数值参数。省略size或size为负数时,读取并返回整个文件的内容。
f.readline()从文件中读取单行数据;字符串末尾保留换行符(\ n)
Iist(f) 或f.readlines()以列表形式读取文件中的所有行
for line in f :从文件中读取多行时,可以用循环遍历整个文件对象。这种操作能高效利用内存,快速,且代码简单
f.write(string)把string的内容写入文件,并返回写入的字符数
f.flush()刷新流的写入缓冲区。调用f.wite(),内容并没有真正写入到文件,而是先积攒到缓存区,当调用flush()时,内容才会真正写入到文件
f.close()刷新并关闭此流,内置了flush方法。即可释放文件占用的系统资源,如果文件已经关闭,则此方法无效。文件关闭后,对文件的任何操作(例如读取或写入)都会引发ValueError
with open( ) as f :在处理文件对象时,最好使用wth关键字。优点是,子句体结束后,文件会自动关闭
os.path.exists(path)如果path指向一个已存在的路径或已打开的文件描述符,返回True。对于失效的符号链接,返回False
os.remove(path)删除文件
os.stat(path)获取文件的信息,如大小,最新访问时间,创建时间等
os.listdir(path)获取文件夹所以得内容
文件分隔符关于目录分隔符号,在windows下/和//都可以,比如"d://aaa//bbb//hi.txt"

目录常见操作:

函数操作
os.mkdir(path,mode=00777)创建一个名为path的目录,应用以数字表示的权限模式mode。
os.makedirs(name,mode=00777)递归目录创建函数。与机dir()类似,但会自动创建到达最后一级目录所需要的中间目录。
os.rmdir(path)删除单级目录
os.removedirs(name)递归删除多级目录
os.path.isdir(path)判断目录是否存在

实例:

递归调用文件目录:

import os
​
def print_dir_all_content(dir_path):
    #获取文件夹(目录)的所有内容(元素)
    content_list = os.listdir(dir_path)
    #遍历content_list,输出对应的信息
    for ele in content_list:
        chid_ele=dir_path + "/" + ele
        if os.path.isdir(chid_ele):
            print(f"目录:{chid_ele}")
            #递归的操作
            print_dir_all_content(chid_ele)
        else:
            print(f"文件:{chid_ele}")
​
print_dir_all_content("E:\深度学习")

pyecharts:

pyecharts介绍:

pyecharts - A Python Echarts Plotting Library built with love.

pyecharts实例:

中文简介 - Document

实例:2014-2023年直辖市折现统计图

from pyecharts.charts import Line
import pyecharts.options as opts
line = Line()
​
#准备x轴数据
#数据可以在https://data.stats.gov.cn/easyquery.htm?cn=E0103下载
f = open("分省年度数据.csv","r",encoding="gbk")
line_datas = f.readlines()
f.close()
for _ in range(3):
    line_datas.pop(0)
x_data = line_datas[0].replace("\n","").split(",")
x_data.pop(0)
x_data.reverse()
# print(x_data)
​
y_data_beijing = []
y_data_chongqing = []
y_data_shanghai = []
y_data_tianjin = []
​
#准备y轴数据
line_datas.pop(0)
print(line_datas)
for line_data in line_datas:
    line_data = line_data.replace("\n","").split(",")
    city = line_data.pop(0)
    line_data.reverse()
    if "北京" in city:
        y_data_beijing = line_data
    if "天津" in city:
        y_data_tianjin = line_data
    if "重庆" in city:
        y_data_chongqing = line_data
    if "上海" in city:
        y_data_shanghai = line_data
print(y_data_beijing)
print(y_data_shanghai)
​
#给echarts添加x,y轴数据
line.add_xaxis(x_data)
line.add_yaxis("北京市历年人口",y_data_beijing,label_opts=opts.LabelOpts(is_show=False))
line.add_yaxis("上海市历年人口",y_data_shanghai,label_opts=opts.LabelOpts(is_show=False))
line.add_yaxis("重庆市历年人口",y_data_chongqing,label_opts=opts.LabelOpts(is_show=False))
line.add_yaxis("天津市历年人口",y_data_tianjin,label_opts=opts.LabelOpts(is_show=False))
​
#设置全局配置项
line.set_global_opts(title_opts=opts.TitleOpts(title="2014-2023年直辖市折现统计图",pos_left="center",pos_bottom="1%"))
line.render("line_4city_population.html")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值