惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
B
Blog RSS Feed
C
Check Point Blog
D
Docker
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
量子位
有赞技术团队
有赞技术团队
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
M
MIT News - Artificial intelligence
B
Blog
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
月光博客
月光博客

jdhao's digital space

Conversion between base64 and OpenCV or PIL Image 腾讯云对象存储博客图床开启 CDN 加速(不需要购买额外域名) Search and Replace in Multiple Files in Vim/Neovim Change Table Column Width in LaTeX Image or Table Side by Side in LaTeX LaTeX 并排显示图像或表格 Firenvim: Neovim inside Your Browser Content inside HTML tags missing in Latest Hugo? Creating Markdown Front Matter with Ultisnips Labelme JSON 标注格式转 voc XML 格式 Nifty Nvim Techniques That Make My Life Easier -- Series 6 macOS 下如何为视频制作字幕 Running Command Asynchronously inside Neovim Resolving Merge Conflict after Git Stash Pop Pylint: command not found? A Hands-on Experience with Neovim's Built-in LSP Support How to Convert PDF to Images with Imagemagick 互联网上常用缩略语集锦 File Backup in Neovim Converting PDF Pages to Images with Poppler Nifty Nvim Techniques That Make My Life Easier -- Series 5 Neovim Configuration for System-wide Use How to sort a list of tuple or list in Python -- lambda or itemgetter? Building A Vim Statusline from Scratch 人类第一颗原子弹爆炸始末 Distributed Training in PyTorch with Horovod Learning Expect Programming Essential Knowledge about SSH Nifty LaTeX Techniques -- Series 1 更改 Adsense 邮寄地址,重新寄送 PIN
Unintuitive Behaviour of Case Sensitivity in Python glob
2019-06-24 · via jdhao's digital space

tl;dr: glob.glob() is case sensitive in Linux, but case insensitive in Windows.

Recently, I was bitten by the unintuitive behaviour of glob.glob(). I think it would be beneficial to write down what I have found.

A little background. I wanted to find all the images under directory test_img with extensions .jpg or *.JPG on my Windows 10 machine. My initial code was like:

import glob

ext = '.jpg'
im_paths1 = glob.glob('test_img/' + '*' + ext)
im_paths2 = glob.glob('test_img/' + '*' + ext.upper())

I expect that im_paths1 and im_paths2 contain the paths of all the images ending in .jpg and .JPG respectively. But the truth is that im_paths1 and im_paths2 are exactly the same: all images whose names end with either .jpg or .JPG have been matched, i.e., glob.glob() is case insensitive on Windows!

I run the same code on Linux and find that glob.glob() is case sensitive.

This inconsistent behaviour on different platforms drives me to read the source code of glob module. It seems that the culprit is fnmatch.filter(), which is used by glob to get the matching file paths (relevant code is here). fnmatch.filter() uses os.path.normcase() for the pattern and filenames in non-POSIX systems (relevant code here). That is why glob.glob() can not distinguish between lower and upper case files on the Windows platform.

This behaviour is a bad design in my opinion, which should be notified to the users.

To keep the behaviour of glob.glob() consistent across different systems, I write the following method to find files in a case sensitive manner on Windows:

Click to check the code.
def find_files(directory, pat):
    """
    Find files in a case sensitive way on Windows.

    Parameters
    ----------
    directory: str
        The directory where you want to find files, can be relative or
        absolute path.
    pat: str
        The pattern of file names you want find, for example,`*.jpg` or
        `*.JPG`.

    Returns
    -------
    A list of file paths matching the given pattern. Empty if no files under
        the directory matches the pattern.
    """
    path_pattern = os.path.join(directory, pat)
    pths = glob.glob(path_pattern)

    match = re.compile(fnmatch.translate(path_pattern)).match
    valid_pths = [pth for pth in pths if match(pth)]

    return valid_pths


print(find_files('test_img', '*.jpg'))

References#