1

我不明白这个源代码在第 3 行做了什么,res = [...];我试图通过在 python 控制台中使用虚拟变量和相同的语法格式进行测试来理解,就像res = ['raj' / 'esh'];它给出错误一样;如果进行测试,res = ['raj' and 'esh'];我总是返回第二个字符串'esh',所以我很困惑为什么在该行中使用“和”。语法 p/o 也让我感到困惑。

def _get_files(parent, p, f, extensions):
    p = Path(p)  #.relative_to(parent)
    res = [p/o for o in f if not o.startswith('.')
           and (extensions is None or f'.{o.split(".")[-1].lower()}' in extensions)]
    return res

解析的参数p是文件路径(字符串),解析的参数 f 是f = [o.name for o in os.scandir(path) if o.is_file()]; 这里语法行中的路径是文件路径。我可以在理解第 3 行方面获得任何帮助吗?

4

2 回答 2

1

这是一个列表理解

res = [p/o for o in f if not o.startswith('.')
       and (extensions is None or f'.{o.split(".")[-1].lower()}' in extensions)]

是语法简写

res = []
for o in f:
    if not o.startswith('.') and (extensions is None or f'.{o.split(".")[-1].lower()}' in extensions):
        res.append(p/o)
于 2018-11-25T23:20:56.137 回答
1

['raj' and 'esh']是一个单元素数组,其唯一元素是'raj'and的结果'esh'and如果为假,则计算第一个操作数,否则计算第二个操作数。由于第一个操作数不是假的,你得到'esh'.

代码中的行不是一个简单的数组,它是一种理解——基本上是一种编写构造数组的循环的简短方法。推导式的一般语法是

[x for y in z if p]

wherey将遍历 iterable 的所有元素z,检查是否p为真,如果是,则添加x到结果中。在您的情况下,条件 ( p) 是

not o.startswith('.')
and
(extensions is None or f'.{o.split(".")[-1].lower()}' in extensions)

对于(可能是文件名的可迭代)的每个元素of如果此标准为真,则结果列表将获得一个元素,该元素由路径p与文件名的串联组成o/这是一个自然的,如果乍一看令人惊讶的串联运算符路径。)

代码段中显示的错误命名使问题更加复杂。考虑这个重写:

def _hidden(filename):
    return filename.startswith('.')

def _extension(filename):
    return '.' + filename.split(".")[-1].lower()

def _extension_ok(filename, allowed_extensions=None):
    return allowed_extensions is None
           or _extension(filename) in allowed_extensions

def _get_files(parent, path, filenames, allowed_extensions=None):
    path = Path(path)
    good_paths = [path/filename for filename in filenames
                  if not _hidden(filename)
                     and _extension_ok(filename, allowed_extensions)]
    return good_paths

现在这读起来几乎像英语,并且非常清楚它在做什么(唯一不可靠的一点是path/filename,几乎任何人都可以通过类比 UNIX 路径来猜出这可能是什么)。

于 2018-11-25T23:23:58.753 回答