• os模块

    OS模块介绍

    什么是OS模块

    • os模块是与操作系统的一个接口

    OS模块的作用

    • 该模块为python自带的标准库模块

    • 提供了一些方便使用操作系统相关功能的函数

    什么是环境变量

    • 环境变量是一个统称,它是一个全局性的变量,全局到你整个环境都有效, 它比你python文件中的全局级别还要高. 它代指你整个软件的环境, 你软件所有的地方都能访问到的这么一个环境变量. 这个时候没有文件的限制了, 所有文件当中都能访问的到.

    • 一般是指操作系统中用来指定操作系统运行环境的一些参数,比如:临时文件夹位置和系统文件夹位置等

    • 操作系统运行系统命令的时候,会到这一系列文件夹去找你输入你的命令在不在里面

    os.environ与系统环境变量和sys.path环境变量的区别:

    • 系统path环境变量:用于执行操作系统命令, 操作系统找命令的时候用到, 这个变量对应的值是一堆文件夹, 这些文件夹, 是在操作系统运行系统命令的时候, 会到这一系列文件夹中去找你输入的命令在不在其里面.

    • sys.path环境变量:以列表的形式保存,存的是一堆文件夹,python查找模块时会检索这个环境变量里的文件夹

    • os.environ环境变量:是一个字典,一系列的键、值对储存在该字典中, 当你想让你这个值在整个环境中都能用的到, 你就可以把这个值往os.environ环境变量中添加

    二、os系列

    以下是os的常用方法:

    方法作用拓展
    os.name(重点)输出字符串指示当前使用的平台。windows下为”nt”,Linux下为”posix”
    os.getcwd得到当前工作目录,即当前python脚本工作的目录路径注意: 获取的是执行文件.如果被导入模块中有这个功能, 并不是获得被导入模块文件的目录路径。而是获得当前执行文件的目录路径。
    os.remove(file)(重点)删除一个文件
    os.rename(“oldname”,”newname”)(重点)重命名文件/目录把新文件名命名成旧文件。(注意: 旧文件一定要不存在, 如果是存在的文件, 则抛出异常)
    os.stat(file)获得文件属性或目录信息
    os.mkdir(name)(重点)创建目录生存单级目录。注意: 如果指定了目录的路径, 你想要生成单级的上一级目录不存在。那么将会抛出异常。(相当与shell中的mkdir dirname)
    os.makedirs(‘dirname1/dirname2’)(重点)可生成多层递归目录
    os.rmdir(name)(重点)删除目录删除单级空目录。若目录不为空,则无法删除。会抛出异常。(相当于shell中的rmdir dirname)
    os.removedirs(r“c:\python”)若目录为空,则删除,并递归到上一级目录,若也为空,则删除,依此类推递归删除多层目录. 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 (注意: 只有为空的才能删)
    os.system(“bash command”)(重点)运行shell命令, 直接显示应用程序向操作系统发送了一个系统调用。告诉操作系统运行字符串中所指定的命令。
    os.linesep给出当前平台的行终止符,Windows使用 ‘\r\n’,Linux使用 ‘\n’, Mac使用 ‘\r’突出当前平台使用导航终止服务。windows下为”\r\n”,Linux下为”/n” (提示: 直接打印看不到任何的效果,我们需要把它放到列表当中. 如: [os.linesep])
    os.listdir(‘dirname’)(重点)返回指定目录下的所有文件和目录名, 包括隐藏文件,并以列表方式打印
    os.walk(dir)(重点)用类似于深度遍历的方式遍历文件夹中的子文件夹以及文件,最基本的显示方式为(root_path,[file_dirs],[files])
    os.curdir返回当前目录以’.’符号的形式表示
    os.chdir(‘dirname’)改变工作目录到’dirname’相当于是shell下的cd命令
    os.pardir获取当前目录的父目录字符串名:(‘..’)以’..’符号的形式表示
    os.sep取代操作系统特定的路径分隔符, win下为”, Linux下为”/”
    os.pathsep(重点)输出用于分割文件路径的字符串 win下为” ; ” , Linux下为” :”
    os.environ(重点)获取系统环境变量注意:以字典格式存在, 其中key和value必须都为字符串类型。
    • os.environ 使用 (重点)

      import osprint(os.environ)
      '''输出内容
      environ({'ALLUSERSPROFILE': 'C:\\ProgramData', 'ANSYS180_DIR': 'F:\\ANSYS Inc\\v180\\ANSYS', 'ANSYS_SYSDIR': 'winx64', 'ANSYS_SYSDIR32': 'win32', 'ANS_OLD_ATTACH': '1', 'APPDATA': 'C:\\Users\\ThinkPad\\AppData\\Roaming', 'AWP_LOCALE180': 'en-us', 'CHOCOLATEYINSTALL': 'C:\\ProgramData\\chocolatey', 'CHOCOLATEYLASTPATHUPDATE': '132503483593518657', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMPUTERNAME': 'DESKTOP-GCJC73B', 'COMSPEC': 'C:\\WINDOWS\\system32\\cmd.exe', 'CONFIGSETROOT': 'C:\\WINDOWS\\ConfigSetRoot', 'DRIVERDATA': 'C:\\Windows\\System32\\Drivers\\DriverData', 'FPS_BROWSER_APP_PROFILE_STRING': 'Internet Explorer', 'FPS_BROWSER_USER_PROFILE_STRING': 'Default', 'FREI0R_PATH': 'E:\\新建文件夹\\Video Converter Studio\\frei0r;E:\\新建文件夹\\Video Converter Studio\\frei0r', 'GOPATH': 'C:\\Users\\ThinkPad\\go', 'HOMEDRIVE': 'C:', 'HOMEPATH': '\\Users\\ThinkPad', 'ICEMCFD_SYSDIR': 'win64_amd', 'IDEA_INITIAL_DIRECTORY': 'F:\\PyCharm\\bin', 'LANG': 'chs', 'LNKEVN': 'C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe', 'LOCALAPPDATA': 'C:\\Users\\ThinkPad\\AppData\\Local', 'LOGONSERVER': '\\\\DESKTOP-GCJC73B', 'LSTC_LICENSE': 'ANSYS', 'NUMBER_OF_PROCESSORS': '8', 'ONEDRIVE': 'C:\\Users\\ThinkPad\\OneDrive', 'OS': 'Windows_NT', 'PATH': 'F:\\python_16\\venv\\Scripts;F:\\Python38\\Scripts;C:\\Program Files (x86)\\Intel\\iCLS Client\\;C:\\Program Files\\Intel\\iCLS Client\\;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files\\proeWildfire 5.0\\bin;D:\\Program Files\\proeWildfire 5.0\\bin;D:\\PTC\\Proe5.0M280\\bin;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files (x86)\\Common Files\\Thunder Network\\KanKan\\Codecs;C:\\Program Files\\dotnet\\;C:\\Program Files\\Pandoc\\;F:\\Go\\bin;F:\\Python38;F:\\Python27;F:\\Python27\\Scripts;C:\\ProgramData\\chocolatey\\bin;F:\\Typeeasy\\;F:\\git\\cmd;C:\\Users\\ThinkPad\\AppData\\Local\\Microsoft\\WindowsApps;;F:\\PyCharm\\bin;;C:\\Users\\ThinkPad\\go\\bin;C:\\Users\\ThinkPad\\AppData\\Roaming\\npm', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 142 Stepping 10, GenuineIntel', 'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '8e0a', 'PROGRAMDATA': 'C:\\ProgramData', 'PROGRAMFILES': 'C:\\Program Files', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'PROGRAMW6432': 'C:\\Program Files', 'PROMPT': '(venv) $P$G', 'PSMODULEPATH': 'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules', 'PUBLIC': 'C:\\Users\\Public', 'PYCHARM': 'F:\\PyCharm\\bin;', 'PYCHARM_DISPLAY_PORT': '63342', 'PYCHARM_HOSTED': '1', 'PYTHONIOENCODING': 'UTF-8', 'PYTHONPATH': 'F:\\PyCharm\\plugins\\python\\helpers\\pycharm_matplotlib_backend;F:\\PyCharm\\plugins\\python\\helpers\\pycharm_display', 'PYTHONUNBUFFERED': '1', 'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\WINDOWS', 'TEMP': 'C:\\Users\\ThinkPad\\AppData\\Local\\Temp', 'TMP': 'C:\\Users\\ThinkPad\\AppData\\Local\\Temp', 'UGII_BASE_DIR': 'E:\\UG_NX8.5_Win64位', 'UGII_LANG': 'simpl_chinese', 'UGII_ROOT_DIR': 'E:\\UG_NX8.5_Win64位\\UGII\\', 'UGS_LICENSE_SERVER': '28000@desktop-gcjc73b', 'USERDOMAIN': 'DESKTOP-GCJC73B', 'USERDOMAIN_ROAMINGPROFILE': 'DESKTOP-GCJC73B', 'USERNAME': 'ThinkPad', 'USERPROFILE': 'C:\\Users\\ThinkPad', 'VIRTUAL_ENV': 'F:\\python_16\\venv', 'WINDIR': 'C:\\WINDOWS', 'WXDRIVE_START_ARGS': '--wxdrive-setting=0 --disable-gpu --disable-software-rasterizer --enable-features=NetworkServiceInProcess', '_OLD_VIRTUAL_PATH': 'F:\\Python38\\Scripts;C:\\Program Files (x86)\\Intel\\iCLS Client\\;C:\\Program Files\\Intel\\iCLS Client\\;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files\\proeWildfire 5.0\\bin;D:\\Program Files\\proeWildfire 5.0\\bin;D:\\PTC\\Proe5.0M280\\bin;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files (x86)\\Common Files\\Thunder Network\\KanKan\\Codecs;C:\\Program Files\\dotnet\\;C:\\Program Files\\Pandoc\\;F:\\Go\\bin;F:\\Python38;F:\\Python27;F:\\Python27\\Scripts;C:\\ProgramData\\chocolatey\\bin;F:\\Typeeasy\\;F:\\git\\cmd;C:\\Users\\ThinkPad\\AppData\\Local\\Microsoft\\WindowsApps;;F:\\PyCharm\\bin;;C:\\Users\\ThinkPad\\go\\bin;C:\\Users\\ThinkPad\\AppData\\Roaming\\npm', '_OLD_VIRTUAL_PROMPT': '$P$G'})
      '''print(type(os.environ))
      '''输出内容
      <class 'os._Environ'>
      '''# 向环境变量中设置值,取值
      # 后面我们连接数据库的用户名密码,不写死到代码中,而是配置在环境变量中,使用代码获取
      os.environ["username"] = "淘小欣"
      name = os.environ.get("username")
      print(name)  # 淘小欣
      
    • os.walk()的使用

      import os
      dir_path=os.walk("F:\python_16\day 31")
      print(dir_path) #<generator object walk at 0x00000208CFB77C10>(拿到的是一个生成器)1.我们对其循环取值
      for i in dir_path:
          print(i)
      '''输出内容
      ('F:\\python_16\\day 31', ['test', '__pycache__'], ['app.py', 'foo.py', 'os.py', 'run.py'])
      ('F:\\python_16\\day 31\\test', ['a', 'c'], [])
      ('F:\\python_16\\day 31\\test\\a', [], ['a.py'])
      ('F:\\python_16\\day 31\\test\\c', [], ['c.py'])
      ('F:\\python_16\\day 31\\__pycache__', [], ['app.cpython-38.pyc', 'foo.cpython-38.pyc'])
      '''
      #可以发现os.walk()以元组为单位区分每一层,每一层又分为三个部分(根目录路径, 根目录下的文件夹列表, 根目录下的文件列表)2.我们也可以将三个部分遍历出来分开查看
      for root,dirs,files in dir_path:
          print(root)
          print(dirs)
          print(files)
          print("=======》")
          
      '''输出内容
      F:\python_16\day 31
      ['test', '__pycache__']
      ['app.py', 'foo.py', 'os.py', 'run.py']
      =======》
      F:\python_16\day 31\test
      ['a', 'c']
      []
      =======》
      F:\python_16\day 31\test\a
      []
      ['a.py']
      =======》
      F:\python_16\day 31\test\c
      []
      ['c.py']
      =======》
      F:\python_16\day 31\__pycache__
      []
      ['app.cpython-38.pyc', 'foo.cpython-38.pyc']
      =======》
      '''3.用os.walk计算一个文件夹的大小示例import os
      def dir_size():
          while True:
              dir_path=input("请输入文件夹路径(Q\q退出)>>>:").strip()
              size=0  #初始化大小
              if dir_path.upper()=="Q":break
              if not os.path.isdir(dir_path):     #判断是否存在该目录
                  print("没有该文件夹,请重新输入")
              path_list=os.walk(dir_path)         #得到生成器
              for root,dirs,files in path_list:   #遍历三个元素
                  for i in files:                 #每次遍历取出文件
                      size +=os.path.getsize(os.path.join(root,i))    #拼接文件路径并计算大小
              print(f"该目录文件总大小为:{size}")
      ​
      dir_size()
      ​
      

    三、os.path系列

    os.path系列主要用于获取文件的属性, 以下是常用方法 :

    方法作用
    os.path.abspath(path)返回规范化的绝对路径 (多个”只识别一个)
    os.path.basename(path)(重点)返回文件名 (如果传入的是路径,会切出文件名)
    os.path.dirname(path)(重点)返回文件路径 (就是当前文件或目录的上一级目录)
    os.path.exists(path)(重点)如果路径 path 存在,返回 True;如果路径 path 不存在,返回 False。
    os.path.getatime(path)返回最近访问时间(浮点型, 有秒级)
    os.path.getmtime(path)返回最近文件修改时间
    os.path.getctime(path)返回文件 path 创建时间
    os.path.getsize(path)(重点)返回文件大小,如果文件不存在就返回错误
    os.path.isabs(path)判断是否为绝对路径
    os.path.isfile(path)(重点)判断路径是否为文件
    os.path.isdir(path)(重点)判断路径是否为目录
    os.path.join(path1, path2,path3)(重点)把目录和文件名拼接成一个路径
    os.path.normcase(path)(重点)转换path的大小写和斜杠 (只在 windows 平台上有效)
    os.path.normpath(path)(重点)规范path字符串形式
    os.path.split(path)把路径分割成 dirname 和 basename,返回一个元组
    • os.path.normcase( ) 说明

      # Linux和Mac平台上, 该函数会原样返回path, 在Windows平台上会将路径中所有字符转换为小写, 并将所有斜杠转换成反斜杠import os
      res=os.path.normpath("F:/python_16///day 29\\\taoxiaoxin")
      print(res)  #F:\python_16\day 29\   aoxiaoxin
      
    • os.path.normpath( ) 说明

      #规范路径, 并且会识别"..", 自动将其返回上一级, 分隔符会转成当前平台使用的分隔符
      import osres = os.path.normpath("F :///python_16\\ta\../xiao/")
      print(res)  #F :\python_16\xiaores2 = os.path.normpath("F:\\python_16/ta\hai/../..")
      print(res2)  #F:\python_16 (返回了两次)
      

    三、OS路径处理

    1.方法一(通用)

    • 这种方法比较通用, Python2 和 Python3 中都适用

    • 可以先使用 os.path.abspath( ) 规范一下返回路径

      import osprint(os.path.abspath(__file__))  # F:\python_16\day 29\add.pyBASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
      print(BASE_DIR)  # F:\python_16(返回上一级两次)BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
      print(BASE_DIR)  # F:\python_16(返回上一级两次)BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
      print(BASE_DIR)  # F:\(返回上一级三次)BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
      print(BASE_DIR)  # F:\(返回上一级三次)
      

    2.方法二

    • 使用比较简单

    • op.pardir : 上一级

    • op.path.normpath( ) : 规范path字符串形式

      #其中可以不使用abspath
      import osprint(os.path.abspath(__file__))  #F:\python_16\day 29\add.pyBASE_DIR = os.path.normpath(os.path.join(__file__,os.pardir,os.pardir))
      print(BASE_DIR)  # F:\python_16  (返回上一级两次)BASE_DIR = os.path.normpath(os.path.join(__file__,os.pardir,".."))
      print(BASE_DIR)  # F:\python_16  (返回上一级两次)BASE_DIR = os.path.normpath(os.path.join(__file__,"..","..",".."))
      print(BASE_DIR)  # F:\  (返回上一级三次)
      

    四、 pathlib模块(在python3.5之后推出)

    # , 推出了一个新的模块pathlib
    from pathlib import Path# 需求: 获取当前文件的父级的父级目录
    res = Path(__file__).parent.parent
    print(res)
    ​
    # 路径拼接 + 规范化路径
    res = Path('//\\a//\\\\/b/c') / 'd/e.txt'
    print(res)  # \a\b\c\d\e.txt
    print(type(res))  # <class 'pathlib.WindowsPath'># 规范化路径
    print(res.resolve())   # 等同于os.path.abspath
    

    五、案例

    • 需求实现: 不利用os.path.getsize统计文件夹的大小, 利用递归实现统计整个文件下含有的所有文件大小

      def search_folder_size(folder_path):
          size = 0
          if os.path.isfile(folder_path):
              return os.path.getsize(folder_path)
      ​
          for file_or_dir in os.listdir(folder_path):  # os.listdir不能判断文件, 如果是文件会抛出异常(NotADirectoryError)
              path = os.path.join(folder_path, file_or_dir)
              if os.path.isfile(path):
                  size += os.path.getsize(path)
              else:
                  # return search_folder_size(path)  # 注意: 这里不能加return。 # 递归一旦return 递归里面的内容,就不会继续往下走了, 从当前位置直接开始回溯,得到最终的结果 # 因为递归是在需要得到预期的结果的时候再去return, 这个return必须严格控制好(return之前, 我们要重新调用search_folder_size(path), 这个时候当它是一个文件的时候, 它的size就是一个全新的size=0, 计算完毕以后开始回溯, 回溯回来以后, 我们之前有个return这个时候就把那个size=0, 0当做结果返回了)
                  search_folder_size(path)
          return size