pip
- install 使用代理
pip install --proxy http://username:password@ip:port package
- 在线安装
# 先进入命令行
pip install 需要的模块/schedule
- 离线安装
编码
- 在文件开头加上
# -\*- coding: UTF-8 -\*-
# -*- coding: UTF-8 -*-
- 在文件开头加上
# coding=gbk
(注意:=
左右两边不能有空格)
# coding=gbk
- 数据输出到文件
f = open('test.txt', 'a+') # a+ 没有就新建,存在就追加
print('hello world', file=f) # 将字符串输出到文件
file.close()
- 不换行输出
print('hello', end="") # 在该行结尾为一个空字符串,并且不会换行
转义字符
\t
\n
回车\b
退一格- 元字符:在字符串前加上
r
或R
print(r'hello\nworld')
# 结果: hello\nworld
# 注意: 最后一个字符不能是一个 \
字符编码
print(chr(0b100111001011000))
print(ord('乘'))
关键字
# 查看关键字
import keyword
print(keyword.kwlist)
变量
变量由三个部分组成: id
type
value
数据类型
type(val)
函数查看类型
int
0b
二进制0o
八进制0x
十六进制
float
浮点数由整数和小数组成。使用浮点数计算,结果具有不确定性
- 浮点数计算
from decimal import Decimal
print(Decimal('1.1') + Decimal('2.2'))
bool
True
可以转换为1
False
可以转换为0
str
- 单引号和双引号的字符串只能在一行
- 三引号的字符串可以在多行
数据类型转换
-
str()
将其它类型转换为 字符串 -
int()
将其它类型转换为 整型 ,转换小数时只取整数部分 -
float()
将其它类型转换为 浮点型
input 函数
a = input('请输入一个数: ') # 注意, input输入获取的值都是字符串
运算符
+
、-
、*
、/
、//
整除
python 中,
/
为正常除法,//
才表示整除,只获取整数
**
: a**b
表示 a 的 b 次方
- 负数参与 整除 运算,结果向下取整
- 负数参与 求余 运算:
余数 = 被除数 - 除数 * 商
比较运算符
==
比较的是 值is
、is not
比较的是引用
逻辑运算符
and
、or
、not
、in
、not in
位运算符
&
、|
、<<
、>>
对象的 布尔值
除了以下值外,其它的全部为 TRUE
,可以用 bool()
函数查看
- False
- 数值 0
- None
- 空字符串
- 空列表
- 空元组
- 空字典
- 空集合
程序结构
分支
if expression:
do
elif expression:
do
else:
do
- 条件表达式
(表达式1) if (条件) else (表达式2)
# 如果条件成立,则结果取左边,否则取右边
pass 语句
表示什么都不做,只是一个占位符,表示待完成代码
range()
用于生成一个整数序列,创建方式:
range(10) # 表示默认从 0 开始,步长默认为 1,创建 10 个
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range(2, 8) # 指定从 2 开始,步长默认为 1,到 8 为止
# [2, 3, 4, 5, 6, 7]
range(2, 10, 3) # 指定从 2 开始,到 10 位置,步长为 3
# [2, 5, 8]
循环结构
while
while expression:
do
for - in
for item in arr:
do
- 100~999之间的水仙花数: 个位的3次方 + 十位的2次方 + 百位
循环控制
-
break
-
continue
else
的特殊用法
while expression:
if exp:
break;
else:
do
当循环正常执行完成,没有遇到 break 时就会进入到 else
列表
创建
lst = [1, 2, 'hello'] # 用 [] 直接创建
lst2 = list(['hello', 'world', 98]) # 用 list 函数创建
索引
列表中元素通过索引获取
- 从前到后为 0 开始
- 从后到前为 -1 开始
lst = [1, 2, 3, 4, 'hello', 5, 'hello']
print(lst[3], lst[-4])
函数
index()
获取元素在列表中的索引。- 若存在相同元素,则只返回第一个元素的索引
- 若不存在该元素,则抛异常
arr.index(1)
arr.index('hello', 1, 3) # 表示在索引 1~3 之间查找 hello
获取多个元素
列表名[start : stop : step]
包括左边,不包括右边,步长为 1 可以省略
lst = list(range(10, 100, 10))
print(lst[1:6:2])
- 步长为负数:切片得到的最后一个元素为结果的第一个,从
start
的位置开始往左边找直到stop
的位置
lst = list(range(10, 100, 10))
print(lst[::-1]) # [90, 80, 70, 60, 50, 40, 30, 20, 10]
print(lst[7::-1])
in
not in
增删改
增
append()
在列表的末尾添加一个元素extend()
在列表末尾添加至少一个元素
lst = [10, 20, 30]
lst2 = ['hello', 'world']
lst.append(lst2) # [10, 20, 30, ['hello', 'world']]
lst.extend(lst2) # [10, 20, 30, 'hello', 'world']
insert(index, value)
在指定位置添加一个元素- 切片添加:在指定位置添加至少一个元素。(实际上是修改)
lst = [10, 20, 30]
lst3 = [True, False, 'hello']
lst[1:]=lst3
print(lst) # [10, True, False, 'hello']
删
remove(val)
一次移除一个元素,有多个只移除第一个,没有抛异常pop(index)
删除指定索引位置的元素,不指定默认删除最后一个- 切片删除 :将会产生一个新列表,原列表不会改变
lst = list(range(10, 60, 10))
new_list = lst[1:3]
print(lst) # [10, 20, 30, 40, 50]
print(new_list) # [20, 30]
# 不产生新的列表
lst[1:3] = []
clear()
清空列表del lst
删除对象
改
- 修改一个值
- 修改多个值。利用切片选取多个元素,再进行替换
lst = [10, 20, 30, 40]
lst[1:3] = [100, 200]
print(lst) # [10, 100, 200, 40]
排序
sort()
默认是升序,可以通过REVERSE=TRUE
设置为降序。在原列表上操作,不会产生新对象,只能是数字比较
lst = [10, 31, 22, 54, 212, 11]
lst.sort(reverse=True)
print(lst)
sorted()
与 sort 用法一样,但是会产生新对象,并且结果是在新对象里
列表生成式
语法:[i for i in range(1, 10)]
lst = [i for i in range(1,10)]
print(lst) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
字典
字典的键必须是不可变序列,如 字符串,整数。
创建
- 花括号
scores = { '张三': 80, '李斯': 99}
- 使用
dict()
函数创建
student = dict(name='jack', age=20)
增删改查判断
获取
- 使用
[]
获取
student = dict(name='jack', age=20)
print(student['name']) # jack
- 使用
get()
方法
scores = { '张三': 80, '李斯': 99}
print(scores.get('张三')) # 80
区别:如果键不存在时,
get()
方法返回None
,而[]
会报错
- 如果键不存在时,返回默认值
scores = { '张三': 80, '李斯': 99}
print(scores.get('老六', 99)) # 99
Key的判断
scores = { '张三': 80, '李斯': 99}
print('张三' in scores) # true
print('张三' not in scores) # false
删除
- 删除指定键值对 :
del scores['张三']
- 清空字典 :
scores.clear()
新增
scores['陈老刘']=100
改
scores['张三']=60
视图操作
keys()
获取所有键。可以通过 list() 转换为列表values()
获取所有值。可以通过 list() 转换为列表items()
获取所有键值对
遍历
for item in scores:
print(item) # 输出键
print(scores.get(item)) # 输出值
特点
- 键不可以重复,值可以重复。键重复后就覆盖
- 元素是无序的。通过键的 hash 值计算位置
- 字典的键必须是不可变对象
字典生成式
zip()
items = ['Friut', 'book', 'Others']
prices = [96, 78, 85]
d = { item.upper():price for item,price in zip(items, prices)}
print(d)
如果两个列表长度不一致,则以短的为基准
元组
元组是不可变序列
t = ('he', 'she', 90)
创建
- 小括号
tuple()
t = tuple(('python', 'java', 100))
- 如果元组中只有一个元素,那么小括号中必须加一个
,
t = ('world', )
获取元素
- 索引
t = ('python', 'java', 29)
print(t[0])
- 遍历
t = ('python', 'java', 29)
for item in t
print(item)
集合
元素不能重复,通过hash存储
创建
- 使用
{}
arr = {1, 2, 'py'}
set()
s = set(range(6))
s1 = set([3,5,12,44]) # 将列表中元素转为集合
s2 = set((1,2,3)) # 将元组转为集合
s3 = set('python') # {'y', 'h', 't', 'o', 'p', 'n'}
s4 = set() # 定义空集合
操作
元素判断
in
和 not in
新增
-
add()
-
update()
一次添加多个元素
a = {10, 20, 30, 40}
a.update({100, 200, 300}) # {20, 100, 40, 10, 300, 30, 200}
删除
remove()
移除不存在的就报异常discard()
存在就删除,不存在就不管pop()
每次删除最小的元素,并返回clear()
集合间的关系
==
判断,只要元素相等就为True
a = {10, 20, 30, 40}
b = {20, 40, 10, 30}
a == b # True
issubset()
子集
a1 = {1, 2, 3, 4, 5, 6}
a2 = {1, 2, 3, 4}
a2.issubset(a1) #True
issuperset()
超集isdisjoin()
交集
集合关系计算
- 交集
s1 = {10, 20, 30, 40}
s2 = {20, 30, 40, 50, 60}
s1.intersection(s2) # 方式一
s1 & s2 # 方式二
- 并集
s1.union(s2) # 方式一
s1 | s2 # 方式二
- 差集
s1.difference(s2) # 方式一
s1 - s2 # 方式二
- 对称差集
s1.symmetric_difference(s2) # 方式一
s1 ^ s2 # 方式二
集合生成式
{ i for i in range(1,10) }
字符串
字符串驻留机制:就是有个字符串常量池,存储定义的字符串,后续有相同的就直接使用该字符串的地址。
- 驻留机制在编译阶段存在
- 对长度为 0 和 1 的时候会发生驻留机制
- 符合标识符的字符串会产生驻留机制
- 强制驻留(
sys.intern()
会强制进行驻留 ) pycharm
等部分 IDE 进行了驻留机制 的优化,
a = 'abc%'
b = 'abc%'
a is b # false
a= sys.intern(b)
a is b # true
常用操作
查找
index()
查找子串第一次出现的位置,找不到报错rindex()
查找子串最后一次出现的位置,找不到报错find()
查找子串第一次出现的位置,找不到返回 -1rfind()
查找子串最后一次出现的位置,找不到返回 -1
大小写转换
upper()
全部转大写lower()
全部转小写swapcase()
反转。大写转小写,小写转大写capitalize()
把第一个转大写,其它转小写title()
把每个单词第一个字符转大写,其它转小写
内容对齐
center()
居中对齐。第一个参数指定宽度,第二个参数指定填充,默认空格ljust()
左对齐rjust()
右对齐zfill()
右对齐,左边用0填充
字符串拆分
split()
从左边开始拆分,默认使用空格,结果是个列表
str = 'Hello World, Jack';
str.split(sep=',') # 指定分隔符
str.split(sep=' ', maxsplit=1) # 指定最多分一次
rsplit()
与上同,从右边开始分割
字符串判断
isidentifier()
字符串是否是合法标识符isspace()
字符串是否全部由空格组成isalpha()
字符串是否全部由字母组成isdecimal()
是否全部为十进制数字isnumeric()
是否全部为数字isalnum()
是否只有数字和字母
替换与合并
replace()
第一个参数指定被替换的字符串,第二个指定要进行替换的字符串,可以通过第三个参数指定最大替换次数join()
将列表或元组中的字符串合并成一个字符串。第一个参数指定合并时间隔内容- 列表或元组中必须全部是字符串
','.join('hello', 'python') # hello,python
','.join('python') # p,y,t,h,o,n
比较操作
- 比较规则:每个对应位置的字符进行比较,相同则下一个开始比较
- 比较原理:每个字符比较的是原始值,实际就是调用
chr()
函数
切片操作
字符串是不可变类型,操作后将产生新的对象
str = 'hello,python'
str[1:5:1] # 索引从1开始,到5结束,步长为1
# 步长省略时默认为1
# 开头省略时默从0开始
# 结尾省略时默认到最后
格式化字符串
-
使用
%
来占位-
%s
表示字符串 -
%d
表示整数 -
%f
表示小数
-
name = '张三'
age = 18
print("我叫%s, 今年%d岁了" % (name, age))
print('%10d' % 99) # 10表示的是宽度
print('%.3f' % 3.141562) # .3 表示小数点后保留几位,四舍五入
- 使用
{}
来占位
print("我叫{0}, 今年{1}岁了".format(name, age))
f-string
格式化
print(f'我叫{name},今年{age}岁')
编码解码
- 编码
s = '天涯海角'
s.encode(encoding="GBK")
- 解码
b = s.encode(encoding="GBK")
b.decode(encoding='GBK') # 编码与解码方式需要一致
函数
创建
def 函数名([输入参数]):
内容
[return xxx]
参数
def calc(a, b):
c = a + b
return c
calc(a=20, b=10)
不可变对象和可变对象的区别:不可变对象只是值的复制传递,可变对象是引用的传递
默认参数
def fun(a, b=10)
c = a + b
return c
个数可变的位置参数
def fun(*args)
print(args)
# 结果是元组
def fun(a, b, c)
print(a, b, c)
lst = [10, 200, 33]
fun(*lst) # 在函数调用时,将列表中的每个元素都转换为位置实参传入
个数可变的关键字形参
def fun(**args)
print(args)
# 结果是字典
fun(a=10, b=20, c=39)
在函数定义中,既有 个数可变的位置参数
又有 个数可变的关键字形参
,那么要求 个数可变的位置参数
必须在前边
返回值
函数返回多个值时,为元组
作用域
global
将变量设置为全局可用
def fun():
global a = 3
print(a)
fun() # 需要先执行该方法之后,外部才能访问该全局变量
print(a)
异常处理
try:
pass
except xxx :
pass
except xxx :
pass
except BaseException as e: # 最底层异常
print("出错了", e)
else
pass
# 如果 try 中没有抛出异常,则执行 else 中的内容
# else 与 except 中的内容只会执行一个
finally
pass
traceback
打印异常信息
import traceback
try:
pass
except:
traceback.print_exc()
类与对象
__foo__
:前后双下划线。定义的是特殊方法,一般是系统定义,如__init__
_foo
:单下划线开头,表示 protected 类型的变量,只能允许其本身与子类进行访问
__foo
:双下划线开头,表示 private 类型的变量,只能是类本身访问
声名类
class Student:
native_pace = '江西'
# 直接写在类里边的方法外的是类属性
# 类属性被所有对象所共享,通过 类名.属性 访问
def __int__(self, name, age): # 初始化方法
self.name = name
self.__age = age
# age就不希望在类的外部使用
# 但还是可以在外部访问
def eat(self): # 称为实例方法。self 默认存在,代表当前对象
print('inner')
@staticmethod
def sm(): # 静态方法,没有self
print('inner, static')
@classmethod
def cm(cls): # 默认参数,当前类
print('类方法')
# 在类内部定义的叫方法,外部定义的叫函数
def fun():
print('outer')
创建对象
实例名 = 类 ()
stu1 = Student('张三')
print(id(stu1))
print(type(stu1))
print(stu1)
stu1.eat()
Student.eat(stu1)
Student.cm()
Student.sm()
动态绑定属性和方法
- 与 js 类似,对象在创建后可以动态绑定原来类不存在的属性和方法
stu1 = Student('韩梅', 16)
stu1.gender = '女'
print(stu1.__dict__)
# {'name': '韩梅', 'age': 16, 'gender': '女'}
def pName(stu):
print(stu.name)
stu1.pName = pName
stu1.pName(stu1)
# 韩梅
封装
python
没有专门的私有修饰符,可以使用在前边加__
- 理论上不可以访问,但实际上可以强行访问
# 修改构造方法
def __init__(self, name, age):
self.name = name
# self.age = age
self.__age = age
stu1 = Student('韩梅', 16)
print(stu1.name)
print(stu1.age)
'''
韩梅
Traceback (most recent call last):
File "D:\Python\Demos\BasicLearn\day01\Learn05.py", line 28, in <module>
print(stu1.age)
AttributeError: 'Student' object has no attribute 'age'
'''
# 强行访问,通过 dir 方法可以看到所以属性和方法
print(dir(stu1))
print(stu1._Student__age)
# 16
继承
- 默认会继承
Object
- 可以多继承,子类必须在构造方法中调用父类构造方法
class Person(object):
def __init__(self, name):
self.name = name
def info(self):
print("姓名=" + self.name)
class Student(Person):
def __init__(self, name, score):
super.__init__(name)
self.score = score
def info(self): # 重写
print('')
方法重写
- 指父类中方法不能满足子类的需求,子类就重写方法体的内容
- 子类可以通过
super().xxx()
调用父类中被重写过的方法
object 类
dir()
可以查看指定对象的所有属性__str__()
方法返回一个对象的描述,通常会进行重写
特殊属性
属性 | 描述 |
---|---|
__dict__ | 获取类对象或实例对象所绑定的所有属性和方法的字典 |
__class__ | 获取所属的类 |
__bases__ | 获取父类的元组 |
__base__ | 获取最近的父类 |
__mro__ | 获取该类的继承的层次结构 |
__subclasses__ | 子类的元组 |
特殊方法
方法名 | 描述 |
---|---|
__add__() | 加法运算,可以重写来自定义 |
__len__() | 计算列表的长度 |
__new__() | 用于创建对象 |
__init__() | 对创建的对象进行初始化 |
class Person:
def __init__(self, name, age):
print('init, self id: %s' % id(self))
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
print('new 执行, cls的值{0}'.format(id(cls)))
obj = super().__new__(cls)
print('创建对象的id: {0}'.format(id(obj)))
print(f'args: {args}, kwargs: {kwargs}')
return obj
def info(self):
print(fr'名字: {self.name}, 年龄: {self.age}')
p1 = Person('tony', 18)
p1.info()
''' 输出:
new 执行, cls的值1326053164592
创建对象的id: 1326052086976
args: ('tony', 18), kwargs: {}
init, self id: 1326052086976
名字: tony, 年龄: 18
'''
- python 中创建对象使用内置函数
__new__
,传递的类对象为cls
,返回的对象再传递到__init__
方法中作为参数self
- 创建对象的参数通过
*args
参数传递到__init__
方法中 **kwargs
参数的作用?
浅拷贝与深拷贝
- 浅拷贝,只拷贝当前对象,对象中的其他属性如果存在对象类型,则只拷贝其引用
import copy
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
def info(self):
print(f'cpu: {self.cpu}, disk: {self.disk}')
class CPU:
def __init__(self, number):
self.number = number
def info(self):
print(f'CPU: {self.number}')
class Disk:
def __init__(self, size):
self.size = size
def info(self):
print(f'size: {self.size}')
cpu = CPU('19-13')
disk = Disk('2T')
c1 = Computer(cpu, disk)
print(c1)
c1.info()
c2 = copy.copy(c1)
print(c2)
c2.info()
'''
<__main__.Computer object at 0x0000021204189D00>
cpu: <__main__.CPU object at 0x00000212040D99A0>, disk: <__main__.Disk object at 0x0000021204068190>
<__main__.Computer object at 0x00000212040F4340>
cpu: <__main__.CPU object at 0x00000212040D99A0>, disk: <__main__.Disk object at 0x0000021204068190>
'''
'''
可以看到 c1 与 c2 两个对象地址不一致,因此是两个对象,但是两个对象的 CPU 和 DISK 的地址都是一致的,因此其引用的对象仍然是同一个
'''
c2.disk.info()
c1.disk.size = '1T'
c2.disk.info()
'''
size: 2T
size: 1T
'''
'''
可以看到,改变 c1 中的 disk size 的值时,c2 中 disk size 的值也被改变了
'''
- 深拷贝。通过使用
import copy
的deepcopy
# 同样是上边的代码,不过将其中的 c2 = copy.copy(c1) 代码修改如下
c2 = copy.deepcopy(c1)
# 输出结果
'''
<__main__.Computer object at 0x000001F1F2939D00>
cpu: <__main__.CPU object at 0x000001F1F28899A0>, disk: <__main__.Disk object at 0x000001F1F2818190>
<__main__.Computer object at 0x000001F1F28A43A0>
cpu: <__main__.CPU object at 0x000001F1F29C9B80>, disk: <__main__.Disk object at 0x000001F1F29CA100>
size: 2T
size: 2T
'''
模块
Python 中,一个
.py
文件就是一个模块。一个模块中可以包含,函数、类、语句 等内容
导入模块
import 模块名 [as 别名]
from 模块名 import 变量 | 函数
- 导入自定义模块,需要将对应目录设置为
Mark Directory As -> Source Root
__main__
# 只有以当前模块开始执行的时候,才会执行其中的内容
# 如果其它模块引用该模块,其中的内容不会执行
if __name == '__main__'
pass
包
包是 python 中的目录结构,用于管理 python 的模块
一个 python 中可以包含多个模块
一个 python 模块中 又可以包含多个 函数 和 类
包中会包含一个
__init__.py
文件
__init__.py
文件
常用的功能模块
模块名 | 描述 |
---|---|
sys | 与python解释器及其环境操作相关的标准库 |
time | 提供与实践相关的各种函数的标准库 |
os | 提供了访问操作系统服务功能的标准库 |
calendar | 提供与日期相关的各种函数的标准库 |
urllib | 用于读取来自网上的数据标准库 |
json | 用于使用JSON序列化和反序列化对象 |
re | 用于在字符串中执行正则表达式匹配和替换 |
math | 提供标准算数运算函数的标准库 |
decimal | 用于进行精确控制远端精度、有效数位和四舍五入操作的十进制运算 |
logging | 提供了灵活的记录事件、错误、警告和调试信息等日志信息的功能 |
文件操作
f = open(file='filename', mode='r')
# open 为内置函数
# open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)
# 常用参数
# file: 表示文件,接收文件地址
# mode: 操作类型
# 'r': 默认值,从文件中读取内容
# 'w': 写入到文件,文件必须存在
# 'b': 以二进制方式打开文件, rb 表示读二进制文件,wb 表示写二进制文件
# 'x': 创建并写入内容到新文件,文件存在则报错
# 'a': 追加内容到文件末尾,不存在则创建文件
# '+': 表示读写方式打开文件,不能单独使用
文件对象常用操作
方法名 | 描述 |
---|---|
read([size]) | 读取全部[指定大小内容] |
readline() | 读取一行 |
readlines() | 所有行全部读出,放进列表 |
write(str) | 写入内容到文件 |
wirtelines(list) | 写入列表内容到文件,不添加换行符 |
seek(offset [,whence]) | 把文件指针移动到指定位置。offset 表示相对于 whence的位置。whence:不同值的含义:0:从文件头开始计算,默认值 1:从当前位置开始计算 2:从文件尾开始计算(utf8格式文本的中文相当于两个字符) |
tell() | 返回文件指针当前所在位置 |
flush() | 将缓冲区的内容写入文件,不关闭 |
close() | 将缓冲区的内容写入文件,关闭文件,并释放对应资源 |
把文件指针移动到指定位置。offset 表示相对于 whence的位置:
with语句
- with 语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源目的
with open('a.txt', mode='r') as file
file.read()
- 实现了特殊方法
__enter__()
和__exit__()
的类称为该类对象遵守了上下文管理器协议,即可以使用with
语句,并且会自动调用
class CustomMgr:
def __enter__(self):
print('enter method')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit method')
def info(self):
print('info method')
with CustomMgr() as cm:
cm.info()
'''
enter method
info method
exit method
'''
OS 模块
- 内置的,与操作系统和文件系统相关
方法名 | 描述 |
---|---|
os.system('程序') | 用于打开一些系统的程序 |
os.startfile('文件路径') | 打开一些可执行文件 |
os.getcwd() | 获取当前所在位置 |
os.listdir(path) | 返回指定目录下的文件和目录信息 |
os.mkdir(path) | 创建目录 |
os.makedirs(path1/path2...[,mode]) | 创建多级目录 |
rmdir(path) | 删除目录 |
removedirs(path1/path2...) | 删除多级目录 |
chdir(path) | 将path设置为当前工作目录(移动到指定目录下) |
os.path 操作目录
函数 | 说明 |
---|---|
os.path.abspath(path) | 获取文件或目录的绝对路径 |
exists(path) | 判断文件或目录是否存在 |
join(path, name) | 将目录与目录或文件名拼接起来 |
splitext() | 分离文件名和扩展名 |
basenaem(path) | 从一个目录中提取文件名 |
dirname(path) | 从一个路径中 提取文件路径,不包括文件名 |
isdir(path) | 判断是否为路径 |