声明:因个人能力有限,本文仅是个人的学习记录笔记,有错误之处还望指出
输出内容
输出地址(文件 \ 显示器)
# 显示器
print('hello world')
# 文件
# a+ : 如果文件不存在就创建文件,存在的话在文件内容后面追加
fp = open('D:/text.text','a+')
print('hello world',file=fp)
fp.close()
+ 转义字符首字母 \ + 转义字符首字母 +转义字符首字母
不希望字符串中的转义字符起作用(使用原字符),在字符前面加上 r\R 且最后一个字符不能是反斜杠
8 b i t = 1 b y t e 1024 b y t e = 1 K B 1024 k b = 1 M B 8bit = 1byte 1024byte = 1KB 1024kb = 1MB 8bit=1byte1024byte=1KB1024kb=1MB
保留字:被赋予了特定的意义,不能被使用(False ,None,and,as,assert,…)
标识符:变量,函数,类,模块起的名字
变量的定义和使用
变量由三部分组成
1. 标识:表示对象所存储的内存地址,使用内置函数 id(obj) 来获取
2. 类型:表示的是对象的数据类型,使用内置函数 type(obj) 来获取
3. 值 : 表示对象锁存储的具体数据,使用 print(obj) 将值进行打印
变量中存储的是标识的值(内存地址)
变量的多次赋值
多次赋值之后,变量会指向新的内存地址(标识)
常用的数据类型
进制 | 基本数 | 表现形式 |
---|---|---|
十 | 0~9 | 118 |
二 | 0,1 | 0b1110110 |
八 | 0~7 | 0o166 |
十六 | 0~9 A~F | 0x76 |
bool 值可以转化为整数 True \ False = 1 \ 0
当两个不同数据类型的时候,函数会报错
数据类型转换函数
函数名 | 作用 | 注意事项 | 例子 |
---|---|---|---|
str() | 将其他数据类型换成字 符串 | 也可用引号转换 | str (12) ‘12’ |
int() | 将其他数据类型换成整 数 | 文字类和小数类字符串,无 法转换 浮点数转化成整数,抹 零取整 | int(“123”) int(9.8) |
float() | 将其他数据类型函数 转成浮点数 | 文字类无法转换 整数转换成浮点数,末尾为0 | float(‘9.9’) float(9) |
# 作为单行注释
‘’’ ‘’‘’ 作为多行注释
中文编码声明注释:写在文件开头加上中文声明注释,用于指定源码文件的编码格式
#coding:gbk
接收用户的输入,输入的类型为 s t r str str
print('===输入函数的使用====')
name = input('你叫什么名字:')
print('\n', name, type(name))
# 从键盘获取两个整数并且计算和
print('\n', '===求和计算===')
num1 = input('数值a:')
num2 = input('数值b:')
print(num1, '+', num2, '=', int(num1)+int(num2))
算术运算符
运算符 | 表示 | 例子 | 结果 |
---|---|---|---|
+ | 加 | 1 + 1 1+1 1+1 | 2 2 2 |
- | 减 | 2 − 1 2-1 2−1 | 1 1 1 |
* | 乘 | 2*3 | 6 |
/ | 除 | 1/2 | 0.5 |
% | 取余(一正一负要公式) | 9%4 | 1 |
% | 余数=被除数 -除数 * 商 | 9%-4 9-(-4)*(-3) | -3 |
** | 幂运算 | 2**3 | 2^3=8 |
// | 整除(一正一负向下取整) | 11//2 | 5 |
// | 整除(一正一负向下取整) | 9//-4 | -3 |
// | 整除(一正一负向下取整) | -9//4 | -3 |
赋值运算符
比较运算符
布尔运算符
运算符 | 备注 |
---|---|
and | 同为True 才为True |
or | 有True 就True |
not | 相反 |
in | 在里面 |
not in | 不在里面 |
位运算符
运算符 | 说明 |
---|---|
位与 & | 对应数位都为 1 , 才为 1 |
位或 | | 对应位都为 0 , 才为0 |
左移位 << | 高位溢出舍弃,低位补 0(*2) |
右移位 >> | 低位溢出舍去 , 高位补 0(/2) |
运算符的优先级
算术运算 > 位运算 > 比较运算 > 布尔运算 > 赋值运算符
基本结构由顺序结构,选择结构,循环结构组成
顺序结构
没有选择和跳转的按先后顺序执行的结构
对象的布尔值
Python 中一切皆为对象,所有的对象都有一个布尔值,通过 内置函数 bool() 来获取
以下对象的布尔值为 False
单分支结构
中文语义 : 如果 … 就 …
语法结构 :
if 条件表达式 :
条件执行体
双分支结构
中文语义 : 如果 … 不满足 … 就 …
语法结构 :
if 条件表达式 :
条件执行体1
else :
条件执行体2
多分支结构
中文语义 :
语法结构 :
if 条件表达式 :
条件执行体1
elif :
条件执行体2
elif :
条件执行体N
else :
条件执行体 N+1
嵌套 if 的使用
语法结构 :
if 条件表达式1 :
if 内层条件表达式:
内层条件执行体1
else :
内层条件执行体2
else :
条件执行体
条件表达式
条件表达式是 if … else 的简写
pass 语句
pass 语句什么都不做, 只是应该占位符,用在语法需要的地方
反复的做同一件事情
语法结构:
while 条件表达式:
条件执行体(循环体)
选择结构的 if 与循环结构的 while 区别
for-in 循环
for-in 语法结构
for 自定义变量 in 可迭代对象:
循环体
循环体内不需要访问的自定义变量,可以将自定义变量替代为下划线
循环结构中又嵌套了另外完整的循环结构,其中内层循环做为外层循环的循环体执行
列表相当于 C 语言的数组,列表中存储的是列表对象的 id,列表对象存储的是列表元素的 id。
创建
特点
查询
获取列表指定元素索引(index())
获取列表中的单个元素
获取列表中的多个元素
列表名[start:stop:step]
列表元素的判断和遍历
列表元素的增加操作
方法 | 操作描述 |
---|---|
append() | 在列表的末尾添加一个元素 |
extend() | 在列表的末尾至少添加一个元素 |
insert() | 在列表的任意位置添加一个元素 |
切片 | 在列表的任意位置添加至少一个元素 |
列表元素的删除操作
方法 | 操作描述 | 操作对象 |
---|---|---|
remove() | 1. 一次删除一个元素 2. 重复元素只删除第一个 3. 不存在抛出 ValueError | 元 素值 |
pop() | 1. 删除一个指定索引上单元素 2. 指定索引不存在则抛出 IndexError 3. 不指定索 引,删除列表中的最后一个元素 | 索引值 |
切片 | 在列表的任意位置添加一个元素 | |
clear() | 清除列表 | 列表元素 |
del | 删除列表 | 列表 |
列表元素的修改操作
列表的排序操作
列表生成式
[item for item in range(start,stop)]
# 第一个 item 是用于标识元素值,可以自定义各个值之间的关系
字典 {}
# 每个键值对之间通过逗号隔开
scores={'jack':100,'Ryan':200}
字典的创建
字典中元素的获取
字典常用操作
del scores[‘张三’]
score[‘tom’]=100
score.clear()
获取字典视图的三个办法
字典元素的遍历
for item in scores:
print(item)
字典的特点
字典生成式
内置函数 zip()
item=['fruit','book','others']
price=[100,200,300]
lst=zip(item,price)
# 字典生成式
goods={item:price for item ,price in zip(item,price)}
元组 ()
可变序列和不可变序列
元组的创建的方式
t=(‘python’,100)
t=tuple((‘python’,100))
t=(10,)
元组的不可变序列原因
在多任务环境下,同时操作对象时不需要加锁(尽量使用不可变序列)
元组中存储的是对象的引用(id)
t=(10,[20,30]0,100)
print(t[0],type(t[0]),id(t0))
print(t[1],type(t[1]),id(t1))
print(t[2],type(t[2]),id(t2))
# 尝试将 t[1] 修改为 100
# t[1]=100 元组是不允许修改元素的
# 因为 t[1] 是列表,列表是可变序列,可以添加数据,且列表的内存地址不变
t[1].append(100) # 向列表中添加元素
元组的遍历
元组是可迭代对象,可以用 for-in 来遍历
d=(1,2,3,'hello','world')
for item in d
print(item)
s={‘python’,‘hello’,100}
s=set(range(11))
s=set()
in / not in
add() 一次添中一个元素
update() 一次至少添中一个元素
remove() 一次删除一个指定元素,如果指定元素不存在则抛出 KeyError
discard() 一次删除一个指定元素,如果指定的元素不存在你抛出异常
pop() 一次只删除一个任意的元素
clear() 清空集合
set_1 == set_2 / set_1 != set_2
set_1.issubset(set_2)
set_1.isuperset(set_2)
set_1.isdisjoint(set_2)
set_1 & set_2
set_1.intersection(set_2)
set_1.union(s2)
set_1 | set_2
set_1.difference(set_2)
set_1 - set_2
set_1.symmetric_difference(set_2)
set_1 ^ set_2
用于生成集合的公式
# 列表生成式
l=[item for item in range(1,11)]
print(l)
# 集合生成式
s=[item for item in range(1,11)]
print(s)
字符串
字符串是 Python 中的基本数据类型,是一个不可变字符序列
字符串的驻留机制
仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同的字符串时,不会开辟新的空间,而是把该字符串的地址赋给新创建的变量
字符串的查询操作方法
方法名称 | 作用 |
---|---|
index() | 查找字串 substr 第一次出现的位置,如果查找的字串不存在时,则抛出 ValueError |
rindex() | 查找字串 substr 最后一次出现的位置,如果查找的字串不存在时,则抛出 ValueError |
find() | 查找字串 substr 第一次出现的位置,如果查找的字串不存在时,则返回 -1 |
rfind() | 查找字串 substr 最后一次出现的位置,如果查找的字串不存在时,则返回 -1 |
字符串的大小写转换操作
方法名称 | 作用 |
---|---|
upper() | 把字符串中的所有字符转换成大写字符 |
lower() | 把字符串中的所有字符转换成小写字符 |
swapcase() | 把字符串中的所有小写字符转换成大写字符,大写字符转换成小写字符(所有字符都改变) |
capitalize | 把第一个字符转换为大写,其余字符转换为小写 |
title() | 把每个单词的第一个字符转化为大写,把每个单词的剩余字符转换为小写 |
字符串内容对齐的方法
方法名称 | 作用 |
---|---|
center() | 居中对齐,参数1:宽度、参数2:填充符(可选,默认是空格)。如果设置宽度小于实际宽度则返回原字符串 |
ljust() | 左对齐,参数1:宽度,参数2:填充符(可选,默认是空格)。如果设置宽度小于实际宽度则返回原字符串 |
rjust() | 右对齐,参数1:宽度,参数2:填充符(可选,默认是空格)。如果设置宽度小于实际宽度则返回原字符串 |
zfill() | 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定宽度小于等于字符串的长度,则返回字符串本身 |
字符串的劈分操作
方法名称 | 作用 |
---|---|
split() | 1. 从字符串的左侧开始劈分,默认的劈分字符是空格字符串,返回值都是一个列表 2. 通过参数 sep 指定劈分字符串的劈分符 3. 通过参数 maxsplit 来指定劈分字符串时的最大劈分次数,在经过最大次的劈分后,剩余的字串会单独作为一部分 |
rsplit() | 1. 从字符串的右侧开始劈分,默认的劈分字符是空格字符串,返回值都是一个列表 2. 通过参数 sep 指定劈分字符串的劈分符 3. 通过参数 maxsplit 来指定劈分字符串时的最大劈分次数,在经过最大次的劈分后,剩余的字串会单独作为一部分 |
字符串的判断方法
方法名称 | 说明 |
---|---|
isidentifier() | 判断字符串是否是合法字符 |
isspace() | 判断字符串是否全部由空白字符组成(回车、换行、水平制表符) |
isalpha() | 判断字符串是否全部由字母组成 |
isdecimal() | 判断字符串是否全部由十进制的数字组成 |
isnumeric() | 判断指定的字符串是否全部由数字组成 |
isalnum() | 判断指定字符串是否全部由字母数字组成 |
字符串的其他操作
功能 | 方法名称 | 作用 |
---|---|---|
字符串的替换 | replace() | 第一个参数指定被替换的字符串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第3个参数来指定最大替换次数 |
字符串的合并 | join() | 将列表或元组中的字符串合并成一个字符串 |
字符串的比较操作
> >= <= < == !=
字符串的切片操作
格式化字符串
‘我叫 %s,今年%d岁了’%(name,age)
‘我的名字叫:{0},今年{1}岁了,我的真名叫:{0}’.format(name,age)
f’我叫{name},今年{age}岁’
字符串的编码转换
函数的创建和调用
函数:执行特定功能的代码
函数的创建
def 函数名称 ([输入参数]):
函数体
[return xxx]
函数的参数传递
函数的返回值
函数的参数定义
函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
个数可变的位置参数(只能是一个)
def fun(*args):
print(args)
个数可变的关键字参数(只能是一个)
def fun(**args):
print(args)
既有关键字形参和位置形参时,要求位置形参放在关键字形参之前
函数参数的总结
参数类型 | 函数定义 | 函数的调用 | 备注 |
---|---|---|---|
位置实参 | √ | ||
将序列中的每个元素都转换为位置实参 | √ | 使用 * | |
关键字实参 | √ | ||
将字典中的每个键值对都转换为关键字实参 | √ | 使用 ** | |
默认形参 | √ | ||
关键字形参 | √ | 使用 * | |
个数可变的位置形参 | √ | 使用 * | |
个数可变的关键字形参 | √ | 使用 ** |
变量的作用域
递归函数
常见的 Bug 的类型
粗心导致的语法错误 SyntaxError
概念不清晰导致的问题
思路不清晰导致的 Bug
用户操作错误导致的 Bug
try :
可能会出现异常的代码
except XXX(异常类型):
异常处理代码
# 例子
try :
n1=int(input('输入一个数:'))
n2=int(input('输入另外一个数:'))
result = a/b
print('结果为:',result)
except ZeroDivisionError:
print("除数不允许为 0")
print('程序结束')
异常处理机制
# 例子
try :
n1=int(input('输入一个数:'))
n2=int(input('输入另外一个数:'))
result = a/b
except BaseException as e: # 异常取别名,进行输出
print("出错")
print(e)
else:
print('结果为:',result)
print('程序结束')
try … except … else … finally结构
finally 块无论是否发生异常都会被执行,能常用俩释放 try 块中申请的资源
# 例子
try :
n1=int(input('输入一个数:'))
n2=int(input('输入另外一个数:'))
result = a/b
except BaseException as e: # 异常取别名,进行输出
print("出错")
print(e)
else:
print('结果为:',result)
finally:
print('无论是否发生异常,总会被执行的代码')
print('程序结束')
常见的异常类型
异常类型 | 描述 |
---|---|
ZeroDivisionError | 除(或取模)零(所有数据类型) |
KeyError | 映射中没有这个键 |
SyntaxError | Python 语法错误 |
ValueError | 传入无效的参数 |
tarceback 模块的使用
提供 tracekace 模块来进行打印异常
import traceback
try:
print('---------')
print('10/0')
except:
traceback.print_exc()
两大编程思想
面向过程 | 面向对象 | |
---|---|---|
区别 | 事物比较简单,可以用线性思维解决 | 事物比较复杂,使用简单的线性思维无法解决 |
共同点 | 都是解决问题的一种思维方式 | 都是解决问题的一种思维方式 |
类与对象
类的创建
class Student: # Student 是类的名称
# 直接写在类里面的变量,称为类属性
native_pace = 'HongKong'
def __init__(self, name, age):
# self.name 称为实体属性,进行了一个赋值操作,将局部变量的name值赋给实体属性
self.name = name
self.age = age
# 实例方法
def eat(self):
print('i like eat watermelon')
# 静态方法
@staticmethod
def method():
print('i have used staticmethod ,so it is static method')
# 类方法
@classmethod
def cm(cls):
print('i have used staticmethod ,so it is class method ')
对象的创建(类的实例化)
语法:
实例名 = 类名()
# 例子
stu=Studnt('jack',20)
# 实例属性
print(stu.name)
# 实例属性
print(stu.age)
# 实例方法
stu.info()
意义:有了实例,可以调用类中的内容(相当于 C 中的结构体对象)
类属性,类方法,静态方法
类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
类方法:使用 @classmethod 修饰的方法,使用类名直接访问的方法
静态方法:使用 @staticmethod 修饰的方法,使用类名直接访问的方法
实例名 = 类名()
# 例子
stu=Studnt('jack',20)
# 访问类属性
print(Student,native_place)
# 调用类方法
Student.cm()
# 调用静态方法
Student.sm()
动态绑定属性和方法
Python是动态语言,在创建对象之后,可以动态的绑定属性和方法
def show():
print('我是函数,在绑定之后变为方法')
stu=Student('Jack',20)
# 动态绑定性别
stu.gender='Male'
#动态绑定方法
stu.show=show
# 调用方法
stu.show()
面向对象的三大特征
封装
class Student:
def __init__(self, age):
self.set_age(age)
def get_age(self):
# 仅限在类中使用(加了两个_)
return self.__age
def set_age(self, age):
if 0 <= age <= 120:
self.__age = age
else:
self.__age = 18
Stu1 = Student(150)
Stu2 = Student(15)
print(Stu1.get_age())
print(Stu2.get_age())
通过dir(实例名称)来查看可用的方法
print(stu.Student.__age)
继承
语法格式
class 子类类名(父类1,父类2...):
pass
代码实现
Student和Teacher 继承 Person
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
class Teacher(Person):
def __init__(self, name, age, teach_of_year):
super().__init__(name, age)
self.teach_of_year = teach_of_year
stu = Student('Jack', 100, 1001)
teacher = Teacher('Ryan', 42, 10)
stu.info()
teacher.info()
方法重写
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
def info(self):
super().info()
print('学号:', self.stu_no)
class Teacher(Person):
def __init__(self, name, age, teach_of_year):
super().__init__(name, age)
self.teach_of_year = teach_of_year
def info(self):
super().info()
print('教龄:', self.teach_of_year)
stu = Student('Jack', 100, 1001)
teacher = Teacher('Ryan', 42, 10)
print('====方法重写=====')
stu.info()
teacher.info()
object 类
class Pupil:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '我叫:{0},今年{1}岁'.format(self.name, self.age)
stu = Pupil('Jack', 20)
print(dir(stu))
print(stu) # 默认调用 __str__() 方法
print(type(stu))
多态
多态:具有多种形态;即便不知道一个变量所引用的对象是什么类型,仍然可以通过这个对象调用的方法,在运行过程中更具变量所引用对象的类型,动态的决定调用那个对象中的方法
class Animal(object):
def eat(self):
print('动物会吃')
class Dog(Animal):
def eat(self):
print('狗吃骨头...')
class Cat(Animal):
def eat(self):
print('猫吃鱼...')
class Person:
def eat(self):
print('人吃五谷杂粮...')
def fun(obj):
obj.eat()
# 开始调用
fun(Cat())
fun(Dog())
fun(Person())
特殊的方法和属性
名称 | 描述 | |
---|---|---|
特殊属性 | _dict_ | 获得类对象或实例对象所绑定的所有属性和方法的字典 |
特殊方法 | _len()_ | 通过重写 _len()_ 方法,让内置函数 len() 的参数可以是自定义类型 |
特殊方法 | _add()_ | 通过重写 _add()_ 方法,可使用自定义对象具有"+"功能 |
特殊方法 | _new()_ | 用于创建对象 |
特殊方法 | _init()_ | 对创建的对象进行初始化 |
类的浅拷贝和深拷贝
模块
模块的导入
import 模块名称 [as 别名] # 导入模块所有
from 模块名称 import 函数/变量/类 # 导入模块的部分
# 使用导入整个模块
函数/变量/类
# 使用导入部分函数
模块名称.函数/变量/类
# 例子 modle是自定义模块
#############################################
# 第一种种导入方式
import module
print(module.div(2, 1))
print(module.fun(2, 1))
#############################################
# 第二种导入方式
from module import fun
from module import div # div 使用moudle模块的 div 函数
print(fun(1, 2))
print(div(1, 2))
以主持下形式运行
在每个模块的定义中都包括一个记录模块名称的变量__name__,以确定他们在那个模块中执行。如果一个模块不是被导入到其他程序中执行,那么它可能子啊接收器的顶级模块中执行。顶级模块的__name__变量的值为__main__
# 只有当点击运行module时候才会运行并不会因为引用该模块就全部运行
if __name__ == "__main__":
print('==================')
print('main是顶级模块')
Python 中的包
Python常用的内置模块
模块名 | 描述 |
---|---|
sys | 与python解释器及其环境操作相关的标准库 |
time | 提供时间相关的各种函数标准库 |
os | 提高了访问操作系统服务功能的标准库 |
calender | 提提供与日期相关的各种函数标准库 |
urllib | 用于读取来自网上的数据标准库 |
json | 用于使用 JSON 序列化和反序列化对象 |
re | 用于子啊字符串中执行正则在表达式匹配和替换 |
math | 提供标准算术运算函数的标准库 |
decimal | 用于精确控制运算的精度,有效位数和四舍五入操作的十进制运算 |
logging | 提供了灵活的记录事件、错误、警告和调试信息等日志信息功能 |
第三方模块的安装和使用
pip install 模块名称
import 模块名称
编码格式
文件读写原理
file=open()
常用的文件打开模式
文件类型
打开模式 | 描述 |
---|---|
r | 只读模式打开 |
w | 只写模式打开,文件不存在则创建,存在则覆盖原有内容 |
a | 追加模式打开文件,不存在则创建,存在则在文件末尾追加 |
b | 二进制方式打开文件,不能单独使用,要和其他模式共用,如:rb,wb |
+ | 以读写方式打开文件,不能单独使用,需要与其他模式共用,如:a+ |
文件对象的常用方法
方法名 | 描述 |
---|---|
read([size]) | 从文件中读取size个字节或字符的内容返回,若省略[size],则读取到文件末尾,则一次读取文件所有内容 |
readline() | 从文本文件中读取一行内容,'\n’为换行符,返回空则声明读到最后一行 |
readlines() | 把文本文件中的每一行都作为独立的字符串对象,并将这些字符串放入列表返回 |
write(str) | 将str写入文件,并返回写入的字节数 |
writelines(s_list) | 将字符串列表s_list 写入文本文件,不添加换行符 |
seek(offset,whence) | 将文件指针移动到新的位置,offset:表示相对于whence的位置:whence:0(文件开头)1(当前位置)2(文件结尾,此时移动的位置是负数) |
tell() | 返回文件指针当前位置 |
flush() | 将缓冲区的内容写入文件 |
close() | 将缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源 |
with语句
with语句可以自动管理上下文资源,不论什么原因体跳出with块,都能确保文件正确的关闭,以此达到释放资源的目的
目录操作
os模块是 Python 内置的与操作系统功能和文件系统相关的模块,该模块中执行的语句通常和操作系统有关,在不同的操作系统上运行可能得到结果不同
os模块与os.path模块用于对目录\文件进行操作
os 模块操作目录的相关函数
函数 | 说明 |
---|---|
getcwd() | 获取当前工作目录 |
mkdir(path[,mode]) | 创建目录 |
makedirs(path1/path2/…[mode]) | 创建多级目录 |
listdir(path) | 返回指定目录下的文件和目录信息 |
rmdir(path) | 删除目录 |
removedirs(path1/path2/…) | 删除多级目录 |
chdir(path) | 将path设置为当前工作目录 |
os.path模块操作目录相关函数
函数 | 说明 |
---|---|
abspath(path) | 获取文件或目录的绝对路径 |
exists(path) | 判断文件或目录是否存在,存在:True,不存在:False |
join(path,name) | 将目录与目录或者文件名拼接在一起 |
splitext() | 分离文件名和拓展名 |
basename(path) | 从一个路径中提取文件路径,不包括文件名 |
isdir(path) | 判断是否为路径 |
walk 可以遍历指定目录下的所有文件