目录
Python基础知识
(一)~(九)上一篇
(十)函数
1、声明函数
#格式
def 函数名(参数):
函数体
return 返回值
2、具体示例
#空函数--> def 函数名():pass
def k_empty():
pass
#无返回值
def k_print(year):
print('2023',year)
#有返回值
def k_return(x,y):
k = x + y
return k
#不定长参数,不确定参数个数时使用--> def 函数名(*参数名):函数体
def k_len(*z):
for p in z:
print(p)
#匿名参数--> lambda 参数 :表达式
name = lambda i,j:i-j
#调用函数
h = name(2,1)
print(h)
k_len(1,2,3,4)
(十一)模块与包
1、模块与包
以 .py 结尾的文件就是一个模块,模块中定义了变量、函数等来实现一些功能。Python有很多自带的模块(标准库)和第三方模块,一个模块可以被其他模块引用,实现了代码的复用性;包是存放模块的文件夹。
2、引用
#格式
import 包名1.包名2…模块
from 包名1.包名2... import 模块名
from 包名1.包名2...模块名 import 变量名/函数名
(十二)面向对象
1、回顾
(1)相关概念
• 类:描述具有相同属性和方法的集合,用它来创建对象。
• 对象:类的实例。
• 方法:类中定义的函数。
• 类变量:定义在类中且在函数之外的变量,在所有实例化对象中公用。
• 局部变量:定义在方法中的变量,只能用于当前实例。
(2)三大特性
• 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式,提高复用性和安全性。
• 继承:一个类继承一个基类便可拥有基类的属性和方法,可提高代码的复用性。
• 多态:父类定义的引用变量可以指向子类的实例对象,提高了程序的拓展性。
2、类
class 类名:属性 方法
(1)构造方法
构造方法__init__() 会在类实例化时自动调用。无论构造方法还是其他方法都需要将 self 作为第一个参数,它代表类的实例,让实例能够访问类中的属性和方法。
注:init别写错了,是init不是int。
(2)类的属性、方法
类创建好后可以直接通过类名访问属性(类名.属性名)。在类中可以定义私有属性和方法,即在属性名或方法名前加两条下划线(__id=‘1’)。
class User():
#定义类
def __init__(self,first_name,last_name,gender,age):
#初始化属性name、gender、age
self.name = first_name.title()+''+last_name.title()
self.gender = gender
self.age = age
#定义方法
def hello(self):
print("Hello,"+self.name+".")
#实例化
user1 = User('huang','xiao','woman',23)
#访问实例的属性
print('name:'+user1.name)
print('gender:'+user1.gender)
print('age:'+str(user1.age))
#调用方法
user1.hello()
#创建多个实例
user2 = User('xiao','li','man',20)
#1、给属性指定默认值,在init()方法中指定了初始值的,那在后面括号中就无需包含形参
class User():
def __init__(self, first_name, last_name, gender, age):
#初始化属性name、gender、age
self.name = first_name.title()+''+last_name.title()
self.gender = gender
self.age = age
self.login = 0
def print_login(self):
print('login是'+str(self.login))
user1 = User("hao","re",'man',30)
print('name:'+user1.name)
print('gender:'+user1.gender)
print('age:'+str(user1.age))
print('login:'+str(user1.login))
user1.print_login()
#2、修改属性值
class User():
def __init__(self, first_name, last_name, gender, age):
#初始化属性name、gender、age
self.name = first_name.title()+''+last_name.title()
self.gender = gender
self.age = age
self.login = 0
def print_login(self):
print('login是'+str(self.login))
def update_login(self,value):
self.login = value
print('login更改后是'+str(self.login))
user1 = User("hao","re",'man',30)
print('name:'+user1.name)
print('gender:'+user1.gender)
print('age:'+str(user1.age))
print('login:'+str(user1.login))
user1.login = 10 #直接通过实例修改默认值
user1.print_login()
user1.update_login(20) #调用方法更改默认值
(3)类的实例化(创建对象)
创建对象后,就可以使用它的访问属性和调用方法。
(4)类的继承
支持多继承,格式为class 基类(子类1, 子类2 …):。举例单继承,还有多继承。
#继承
class User():
#定义类
def __init__(self,first_name,last_name,gender,age):
#初始化属性name、gender、age
self.name = first_name.title()+''+last_name.title()
self.gender = gender
self.age = age
#定义方法
def hello(self):
print("Hello,"+self.name+".")
#定义子类继承父类User
class Admin(User):
def __init__(self,first_name,last_name,gender,age):
#初始化父类属性
super().__init__(first_name,last_name,gender,age)
#可以添加子类特有属性
self.identity = 'admin'
#添加子类特有方法
def hello_admin(self):
print("Welcome to login "+self.name)
admin1 = Admin("hang",'zhou','women',40)
admin1.hello() #调用子类继承父类的方法
admin1.hello_admin() #调用子类特有的方法
(5)重写父类
对于父类的方法,只要它不符合子类的要求,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
#重写
class User():
#定义类
def __init__(self,first_name,last_name,gender,age):
#初始化属性name、gender、age
self.name = first_name.title()+''+last_name.title()
self.gender = gender
self.age = age
#定义方法
def hello(self):
print("Hello,"+self.name+".")
def desc(self):
print('This is '+self.name)
#定义子类继承父类User
class Admin(User):
def __init__(self,first_name,last_name,gender,age):
#初始化父类属性
super().__init__(first_name,last_name,gender,age)
#可以添加子类特有属性
self.identity = 'admin'
#添加子类特有方法
def hello_admin(self):
print("Welcome to login "+self.name)
#重写父类方法desc
def desc(self):
print('This is '+self.name+' and '+str(self.age))
admin1 = Admin("hang",'zhou','women',40)
admin1.desc()
(十三)时间
1、time模块
(1)struct_time类,代表一个时间对象,可以通过索引和属性名访问值。
#localtime()表示当前时间,返回类型为struct_time对象
import time
t = time.localtime()
print('struct_time:', t)
print('year:', t.tm_year)
print('year:>', t[0])
(2)常用函数。
2、datetime模块
datatime模块重新封装了 time 模块,提供了更多接口,变得更加直观和易于调用。
(1)date类:表示一个由年月日组成的日期,格式为datetime.date(year,month,day)。
import datetime
import time
print(datetime.date.today())
print(datetime.date.fromtimestamp(time.time()))
print(datetime.date.min)
print(datetime.date.max)
import datetime
td = datetime.date.today()
print(td.replace(year=1945, month=8, day=15))
print(td.timetuple())
print(td.weekday())
print(td.isoweekday())
print(td.isocalendar())
print(td.isoformat())
print(td.strftime('%Y %m %d %H:%M:%S %f'))
print(td.year)
print(td.month)
print(td.day)
(2)time类:表示由时、分、秒、微秒组成的时间,格式为:time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)。
import datetime
t = datetime.time(10, 10, 10)
print(t.isoformat())
print(t.replace(hour=9, minute=9))
print(t.strftime('%I:%M:%S %p'))
print(t.hour)
print(t.minute)
print(t.second)
print(t.microsecond)
print(t.tzinfo)
(3)datetime类:包括了 date 与 time 的所有信息,格式为:datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)。
3、calendar模块
处理日历的函数。
(1)常用函数。
import calendar
calendar.setfirstweekday(1)
print(calendar.firstweekday())
print(calendar.isleap(2023))
print(calendar.leapdays(1945, 2023))
print(calendar.weekday(2023, 12, 1))
print(calendar.monthrange(2023, 12))
print(calendar.month(2023, 12))
print(calendar.prcal(2023))
(2)Calendar类:Calendar 对象提供了一些日历数据格式化的方法。
from calendar import Calendar
c = Calendar()
print(list(c.iterweekdays()))
for i in c.itermonthdates(2023, 12):
print(i)
(3)TextCalendar类:为 Calendar子类,用来生成纯文本日历。
from calendar import TextCalendar
tc = TextCalendar()
print(tc.formatmonth(2023, 4))
print(tc.formatyear(2023))
(4)HTMLCalendar类:生成HTML日历。
(十四)文件基本操作
1、创建
使用open()函数创建或打开文件,格式open(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)。
• file:将要打开的文件的路径或被封装的整数类型文件描述符。
• mode:一个可选字符串,默认为r,可选如下。
• buffering:是一个可选的整数,用于设置缓冲策略。
• encoding:用于解码或编码文件的编码的名称。
• errors:是一个可选的字符串,用于指定如何处理编码和解码错误(不能在二进制模式下使用)。
• newline:区分换行符。
• closefd:如果 closefd 为 False 并且给出了文件描述符而不是文件名,那么当文件关闭时,底层文件描述符将保持打开状态;如果给出文件名,closefd 为 True (默认值),否则将引发错误。
• opener:可以通过传递可调用的 opener 来使用自定义开启器。
2、写入
t = open('test.txt', mode='w',encoding='utf-8')
t.write('huang\n')
t.close()
#可以用with as语句,执行完成后会自动关闭已经打开的文件。
with open('test.txt',mode='w',encoding='utf-8') as t:
t.write('huang\n')
3、读取
with open('test.txt','r',encoding='utf-8') as t:
print(t.read(2))
4、定位
5、其他
isatty()、truncate()等,略。
(十五)OS模块
os 模块提供了各种操作系统的接口,这些接口主要是用来操作文件和目录。Python中所有依赖于操作系统的内置模块统一设计方式为:对于不同操作系统可用的相同功能使用相同的接口,这样大大增加了代码的可移植性。
import os
import datetime
print(os.getcwd()) #查看当前路径
print(os.listdir('E:/')) #返回指定目录下包含的文件和目录名列表
print(os.path.abspath('.')) #返回路径的绝对路径
print(os.path.split('E:/test.bin')) #将路径拆为目录和文件两部分,返回结果为元组类型
print(os.path.join('E:/','tmp.txt')) #将一个或多个path进行拼接
print(datetime.datetime.utcfromtimestamp(os.path.getmtime('E:/test.bin'))) #返回path的最后修改时间
print(datetime.datetime.utcfromtimestamp(os.path.getatime('E:/test.bin'))) #返回path的最后访问时间
print(os.path.exists('E:/test.bin')) #判断path是否存在,存在true,否则false
print(os.path.isdir('E:/test.bin')) #判断path是否为目录
print(os.path.isfile('E:/test.bin')) #判断path是否为文件
print(os.path.getsize('E:/test.bin')) #返回path的大小,以字节为单位,若是目录则返回0
print(os.mkdir('E:/test2.bin')) #创建一个目录
print(os.makedirs('E:/tt/t')) #创建多级目录,tt、t均不存在使用mkdir会报错
#print(os.chdir('/test')) #更改当前工作目录
print(os.system('ping www.baidu,com')) #调用shell脚本
(十六)错误和异常
1、错误
通常是语法错误、逻辑错误等。
2、异常
BaseException为所有异常类的基类,下面又分为四大类;Exception为所有非系统退出类异常的基类,下面包括常见的:MemoryError(内存溢出)、BlockingIOError(IO异常)、SyntaxError(语法错误异常)等。
3、异常处理
(1)举例,被除数为0时,未捕获异常。
(2)捕获异常。try/except语句,还有else(出现在except子句后,只有在没有出现异常时执行)、finally(放在最后,无论是否有异常都会执行)。
#2、捕获异常
def getNum(n):
try:
return 10 / n
except IOError:
print('IOError')
except ZeroDivisionError:
print("ZeroDivisionError")
print(getNum(0))
(3)抛出异常。使用raise语句强制抛出一个指令的异常。
(4)自定义异常,了解一下。
(十七)枚举
枚举就有不可变的特性,所以枚举的主要作用就是用来定义常量的。
from enum import Enum,unique
#枚举通过继承Enum的方式来定义
class WeekDay(Enum):
Mon = 0
Tue = 1
Wed = 2
print(WeekDay.Mon) #枚举成员
print(WeekDay.Mon.name) #枚举成员名称
print(WeekDay.Mon.value) #枚举成员值
#枚举的迭代1
for day in WeekDay:
print(day)
print(day.name)
print(day.value)
#枚举的迭代2
print(list(WeekDay))
#枚举的比较,枚举成员及属性可以使用is进行对象比较,或==进行值比较
print(WeekDay.Mon is WeekDay.Tue)
print(WeekDay.Mon == WeekDay.Mon)
#枚举成员不能进行大小比较 WeekDay.Mon<WeekDay.Thu错误返回Type Error
#确保枚举成员值唯一,通过装饰器@unique来实现
#from enum import Enum,unique
@unique
class Week(Enum):
M = 0
T = 1
(十八)迭代器与生成器
for循环来遍历,遍历的过程就是迭代。
for I in 'huang':
print(i)
1、可迭代对象
可迭代对象需有__iter__()方法,它们均可使用for循环遍历;可以使用isinstance()方法来判断一个对象是否为可迭代对象。
from collections.abc import Iterable
print(isinstance('huang',Iterable))
print(isinstance([1,2,3],Iterable))
print(isinstance(1,Iterable))
2、迭代器
迭代器需要__iter__()(返回迭代器对象本身)和__next__()(返回下一项数据)两个方法,这两个方法组成了迭代器协议。迭代器对象本质是一个数据流,它不断调用返回下一项数据,当没有下一项数据时抛出StopIteration异常迭代结束。
#实现迭代器
class MyIterator:
def __init__(self):
self.s = '天气晴'
self.i = 0
def __iter__(self): #返回迭代器对象本身
return self
def __next__(self): #返回下一项数据
if self.i < 3:
n = self.s[self.i]
self.i += 1
return n
else:
raise StopIteration
my_iter= iter(MyIterator())
for i in my_iter:
print(i)
3、生成器
生成器(一边循环一边计算的机制称为生成器,有利于减小服务器资源)是用来创建迭代器的工具,写法和标准函数相似,不同之处在于返回时使用了yield语句。yield是一个关键字,作用和return差不多,但yield返回的是一个生成器。
#创建生成器1
def reverse(data):
for i in range(len(data)-1,-1,-1):
yield data[i]
for char in reverse('Huang'):
print(char)
#创建生成器2
#列表
l = [x*x for x in range(5)]
print(l)
#生成器
g = (x*x for x in range(5))
for s in g:
print(s)
(十九)装饰器
1、闭包
简单理解,调用一个带有返回值的函数x,会返回一个函数y,则函数y称为闭包。闭包和类有些相似,都能实现数据封装、方法复用等;闭包还可以避免使用全局变量等。
2、装饰器
也称装饰函数,是闭包的应用,主要用于某些函数需要拓展功能但又不希望修改原函数。装饰器可以基于函数、类实现。
#基于函数的
#装饰函数
def funA(fun):
def funB(*args,**kw):
print('开始',fun.__name__)
fun(*args,**kw)
print('结束',fun.__name__)
return funB
@funA
#业务函数
def funC(name):
print('hello',name)
funC('huang')
#基于类
class Test(object):
def __init__(self, func):
print('函数名是 %s ' % func.__name__)
self.__func = func
def __call__(self, *args, **kwargs):
self.__func()
@Test
def hello():
print('Hello ...')
hello()
(二十)命名空间与作用域
1、命名空间概念
命名空间是名称到对象的映射,大部分命名空间是通过Python字典来实现的,是用于避免项目中的名字冲突,每个命名空间相对独立。
2、命名空间种类和生命周期
(1)内置:内置函数、异常等,如abs函数、BaseException异常。在Python解释器启动时创建,退出时销毁。
(2)全局:模块中定义的名称,如类、函数等。在模块定义被读入时创建,在Python解释器退出时销毁。
(3)局部:函数中定义的名称。对于类:在Python解释器督导类定义时创建,类定义结束后销毁;对于函数:函数被调用时创建,函数执行完成或出现未捕获异常时销毁。
3、作用域概念
Python程序可以直接访问命名空间的文本区域,名称的非限定引用会尝试在命名空间中查找名称,作用域是静态的,命名空间是随着解释器的执行动态产生的,因此在作用域中访问命名空间中的名字具有动态性,即作用域被静态确定,被动态使用。
4、作用域种类
(1)局部:最先被搜索的最内部作用域(局部名称)。
(2)嵌套:根据嵌套层次由内向外搜索(非全局、非局部名称)。
(3)全局:倒数第二个被搜索(当前模块的全局名称)。
(4)内建:最后被搜索(内置名称的命名空间)。
搜索顺序:局部、嵌套、全局、内建。
# 全局作用域
g = 1
def outer():
# 嵌套作用域
e = 2
def inner():
# 局部作用域
i = 3
5、全局变量、局部变量
(1)全局变量是定义在函数外部的变量,可以在整个程序范围内进行访问。局部变量是定义在函数内部的变量,可以在函数内进行访问。
a = 0 #全局变量
print('a为',a)
def sub(i,j)
b = i-j #局部变量
print('b为',b)
sub(3,1)
(2)global和nonlocal关键字。
b = 0 #全局变量
print('b1为',a)
def sub(i,j)
global b #修改函数中的变量为全局变量,使用global声明为全局变量
b = i-j
print('b2为',b)
sub(3,1)
print('b3为',a)
#result-->0,2,2
def outer():
d = 1
def inner():
nonlocal d #修改嵌套作用域中的变量
d = 2
print('inner:', d)
inner()
print('outer:', d)
outer()
#result-->2 2
(二十一)数学模块
1、math模块
import math
a = 1.5
print(math.ceil(a)) #返回a的向上取整,大于或等于x的最小整数 2
b = 1.5
print(math.floor(b)) #返回b的向下取整,小于或等于x的最大整数 1
c = -1
print(math.fabs(c)) #返回c的绝对值 1.0
d = 3
e =2
print(math.fmod(d,e)) #返回d/e的余数,值为浮点数 1.0
f = 3
print(math.factorial(3)) #返回f的阶乘,若f不为整数或为附属将引发ValueError 6
g = 3
h = 2
print(math.pow(g,h)) #返回g的h次幂 9.0
print(math.fsum((1,2,3))) #返回迭代器中所有元素的和 6.0
i = 9
j = 6
print(math.gcd(i,j)) #返回整数i、j的最大公约数 3
k = 144
print(math.sqrt(k)) #返回k的平方根 12.0
l = 14.4
print(math.trunc(l)) #返回l的整数部分 14
m = 2
print(math.exp(m)) #返回e的m次幂 7.38905609893065
n = 10
o = 10
print(math.log(n)) #返回x的对数,底数默认为e 2.302585092994046
print(math.log(n,o)) #返回x的对数,指定底数 1.0
print(math.e) #返回常量e 2.718281828459045
print(math.pi) #返回常量Π 3.141592653589793
#tan()、atan()、sin()、asin()、cos()、acos()等,略
2、decimal模块
decimal 模块为正确舍入十进制浮点运算提供了支持,相比内置的浮点类型 float,它能更加精确的控制精度。decimal 在一个独立的 context 下工作,可以使用 getcontext() 查看当前上下文。
import decimal
d1 = decimal.Decimal(1.1)
d2 = decimal.Decimal(9.9)
print(d1 + d2)
print(d1 - d2)
print(d1 * d2)
print(d1 / d2)
#result
#11.00000000000000044408920985
#-8.800000000000000266453525910
#10.89000000000000127009514017
#0.1111111111111111160952773272
3、random模块
import random
print(random.random()) #随机返回浮点数
print(random.uniform(1.1,9.9)) #返回[1.1,9.9)范围内随机浮点数
print(random.randint(1,15)) #返回[1,15]范围内的一个随机整数
print(random.randrange(1, 10))
print(random.randrange(1, 10, 2)) #返回[start, stop)范围内步长为step的一个随机整数
print(random.choice('123456')) #非空序列中随机返回一个元素
l = [1, 2, 3, 4, 5, 6] #将序列l随机打乱位置
random.shuffle(l)
print(l)
print(random.sample(l, 3)) #返回从总体序列或集合中选择的唯一元素的k长度列表,用于无重复的随机抽样
(二十二)Sys模块
1、概念
Sys模块和Python解释器进行交互,提供一系列用于控制Python运行环境的函数和变量。
2、使用
- argv,返回传递给Python脚本的命令行参数列表
- version,返回Python解释器的版本信息
- winver,返回Python解释器主版号
- platform,返回操作系统平台名称
- path,返回模块的搜索路径列表
- maxsize,返回支持的最大整数值
- maxunicode,返回支持的最大 Unicode 值
- copyright,返回 Python 版权信息
- modules,以字典类型返回系统导入的模块
- byteorder,返回本地字节规则的指示器
- executable,返回 Python 解释器所在路径
- stdout,标准输出
import sys
sys.stdout.write('Hi' + '\n') #Hi
print('Hi') #Hi
- stdin,标准输入
- stderr,错误输出
- exit(),退出当前程序
- getdefaultencoding(),返回当前默认字符串编码的名称
- getrefcount(obj),返回对象的引用计数
- getrecursionlimit(),返回支持的递归深度
- getsizeof(object[, default]),以字节为单位返回对象的大小
- setswitchinterval(interval),设置线程切换的时间间隔
- getswitchinterval(),返回线程切换时间间隔
(二十三)其他
1、argparse模块
argparse模块主要用于处理Python命令行参数和选项,程序定义好所需参数后,该模块会通过sys.argv解析出那些参数;argparse 模块还会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。
2、正则表达式
Python提供了内置模块re和第三方模块regex来支持正则表达式,regex模块提供了与re模块兼容的 API接口,同时还提供了额外的功能和更全面的Unicode支持。
字符 | 说明 |
---|---|
. | 默认情况,匹配除了换行的任意字符;如果指定了标签 DOTALL,则匹配包括换行符的任意字符 |
^ | 匹配字符串的开头,在 MULTILINE 模式也匹配换行后的首个符号 |
$ | 匹配字符串尾或者换行符的前一个字符,在 MULTILINE 模式匹配换行符的前一个字符 |
* | 匹配前一个字符 0 到无限次 |
+ | 匹配前一个字符 1 到无限次 |
? | 匹配前一个字符 0 次或 1 次 |
{m} | 匹配前一个字符 m 次 |
{m, n} | 匹配前一个字符 m 到 n 次 |
*? +? ?? {m,n}? | 使 *、+、?、{m,n} 变成非贪婪模式,也就是使这些匹配次数不定的表达式尽可能少的匹配 |
\ | 转义特殊字符 |
[...] | 用于表示一个字符集合 |
\\| | 匹配 \ |
(...) | 将括起来的表达式分组, |
(?aiLmsux) | aiLmsux 每一个字符代表一个匹配模式,可选多个 |
(?:…) | (…) 的不分组版本 |
(?P<name>…) | 分组,除了原有的编号外再指定一个额外的别名 |
(?P=name) | 引用别名为 name 的分组匹配到的字符串 |
(?#…) | # 后面的将作为注释被忽略 |
(?=…) | 匹配 … 的内容,但是并不消费样式的内容 |
(?!…) | 匹配 … 不符合的情况 |
(?<=…) | 匹配字符串的当前位置,它的前面匹配 … 的内容到当前位置 |
(?<!…) | 匹配当前位置之前不是 … 的样式 |
(?(id/name)yes-pattern\\|no-pattern) | 如果给定的 id 或 name 存在,将会尝试匹配 yes-pattern ,否则就尝试匹配 no-pattern,no-pattern 可选,也可以被忽略 |
\number | 匹配数字代表的组合 |
\A | 只匹配字符串开始 |
\b | 匹配空字符串,但只在单词开始或结尾的位置 |
\B | 匹配空字符串,但不能在词的开头或者结尾 |
\d | 主要匹配数字 [0-9] |
\D | 匹配任何非十进制数字的字符 |
\s | 匹配空白字符,主要包括:空格 \t \n \r \f \v |
\S | 匹配任何非空白字符 |
\w | 匹配 [a-zA-Z0-9_] |
\W | 匹配非单词字符 |
\Z | 只匹配字符串尾 |